3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 01:25:31 +00:00

Merge branch 'opt' of https://git01.codeplex.com/z3 into opt

This commit is contained in:
unknown 2015-01-28 17:54:26 -08:00
commit f020b7c7b8
380 changed files with 66767 additions and 3722 deletions

View file

@ -24,6 +24,7 @@ Revision History:
#include"bv_decl_plugin.h"
#include"datatype_decl_plugin.h"
#include"array_decl_plugin.h"
#include"pb_decl_plugin.h"
#include"ast_translation.h"
#include"ast_pp.h"
#include"ast_ll_pp.h"
@ -1075,7 +1076,6 @@ extern "C" {
case OP_BSREM_I:
case OP_BUREM_I:
case OP_BSMOD_I:
return Z3_OP_UNINTERPRETED;
default:
UNREACHABLE();
@ -1084,9 +1084,10 @@ extern "C" {
}
if (mk_c(c)->get_dt_fid() == _d->get_family_id()) {
switch(_d->get_decl_kind()) {
case OP_DT_CONSTRUCTOR: return Z3_OP_DT_CONSTRUCTOR;
case OP_DT_RECOGNISER: return Z3_OP_DT_RECOGNISER;
case OP_DT_ACCESSOR: return Z3_OP_DT_ACCESSOR;
case OP_DT_CONSTRUCTOR: return Z3_OP_DT_CONSTRUCTOR;
case OP_DT_RECOGNISER: return Z3_OP_DT_RECOGNISER;
case OP_DT_ACCESSOR: return Z3_OP_DT_ACCESSOR;
case OP_DT_UPDATE_FIELD: return Z3_OP_DT_UPDATE_FIELD;
default:
UNREACHABLE();
return Z3_OP_UNINTERPRETED;
@ -1124,6 +1125,15 @@ extern "C" {
}
}
if (mk_c(c)->get_pb_fid() == _d->get_family_id()) {
switch(_d->get_decl_kind()) {
case OP_PB_LE: return Z3_OP_PB_LE;
case OP_PB_GE: return Z3_OP_PB_GE;
case OP_AT_MOST_K: return Z3_OP_PB_AT_MOST;
default: UNREACHABLE();
}
}
return Z3_OP_UNINTERPRETED;
Z3_CATCH_RETURN(Z3_OP_UNINTERPRETED);
}

View file

@ -37,9 +37,7 @@ extern "C" {
catch (z3_exception & ex) {
// The error handler is only available for contexts
// Just throw a warning.
std::ostringstream buffer;
buffer << "Error setting " << param_id << ", " << ex.msg();
warning_msg(buffer.str().c_str());
warning_msg(ex.msg());
}
}
@ -64,9 +62,7 @@ extern "C" {
catch (z3_exception & ex) {
// The error handler is only available for contexts
// Just throw a warning.
std::ostringstream buffer;
buffer << "Error setting " << param_id << ": " << ex.msg();
warning_msg(buffer.str().c_str());
warning_msg(ex.msg());
return Z3_FALSE;
}
}
@ -92,9 +88,7 @@ extern "C" {
catch (z3_exception & ex) {
// The error handler is only available for contexts
// Just throw a warning.
std::ostringstream buffer;
buffer << "Error setting " << param_id << ": " << ex.msg();
warning_msg(buffer.str().c_str());
warning_msg(ex.msg());
}
}

View file

@ -109,6 +109,7 @@ namespace api {
m_basic_fid = m().get_basic_family_id();
m_arith_fid = m().mk_family_id("arith");
m_bv_fid = m().mk_family_id("bv");
m_pb_fid = m().mk_family_id("pb");
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");

View file

@ -75,6 +75,7 @@ namespace api {
family_id m_bv_fid;
family_id m_dt_fid;
family_id m_datalog_fid;
family_id m_pb_fid;
datatype_decl_plugin * m_dt_plugin;
std::string m_string_buffer; // temporary buffer used to cache strings sent to the "external" world.
@ -121,6 +122,7 @@ namespace api {
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_pb_fid() const { return m_pb_fid; }
datatype_decl_plugin * get_dt_plugin() const { return m_dt_plugin; }
Z3_error_code get_error_code() const { return m_error_code; }

View file

@ -125,7 +125,7 @@ namespace api {
return "unknown";
}
}
std::string to_string(unsigned num_queries, expr*const* queries) {
std::string to_string(unsigned num_queries, expr* const* queries) {
std::stringstream str;
m_context.display_smt2(num_queries, queries, str);
return str.str();
@ -466,13 +466,16 @@ extern "C" {
ast_manager& m = mk_c(c)->m();
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, m);
mk_c(c)->save_object(v);
expr_ref_vector rules(m);
expr_ref_vector rules(m), queries(m);
svector<symbol> names;
to_fixedpoint_ref(d)->ctx().get_rules_as_formulas(rules, names);
to_fixedpoint_ref(d)->ctx().get_rules_as_formulas(rules, queries, names);
for (unsigned i = 0; i < rules.size(); ++i) {
v->m_ast_vector.push_back(rules[i].get());
}
for (unsigned i = 0; i < queries.size(); ++i) {
v->m_ast_vector.push_back(m.mk_not(queries[i].get()));
}
RETURN_Z3(of_ast_vector(v));
Z3_CATCH_RETURN(0);
}

View file

@ -618,4 +618,25 @@ extern "C" {
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_datatype_update_field(
__in Z3_context c, __in Z3_func_decl f, __in Z3_ast t, __in Z3_ast v) {
Z3_TRY;
LOG_Z3_datatype_update_field(c, f, t, v);
RESET_ERROR_CODE();
ast_manager & m = mk_c(c)->m();
func_decl* _f = to_func_decl(f);
expr* _t = to_expr(t);
expr* _v = to_expr(v);
expr* args[2] = { _t, _v };
sort* domain[2] = { m.get_sort(_t), m.get_sort(_v) };
parameter param(_f);
func_decl * d = m.mk_func_decl(mk_c(c)->get_array_fid(), OP_DT_UPDATE_FIELD, 1, &param, 2, domain);
app* r = m.mk_app(d, 2, args);
mk_c(c)->save_ast_trail(r);
check_sorts(c, r);
RETURN_Z3(of_ast(r));
Z3_CATCH_RETURN(0);
}
};

243
src/api/api_opt.cpp Normal file
View file

@ -0,0 +1,243 @@
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
api_opt.cpp
Abstract:
API for optimization
Author:
Nikolaj Bjorner (nbjorner) 2013-12-3.
Revision History:
--*/
#include<iostream>
#include"z3.h"
#include"api_log_macros.h"
#include"api_stats.h"
#include"api_context.h"
#include"api_util.h"
#include"api_model.h"
#include"opt_context.h"
#include"cancel_eh.h"
#include"scoped_timer.h"
extern "C" {
struct Z3_optimize_ref : public api::object {
opt::context* m_opt;
Z3_optimize_ref():m_opt(0) {}
virtual ~Z3_optimize_ref() { dealloc(m_opt); }
};
inline Z3_optimize_ref * to_optimize(Z3_optimize o) { return reinterpret_cast<Z3_optimize_ref *>(o); }
inline Z3_optimize of_optimize(Z3_optimize_ref * o) { return reinterpret_cast<Z3_optimize>(o); }
inline opt::context* to_optimize_ptr(Z3_optimize o) { return to_optimize(o)->m_opt; }
Z3_optimize Z3_API Z3_mk_optimize(Z3_context c) {
Z3_TRY;
LOG_Z3_mk_optimize(c);
RESET_ERROR_CODE();
Z3_optimize_ref * o = alloc(Z3_optimize_ref);
o->m_opt = alloc(opt::context,mk_c(c)->m());
mk_c(c)->save_object(o);
RETURN_Z3(of_optimize(o));
Z3_CATCH_RETURN(0);
}
void Z3_API Z3_optimize_inc_ref(Z3_context c, Z3_optimize o) {
Z3_TRY;
LOG_Z3_optimize_inc_ref(c, o);
RESET_ERROR_CODE();
to_optimize(o)->inc_ref();
Z3_CATCH;
}
void Z3_API Z3_optimize_dec_ref(Z3_context c, Z3_optimize o) {
Z3_TRY;
LOG_Z3_optimize_dec_ref(c, o);
RESET_ERROR_CODE();
to_optimize(o)->dec_ref();
Z3_CATCH;
}
void Z3_API Z3_optimize_assert(Z3_context c, Z3_optimize o, Z3_ast a) {
Z3_TRY;
LOG_Z3_optimize_assert(c, o, a);
RESET_ERROR_CODE();
CHECK_FORMULA(a,);
to_optimize_ptr(o)->add_hard_constraint(to_expr(a));
Z3_CATCH;
}
unsigned Z3_API Z3_optimize_assert_soft(Z3_context c, Z3_optimize o, Z3_ast a, Z3_string weight, Z3_symbol id) {
Z3_TRY;
LOG_Z3_optimize_assert_soft(c, o, a, weight, id);
RESET_ERROR_CODE();
CHECK_FORMULA(a,0);
rational w(weight);
return to_optimize_ptr(o)->add_soft_constraint(to_expr(a), w, to_symbol(id));
Z3_CATCH_RETURN(0);
}
unsigned Z3_API Z3_optimize_maximize(Z3_context c, Z3_optimize o, Z3_ast t) {
Z3_TRY;
LOG_Z3_optimize_maximize(c, o, t);
RESET_ERROR_CODE();
CHECK_VALID_AST(t,0);
return to_optimize_ptr(o)->add_objective(to_app(t), true);
Z3_CATCH_RETURN(0);
}
unsigned Z3_API Z3_optimize_minimize(Z3_context c, Z3_optimize o, Z3_ast t) {
Z3_TRY;
LOG_Z3_optimize_minimize(c, o, t);
RESET_ERROR_CODE();
CHECK_VALID_AST(t,0);
return to_optimize_ptr(o)->add_objective(to_app(t), false);
Z3_CATCH_RETURN(0);
}
void Z3_API Z3_optimize_push(Z3_context c,Z3_optimize d) {
Z3_TRY;
LOG_Z3_optimize_push(c, d);
RESET_ERROR_CODE();
to_optimize_ptr(d)->push();
Z3_CATCH;
}
void Z3_API Z3_optimize_pop(Z3_context c,Z3_optimize d) {
Z3_TRY;
LOG_Z3_optimize_pop(c, d);
RESET_ERROR_CODE();
to_optimize_ptr(d)->pop(1);
Z3_CATCH;
}
Z3_lbool Z3_API Z3_optimize_check(Z3_context c, Z3_optimize o) {
Z3_TRY;
LOG_Z3_optimize_check(c, o);
RESET_ERROR_CODE();
lbool r = l_undef;
cancel_eh<opt::context> eh(*to_optimize_ptr(o));
unsigned timeout = to_optimize_ptr(o)->get_params().get_uint("timeout", mk_c(c)->get_timeout());
api::context::set_interruptable si(*(mk_c(c)), eh);
{
scoped_timer timer(timeout, &eh);
try {
r = to_optimize_ptr(o)->optimize();
}
catch (z3_exception& ex) {
mk_c(c)->handle_exception(ex);
r = l_undef;
}
// to_optimize_ref(d).cleanup();
}
return of_lbool(r);
Z3_CATCH_RETURN(Z3_L_UNDEF);
}
Z3_model Z3_API Z3_optimize_get_model(Z3_context c, Z3_optimize o) {
Z3_TRY;
LOG_Z3_optimize_get_model(c, o);
RESET_ERROR_CODE();
model_ref _m;
to_optimize_ptr(o)->get_model(_m);
Z3_model_ref * m_ref = alloc(Z3_model_ref);
if (_m) {
m_ref->m_model = _m;
}
else {
m_ref->m_model = alloc(model, mk_c(c)->m());
}
mk_c(c)->save_object(m_ref);
RETURN_Z3(of_model(m_ref));
Z3_CATCH_RETURN(0);
}
void Z3_API Z3_optimize_set_params(Z3_context c, Z3_optimize o, Z3_params p) {
Z3_TRY;
LOG_Z3_optimize_set_params(c, o, p);
RESET_ERROR_CODE();
param_descrs descrs;
to_optimize_ptr(o)->collect_param_descrs(descrs);
to_params(p)->m_params.validate(descrs);
params_ref pr = to_param_ref(p);
to_optimize_ptr(o)->updt_params(pr);
Z3_CATCH;
}
Z3_param_descrs Z3_API Z3_optimize_get_param_descrs(Z3_context c, Z3_optimize o) {
Z3_TRY;
LOG_Z3_optimize_get_param_descrs(c, o);
RESET_ERROR_CODE();
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref);
mk_c(c)->save_object(d);
to_optimize_ptr(o)->collect_param_descrs(d->m_descrs);
Z3_param_descrs r = of_param_descrs(d);
RETURN_Z3(r);
Z3_CATCH_RETURN(0);
}
// get lower value or current approximation
Z3_ast Z3_API Z3_optimize_get_lower(Z3_context c, Z3_optimize o, unsigned idx) {
Z3_TRY;
LOG_Z3_optimize_get_lower(c, o, idx);
RESET_ERROR_CODE();
expr_ref e = to_optimize_ptr(o)->get_lower(idx);
mk_c(c)->save_ast_trail(e);
RETURN_Z3(of_expr(e));
Z3_CATCH_RETURN(0);
}
// get upper or current approximation
Z3_ast Z3_API Z3_optimize_get_upper(Z3_context c, Z3_optimize o, unsigned idx) {
Z3_TRY;
LOG_Z3_optimize_get_upper(c, o, idx);
RESET_ERROR_CODE();
expr_ref e = to_optimize_ptr(o)->get_upper(idx);
mk_c(c)->save_ast_trail(e);
RETURN_Z3(of_expr(e));
Z3_CATCH_RETURN(0);
}
Z3_string Z3_API Z3_optimize_to_string(Z3_context c, Z3_optimize o) {
Z3_TRY;
LOG_Z3_optimize_to_string(c, o);
RESET_ERROR_CODE();
return mk_c(c)->mk_external_string(to_optimize_ptr(o)->to_string());
Z3_CATCH_RETURN("");
}
Z3_string Z3_API Z3_optimize_get_help(Z3_context c, Z3_optimize d) {
Z3_TRY;
LOG_Z3_optimize_get_help(c, d);
RESET_ERROR_CODE();
std::ostringstream buffer;
param_descrs descrs;
to_optimize_ptr(d)->collect_param_descrs(descrs);
descrs.display(buffer);
return mk_c(c)->mk_external_string(buffer.str());
Z3_CATCH_RETURN("");
}
Z3_stats Z3_API Z3_optimize_get_statistics(Z3_context c,Z3_optimize d) {
Z3_TRY;
LOG_Z3_optimize_get_statistics(c, d);
RESET_ERROR_CODE();
Z3_stats_ref * st = alloc(Z3_stats_ref);
to_optimize_ptr(d)->collect_statistics(st->m_stats);
mk_c(c)->save_object(st);
Z3_stats r = of_stats(st);
RETURN_Z3(r);
Z3_CATCH_RETURN(0);
}
};

61
src/api/api_pb.cpp Normal file
View file

@ -0,0 +1,61 @@
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
api_pb.cpp
Abstract:
API for pb theory
Author:
Nikolaj Bjorner (nbjorner) 2013-11-13.
Revision History:
--*/
#include<iostream>
#include"z3.h"
#include"api_log_macros.h"
#include"api_context.h"
#include"api_util.h"
#include"pb_decl_plugin.h"
extern "C" {
Z3_ast Z3_API Z3_mk_atmost(Z3_context c, unsigned num_args,
Z3_ast const args[], unsigned k) {
Z3_TRY;
LOG_Z3_mk_atmost(c, num_args, args, k);
RESET_ERROR_CODE();
parameter param(k);
pb_util util(mk_c(c)->m());
ast* a = util.mk_at_most_k(num_args, to_exprs(args), k);
mk_c(c)->save_ast_trail(a);
check_sorts(c, a);
RETURN_Z3(of_ast(a));
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_API Z3_mk_pble(Z3_context c, unsigned num_args,
Z3_ast const args[], int _coeffs[],
int k) {
Z3_TRY;
LOG_Z3_mk_pble(c, num_args, args, _coeffs, k);
RESET_ERROR_CODE();
pb_util util(mk_c(c)->m());
vector<rational> coeffs;
for (unsigned i = 0; i < num_args; ++i) {
coeffs.push_back(rational(_coeffs[i]));
}
ast* a = util.mk_le(num_args, coeffs.c_ptr(), to_exprs(args), rational(k));
mk_c(c)->save_ast_trail(a);
check_sorts(c, a);
RETURN_Z3(of_ast(a));
Z3_CATCH_RETURN(0);
}
};

View file

@ -1314,6 +1314,26 @@ namespace z3 {
expr_vector assertions() const { Z3_ast_vector r = Z3_solver_get_assertions(ctx(), m_solver); check_error(); return expr_vector(ctx(), r); }
expr proof() const { Z3_ast r = Z3_solver_get_proof(ctx(), m_solver); check_error(); return expr(ctx(), r); }
friend std::ostream & operator<<(std::ostream & out, solver const & s) { out << Z3_solver_to_string(s.ctx(), s); return out; }
std::string to_smt2(char const* status = "unknown") {
array<Z3_ast> es(assertions());
Z3_ast const* fmls = es.ptr();
Z3_ast fml = 0;
unsigned sz = es.size();
if (sz > 0) {
--sz;
fml = fmls[sz];
}
else {
fml = ctx().bool_val(true);
}
return std::string(Z3_benchmark_to_smtlib_string(
ctx(),
"", "", status, "",
sz,
fmls,
fml));
}
};
class goal : public object {
@ -1513,6 +1533,62 @@ namespace z3 {
}
};
class optimize : public object {
Z3_optimize m_opt;
public:
class handle {
unsigned m_h;
public:
handle(unsigned h): m_h(h) {}
unsigned h() const { return m_h; }
};
optimize(context& c):object(c) { m_opt = Z3_mk_optimize(c); Z3_optimize_inc_ref(c, m_opt); }
~optimize() { Z3_optimize_dec_ref(ctx(), m_opt); }
operator Z3_optimize() const { return m_opt; }
void add(expr const& e) {
assert(e.is_bool());
Z3_optimize_assert(ctx(), m_opt, e);
}
handle add(expr const& e, unsigned weight) {
assert(e.is_bool());
std::stringstream strm;
strm << weight;
return handle(Z3_optimize_assert_soft(ctx(), m_opt, e, strm.str().c_str(), 0));
}
handle add(expr const& e, char const* weight) {
assert(e.is_bool());
return handle(Z3_optimize_assert_soft(ctx(), m_opt, e, weight, 0));
}
handle maximize(expr const& e) {
return handle(Z3_optimize_maximize(ctx(), m_opt, e));
}
handle minimize(expr const& e) {
return handle(Z3_optimize_minimize(ctx(), m_opt, e));
}
void push() {
Z3_optimize_push(ctx(), m_opt);
}
void pop() {
Z3_optimize_pop(ctx(), m_opt);
}
check_result check() { Z3_lbool r = Z3_optimize_check(ctx(), m_opt); check_error(); return to_check_result(r); }
model get_model() const { Z3_model m = Z3_optimize_get_model(ctx(), m_opt); check_error(); return model(ctx(), m); }
void set(params const & p) { Z3_optimize_set_params(ctx(), m_opt, p); check_error(); }
expr lower(handle const& h) {
Z3_ast r = Z3_optimize_get_lower(ctx(), m_opt, h.h());
check_error();
return expr(ctx(), r);
}
expr upper(handle const& h) {
Z3_ast r = Z3_optimize_get_upper(ctx(), m_opt, h.h());
check_error();
return expr(ctx(), r);
}
stats statistics() const { Z3_stats r = Z3_optimize_get_statistics(ctx(), m_opt); check_error(); return stats(ctx(), r); }
friend std::ostream & operator<<(std::ostream & out, optimize const & s) { out << Z3_optimize_to_string(s.ctx(), s.m_opt); return out; }
std::string help() const { char const * r = Z3_optimize_get_help(ctx(), m_opt); check_error(); return r; }
};
inline tactic fail_if(probe const & p) {
Z3_tactic r = Z3_tactic_fail_if(p.ctx(), p);
p.check_error();

View file

@ -449,6 +449,19 @@ namespace Microsoft.Z3
return MkDatatypeSorts(MkSymbols(names), c);
}
/// <summary>
/// Update a datatype field at expression t with value v.
/// The function performs a record update at t. The field
/// that is passed in as argument is updated with value v,
/// the remainig fields of t are unchanged.
/// </summary>
public Expr MkUpdateField(FuncDecl field, Expr t, Expr v)
{
return Expr.Create(this, Native.Z3_datatype_update_field(
nCtx, field.NativeObject,
t.NativeObject, v.NativeObject));
}
#endregion
#endregion
@ -2251,6 +2264,36 @@ namespace Microsoft.Z3
}
#endregion
#region Pseudo-Boolean constraints
/// <summary>
/// Create an at-most-k constraint.
/// </summary>
public BoolExpr MkAtMost(BoolExpr[] args, uint k)
{
Contract.Requires(args != null);
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
CheckContextMatch(args);
return new BoolExpr(this, Native.Z3_mk_atmost(nCtx, (uint) args.Length,
AST.ArrayToNative(args), k));
}
/// <summary>
/// Create a pseudo-Boolean less-or-equal constraint.
/// </summary>
public BoolExpr MkPBLe(int[] coeffs, BoolExpr[] args, int k)
{
Contract.Requires(args != null);
Contract.Requires(coeffs != null);
Contract.Requires(args.Length == coeffs.Length);
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
CheckContextMatch(args);
return new BoolExpr(this, Native.Z3_mk_pble(nCtx, (uint) args.Length,
AST.ArrayToNative(args),
coeffs, k));
}
#endregion
#region Numerals
#region General Numerals
@ -3438,6 +3481,18 @@ namespace Microsoft.Z3
}
#endregion
#region Optimization
/// <summary>
/// Create an Optimization context.
/// </summary>
public Optimize MkOptimize()
{
Contract.Ensures(Contract.Result<Optimize>() != null);
return new Optimize(this);
}
#endregion
#region Miscellaneous
/// <summary>
@ -3594,6 +3649,7 @@ namespace Microsoft.Z3
Contract.Invariant(m_Statistics_DRQ != null);
Contract.Invariant(m_Tactic_DRQ != null);
Contract.Invariant(m_Fixedpoint_DRQ != null);
Contract.Invariant(m_Optimize_DRQ != null);
}
readonly private AST.DecRefQueue m_AST_DRQ = new AST.DecRefQueue();
@ -3611,6 +3667,7 @@ namespace Microsoft.Z3
readonly private Statistics.DecRefQueue m_Statistics_DRQ = new Statistics.DecRefQueue();
readonly private Tactic.DecRefQueue m_Tactic_DRQ = new Tactic.DecRefQueue();
readonly private Fixedpoint.DecRefQueue m_Fixedpoint_DRQ = new Fixedpoint.DecRefQueue();
readonly private Optimize.DecRefQueue m_Optimize_DRQ = new Optimize.DecRefQueue();
internal AST.DecRefQueue AST_DRQ { get { Contract.Ensures(Contract.Result<AST.DecRefQueue>() != null); return m_AST_DRQ; } }
internal ASTMap.DecRefQueue ASTMap_DRQ { get { Contract.Ensures(Contract.Result<ASTMap.DecRefQueue>() != null); return m_ASTMap_DRQ; } }
@ -3627,6 +3684,7 @@ namespace Microsoft.Z3
internal Statistics.DecRefQueue Statistics_DRQ { get { Contract.Ensures(Contract.Result<Statistics.DecRefQueue>() != null); return m_Statistics_DRQ; } }
internal Tactic.DecRefQueue Tactic_DRQ { get { Contract.Ensures(Contract.Result<Tactic.DecRefQueue>() != null); return m_Tactic_DRQ; } }
internal Fixedpoint.DecRefQueue Fixedpoint_DRQ { get { Contract.Ensures(Contract.Result<Fixedpoint.DecRefQueue>() != null); return m_Fixedpoint_DRQ; } }
internal Optimize.DecRefQueue Optimize_DRQ { get { Contract.Ensures(Contract.Result<Optimize.DecRefQueue>() != null); return m_Optimize_DRQ; } }
internal long refCount = 0;
@ -3670,6 +3728,7 @@ namespace Microsoft.Z3
Statistics_DRQ.Clear(this);
Tactic_DRQ.Clear(this);
Fixedpoint_DRQ.Clear(this);
Optimize_DRQ.Clear(this);
m_boolSort = null;
m_intSort = null;

View file

@ -0,0 +1,111 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
Deprecated.cs
Abstract:
Expose deprecated features for use from the managed API
those who use them for experiments.
Author:
Christoph Wintersteiger (cwinter) 2012-03-15
Notes:
--*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Diagnostics.Contracts;
namespace Microsoft.Z3
{
/// <summary>
/// The main interaction with Z3 happens via the Context.
/// </summary>
[ContractVerification(true)]
public class Deprecated
{
/// <summary>
/// Creates a backtracking point.
/// </summary>
/// <seealso cref="Pop"/>
public static void Push(Context ctx) {
Native.Z3_push(ctx.nCtx);
}
/// <summary>
/// Backtracks <paramref name="n"/> backtracking points.
/// </summary>
/// <remarks>Note that an exception is thrown if <paramref name="n"/> is not smaller than <c>NumScopes</c></remarks>
/// <seealso cref="Push"/>
public static void Pop(Context ctx, uint n = 1) {
Native.Z3_pop(ctx.nCtx, n);
}
/// <summary>
/// Assert a constraint (or multiple) into the solver.
/// </summary>
public static void Assert(Context ctx, params BoolExpr[] constraints)
{
Contract.Requires(constraints != null);
Contract.Requires(Contract.ForAll(constraints, c => c != null));
ctx.CheckContextMatch(constraints);
foreach (BoolExpr a in constraints)
{
Native.Z3_assert_cnstr(ctx.nCtx, a.NativeObject);
}
}
/// <summary>
/// Checks whether the assertions in the context are consistent or not.
/// </summary>
public static Status Check(Context ctx, List<BoolExpr> core, ref Model model, ref Expr proof, params Expr[] assumptions)
{
Z3_lbool r;
model = null;
proof = null;
if (assumptions == null || assumptions.Length == 0)
r = (Z3_lbool)Native.Z3_check(ctx.nCtx);
else {
IntPtr mdl = IntPtr.Zero, prf = IntPtr.Zero;
uint core_size = 0;
IntPtr[] native_core = new IntPtr[assumptions.Length];
r = (Z3_lbool)Native.Z3_check_assumptions(ctx.nCtx,
(uint)assumptions.Length, AST.ArrayToNative(assumptions),
ref mdl, ref prf, ref core_size, native_core);
for (uint i = 0; i < core_size; i++)
core.Add((BoolExpr)Expr.Create(ctx, native_core[i]));
if (mdl != IntPtr.Zero) {
model = new Model(ctx, mdl);
}
if (prf != IntPtr.Zero) {
proof = Expr.Create(ctx, prf);
}
}
switch (r)
{
case Z3_lbool.Z3_L_TRUE: return Status.SATISFIABLE;
case Z3_lbool.Z3_L_FALSE: return Status.UNSATISFIABLE;
default: return Status.UNKNOWN;
}
}
/// <summary>
/// Retrieves an assignment to atomic propositions for a satisfiable context.
/// </summary>
public static BoolExpr GetAssignment(Context ctx)
{
IntPtr x = Native.Z3_get_context_assignment(ctx.nCtx);
return (BoolExpr)Expr.Create(ctx, x);
}
}
}

View file

@ -304,6 +304,19 @@ namespace Microsoft.Z3
}
/// <summary>
/// Fixedpoint statistics.
/// </summary>
public Statistics Statistics
{
get
{
Contract.Ensures(Contract.Result<Statistics>() != null);
return new Statistics(Context, Native.Z3_fixedpoint_get_statistics(Context.nCtx, NativeObject));
}
}
/// <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.

View file

@ -19,12 +19,12 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\..\..\cwinter\bugs\z3bugs\Debug\</OutputPath>
<OutputPath>..\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>C:\cwinter\bugs\z3bugs\Debug\Microsoft.Z3.XML</DocumentationFile>
<DocumentationFile>..\Debug\Microsoft.Z3.XML</DocumentationFile>
<CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
<CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
<CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
@ -254,7 +254,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\..\..\..\..\cwinter\bugs\z3bugs\Debug\</OutputPath>
<OutputPath>..\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DebugType>full</DebugType>
@ -266,7 +266,7 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
<DocumentationFile>C:\cwinter\bugs\z3bugs\Debug\Microsoft.Z3.XML</DocumentationFile>
<DocumentationFile>..\x86\Debug\Microsoft.Z3.XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>

296
src/api/dotnet/Optimize.cs Normal file
View file

@ -0,0 +1,296 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
Optimize.cs
Abstract:
Z3 Managed API: Optimizes
Author:
Nikolaj Bjorner (nbjorner) 2013-12-03
Notes:
--*/
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
namespace Microsoft.Z3
{
/// <summary>
/// Object for managing optimizization context
/// </summary>
[ContractVerification(true)]
public class Optimize : Z3Object
{
/// <summary>
/// A string that describes all available optimize solver parameters.
/// </summary>
public string Help
{
get
{
Contract.Ensures(Contract.Result<string>() != null);
return Native.Z3_optimize_get_help(Context.nCtx, NativeObject);
}
}
/// <summary>
/// Sets the optimize solver parameters.
/// </summary>
public Params Parameters
{
set
{
Contract.Requires(value != null);
Context.CheckContextMatch(value);
Native.Z3_optimize_set_params(Context.nCtx, NativeObject, value.NativeObject);
}
}
/// <summary>
/// Retrieves parameter descriptions for Optimize solver.
/// </summary>
public ParamDescrs ParameterDescriptions
{
get { return new ParamDescrs(Context, Native.Z3_optimize_get_param_descrs(Context.nCtx, NativeObject)); }
}
/// <summary>
/// Assert a constraint (or multiple) into the optimize solver.
/// </summary>
public void Assert(params BoolExpr[] constraints)
{
Contract.Requires(constraints != null);
Contract.Requires(Contract.ForAll(constraints, c => c != null));
Context.CheckContextMatch(constraints);
foreach (BoolExpr a in constraints)
{
Native.Z3_optimize_assert(Context.nCtx, NativeObject, a.NativeObject);
}
}
/// <summary>
/// Alias for Assert.
/// </summary>
public void Add(params BoolExpr[] constraints)
{
Assert(constraints);
}
/// <summary>
/// Handle to objectives returned by objective functions.
/// </summary>
public class Handle
{
Optimize opt;
uint handle;
internal Handle(Optimize opt, uint h)
{
this.opt = opt;
this.handle = h;
}
/// <summary>
/// Retrieve a lower bound for the objective handle.
/// </summary>
public ArithExpr Lower
{
get { return opt.GetLower(handle); }
}
/// <summary>
/// Retrieve an upper bound for the objective handle.
/// </summary>
public ArithExpr Upper
{
get { return opt.GetUpper(handle); }
}
/// <summary>
/// Retrieve the value of an objective.
/// </summary>
public ArithExpr Value
{
get { return Lower; }
}
}
/// <summary>
/// Assert soft constraint
/// </summary>
/// <remarks>
/// Return an objective which associates with the group of constraints.
/// </remarks>
public Handle AssertSoft(BoolExpr constraint, uint weight, string group)
{
Context.CheckContextMatch(constraint);
Symbol s = Context.MkSymbol(group);
return new Handle(this, Native.Z3_optimize_assert_soft(Context.nCtx, NativeObject, constraint.NativeObject, weight.ToString(), s.NativeObject));
}
///
/// <summary>
/// Check satisfiability of asserted constraints.
/// Produce a model that (when the objectives are bounded and
/// don't use strict inequalities) meets the objectives.
/// </summary>
///
public Status Check() {
Z3_lbool r = (Z3_lbool)Native.Z3_optimize_check(Context.nCtx, NativeObject);
switch (r)
{
case Z3_lbool.Z3_L_TRUE:
return Status.SATISFIABLE;
case Z3_lbool.Z3_L_FALSE:
return Status.UNSATISFIABLE;
default:
return Status.UNKNOWN;
}
}
/// <summary>
/// Creates a backtracking point.
/// </summary>
/// <seealso cref="Pop"/>
public void Push()
{
Native.Z3_optimize_push(Context.nCtx, NativeObject);
}
/// <summary>
/// Backtrack one backtracking point.
/// </summary>
/// <remarks>Note that an exception is thrown if Pop is called without a corresponding <c>Push</c></remarks>
/// <seealso cref="Push"/>
public void Pop()
{
Native.Z3_optimize_pop(Context.nCtx, NativeObject);
}
/// <summary>
/// The model of the last <c>Check</c>.
/// </summary>
/// <remarks>
/// The result is <c>null</c> if <c>Check</c> was not invoked before,
/// if its results was not <c>SATISFIABLE</c>, or if model production is not enabled.
/// </remarks>
public Model Model
{
get
{
IntPtr x = Native.Z3_optimize_get_model(Context.nCtx, NativeObject);
if (x == IntPtr.Zero)
return null;
else
return new Model(Context, x);
}
}
/// <summary>
/// Declare an arithmetical maximization objective.
/// Return a handle to the objective. The handle is used as
/// to retrieve the values of objectives after calling Check.
/// </summary>
public Handle MkMaximize(ArithExpr e)
{
return new Handle(this, Native.Z3_optimize_maximize(Context.nCtx, NativeObject, e.NativeObject));
}
/// <summary>
/// Declare an arithmetical minimization objective.
/// Similar to MkMaximize.
/// </summary>
public Handle MkMinimize(ArithExpr e)
{
return new Handle(this, Native.Z3_optimize_minimize(Context.nCtx, NativeObject, e.NativeObject));
}
/// <summary>
/// Retrieve a lower bound for the objective handle.
/// </summary>
private ArithExpr GetLower(uint index)
{
return (ArithExpr)Expr.Create(Context, Native.Z3_optimize_get_lower(Context.nCtx, NativeObject, index));
}
/// <summary>
/// Retrieve an upper bound for the objective handle.
/// </summary>
private ArithExpr GetUpper(uint index)
{
return (ArithExpr)Expr.Create(Context, Native.Z3_optimize_get_upper(Context.nCtx, NativeObject, index));
}
/// <summary>
/// Print the context to a string (SMT-LIB parseable benchmark).
/// </summary>
public override string ToString()
{
return Native.Z3_optimize_to_string(Context.nCtx, NativeObject);
}
/// <summary>
/// Optimize statistics.
/// </summary>
public Statistics Statistics
{
get
{
Contract.Ensures(Contract.Result<Statistics>() != null);
return new Statistics(Context, Native.Z3_optimize_get_statistics(Context.nCtx, NativeObject));
}
}
#region Internal
internal Optimize(Context ctx, IntPtr obj)
: base(ctx, obj)
{
Contract.Requires(ctx != null);
}
internal Optimize(Context ctx)
: base(ctx, Native.Z3_mk_optimize(ctx.nCtx))
{
Contract.Requires(ctx != null);
}
internal class DecRefQueue : IDecRefQueue
{
public override void IncRef(Context ctx, IntPtr obj)
{
Native.Z3_optimize_inc_ref(ctx.nCtx, obj);
}
public override void DecRef(Context ctx, IntPtr obj)
{
Native.Z3_optimize_dec_ref(ctx.nCtx, obj);
}
};
internal override void IncRef(IntPtr o)
{
Context.Optimize_DRQ.IncAndClear(Context, o);
base.IncRef(o);
}
internal override void DecRef(IntPtr o)
{
Context.Optimize_DRQ.Add(o);
base.DecRef(o);
}
#endregion
}
}

View file

@ -79,6 +79,7 @@ namespace Microsoft.Z3
Native.Z3_params_set_symbol(Context.nCtx, NativeObject, name.NativeObject, value.NativeObject);
}
/// <summary>
/// Adds a parameter setting.
/// </summary>
@ -118,6 +119,7 @@ namespace Microsoft.Z3
/// </summary>
public void Add(string name, string value)
{
Contract.Requires(name != null);
Contract.Requires(value != null);
Native.Z3_params_set_symbol(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, Context.MkSymbol(value).NativeObject);

View file

@ -0,0 +1,9 @@
The default Z3 bindings for .NET are built for the .NET framework version 4.
Should the need arise, it is also possible to build them for .NET 3.5; the
instructions are as follows:
In the project properties of Microsoft.Z3.csproj:
- Under 'Application': Change Target framework to .NET Framework 3.5
- Under 'Build': Add FRAMEWORK_LT_4 to the condidional compilation symbols
- Remove the reference to System.Numerics
- Install the NuGet Package "Microsoft Code Contracts for Net3.5"

View file

@ -375,6 +375,23 @@ public class Context extends IDisposable
return mkDatatypeSorts(MkSymbols(names), c);
}
/**
* Update a datatype field at expression t with value v.
* The function performs a record update at t. The field
* that is passed in as argument is updated with value v,
* the remainig fields of t are unchanged.
**/
public Expr MkUpdateField(FuncDecl field, Expr t, Expr v)
throws Z3Exception
{
return Expr.create
(this,
Native.datatypeUpdateField
(nCtx(), field.getNativeObject(),
t.getNativeObject(), v.getNativeObject()));
}
/**
* Creates a new function declaration.
**/

View file

@ -319,6 +319,18 @@ public class Fixedpoint extends Z3Object
return res;
}
/**
* Fixedpoint statistics.
*
* @throws Z3Exception
**/
public Statistics getStatistics() throws Z3Exception
{
return new Statistics(getContext(), Native.fixedpointGetStatistics(
getContext().nCtx(), getNativeObject()));
}
Fixedpoint(Context ctx, long obj) throws Z3Exception
{
super(ctx, obj);

View file

@ -298,9 +298,8 @@ class AstRef(Z3PPObject):
return self.ast
def get_id(self):
"""Return unique identifier for object. It can be used for hash-tables and maps."""
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
"""Return unique identifier for object. It can be used for hash-tables and maps."""
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
def ctx_ref(self):
"""Return a reference to the C context where this AST node is stored."""
@ -453,8 +452,7 @@ class SortRef(AstRef):
return Z3_sort_to_ast(self.ctx_ref(), self.ast)
def get_id(self):
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
def kind(self):
"""Return the Z3 internal kind of a sort. This method can be used to test if `self` is one of the Z3 builtin sorts.
@ -555,6 +553,8 @@ def _to_sort_ref(s, ctx):
return ArraySortRef(s, ctx)
elif k == Z3_DATATYPE_SORT:
return DatatypeSortRef(s, ctx)
elif k == Z3_FINITE_DOMAIN_SORT:
return FiniteDomainSortRef(s, ctx)
return SortRef(s, ctx)
def _sort(ctx, a):
@ -595,7 +595,7 @@ class FuncDeclRef(AstRef):
return Z3_func_decl_to_ast(self.ctx_ref(), self.ast)
def get_id(self):
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
def as_func_decl(self):
return self.ast
@ -743,7 +743,7 @@ class ExprRef(AstRef):
return self.ast
def get_id(self):
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
def sort(self):
"""Return the sort of expression `self`.
@ -1540,7 +1540,7 @@ class PatternRef(ExprRef):
return Z3_pattern_to_ast(self.ctx_ref(), self.ast)
def get_id(self):
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
def is_pattern(a):
"""Return `True` if `a` is a Z3 pattern (hint for quantifier instantiation.
@ -1605,7 +1605,7 @@ class QuantifierRef(BoolRef):
return self.ast
def get_id(self):
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
return Z3_get_ast_id(self.ctx_ref(), self.as_ast())
def sort(self):
"""Return the Boolean sort."""
@ -6033,22 +6033,20 @@ class Solver(Z3PPObject):
return Z3_solver_to_string(self.ctx.ref(), self.solver)
def to_smt2(self):
"""return SMTLIB2 formatted benchmark for solver's assertions"""
es = self.assertions()
sz = len(es)
sz1 = sz
if sz1 > 0:
sz1 -= 1
v = (Ast * sz1)()
for i in range(sz1):
v[i] = es[i].as_ast()
if sz > 0:
e = es[sz1].as_ast()
else:
e = BoolVal(True, self.ctx).as_ast()
return Z3_benchmark_to_smtlib_string(self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e)
"""return SMTLIB2 formatted benchmark for solver's assertions"""
es = self.assertions()
sz = len(es)
sz1 = sz
if sz1 > 0:
sz1 -= 1
v = (Ast * sz1)()
for i in range(sz1):
v[i] = es[i].as_ast()
if sz > 0:
e = es[sz1].as_ast()
else:
e = BoolVal(True, self.ctx).as_ast()
return Z3_benchmark_to_smtlib_string(self.ctx.ref(), "benchmark generated from python API", "", "unknown", "", sz1, v, e)
def SolverFor(logic, ctx=None):
"""Create a solver customized for the given logic.
@ -6166,7 +6164,7 @@ class Fixedpoint(Z3PPObject):
Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, head.as_ast(), name)
else:
body = _get_args(body)
f = self.abstract(Implies(And(body),head))
f = self.abstract(Implies(And(body, self.ctx),head))
Z3_fixedpoint_add_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
def rule(self, head, body = None, name = None):
@ -6183,7 +6181,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:
@ -6194,7 +6192,7 @@ class Fixedpoint(Z3PPObject):
if sz == 1:
query = query[0]
else:
query = And(query)
query = And(query, self.ctx)
query = self.abstract(query, False)
r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast())
return CheckSatResult(r)
@ -6213,7 +6211,7 @@ class Fixedpoint(Z3PPObject):
name = ""
name = to_symbol(name, self.ctx)
body = _get_args(body)
f = self.abstract(Implies(And(body),head))
f = self.abstract(Implies(And(body, self.ctx),head))
Z3_fixedpoint_update_rule(self.ctx.ref(), self.fixedpoint, f.as_ast(), name)
def get_answer(self):
@ -6310,6 +6308,166 @@ class Fixedpoint(Z3PPObject):
else:
return Exists(self.vars, fml)
#########################################
#
# Finite domain sorts
#
#########################################
class FiniteDomainSortRef(SortRef):
"""Finite domain sort."""
def size(self):
"""Return the size of the finite domain sort"""
r = (ctype.c_ulonglong * 1)()
if Z3_get_finite_domain_sort_size(self.ctx_ref(), self.ast(), r):
return r[0]
else:
raise Z3Exception("Failed to retrieve finite domain sort size")
def FiniteDomainSort(name, sz, ctx=None):
"""Create a named finite domain sort of a given size sz"""
ctx = _get_ctx(ctx)
return FiniteDomainSortRef(Z3_mk_finite_domain_sort(ctx.ref(), name, sz), ctx)
#########################################
#
# Optimize
#
#########################################
class OptimizeObjective:
def __init__(self, opt, value, is_max):
self._opt = opt
self._value = value
self._is_max = is_max
def lower(self):
opt = self._opt
return _to_expr_ref(Z3_optimize_get_lower(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
def upper(self):
opt = self._opt
return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
def value(self):
if self._is_max:
return self.upper()
else:
return self.lower()
class Optimize(Z3PPObject):
"""Optimize API provides methods for solving using objective functions and weighted soft constraints"""
def __init__(self, ctx=None):
self.ctx = _get_ctx(ctx)
self.optimize = Z3_mk_optimize(self.ctx.ref())
Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
def __del__(self):
if self.optimize != None:
Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
def set(self, *args, **keys):
"""Set a configuration option. The method `help()` return a string containing all available options.
"""
p = args2params(args, keys, self.ctx)
Z3_optimize_set_params(self.ctx.ref(), self.optimize, p.params)
def help(self):
"""Display a string describing all available options."""
print(Z3_optimize_get_help(self.ctx.ref(), self.optimize))
def param_descrs(self):
"""Return the parameter description set."""
return ParamDescrsRef(Z3_optimize_get_param_descrs(self.ctx.ref(), self.optimize), self.ctx)
def assert_exprs(self, *args):
"""Assert constraints as background axioms for the optimize solver."""
args = _get_args(args)
for arg in args:
if isinstance(arg, Goal) or isinstance(arg, AstVector):
for f in arg:
Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
else:
Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
def add(self, *args):
"""Assert constraints as background axioms for the optimize solver. Alias for assert_expr."""
self.assert_exprs(*args)
def add_soft(self, arg, weight = "1", id = None):
"""Add soft constraint with optional weight and optional identifier.
If no weight is supplied, then the penalty for violating the soft constraint
is 1.
Soft constraints are grouped by identifiers. Soft constraints that are
added without identifiers are grouped by default.
"""
if _is_int(weight):
weight = "%d" % weight
if not isinstance(weight, str):
raise Z3Exception("weight should be a string or an integer")
if id == None:
id = ""
id = to_symbol(id, self.ctx)
v = Z3_optimize_assert_soft(self.ctx.ref(), self.optimize, arg.as_ast(), weight, id)
return OptimizeObjective(self, v, False)
def maximize(self, arg):
"""Add objective function to maximize."""
return OptimizeObjective(self, Z3_optimize_maximize(self.ctx.ref(), self.optimize, arg.as_ast()), True)
def minimize(self, arg):
"""Add objective function to minimize."""
return OptimizeObjective(self, Z3_optimize_minimize(self.ctx.ref(), self.optimize, arg.as_ast()), False)
def push(self):
"""create a backtracking point for added rules, facts and assertions"""
Z3_optimize_push(self.ctx.ref(), self.optimize)
def pop(self):
"""restore to previously created backtracking point"""
Z3_optimize_pop(self.ctx.ref(), self.optimize)
def check(self):
"""Check satisfiability while optimizing objective functions."""
return CheckSatResult(Z3_optimize_check(self.ctx.ref(), self.optimize))
def model(self):
"""Return a model for the last check()."""
try:
return ModelRef(Z3_optimize_get_model(self.ctx.ref(), self.optimize), self.ctx)
except Z3Exception:
raise Z3Exception("model is not available")
def lower(self, obj):
if not isinstance(obj, OptimizeObjective):
raise Z3Exception("Expecting objective handle returned by maximize/minimize")
return obj.lower()
def upper(self, obj):
if not isinstance(obj, OptimizeObjective):
raise Z3Exception("Expecting objective handle returned by maximize/minimize")
return obj.upper()
def __repr__(self):
"""Return a formatted string with all added rules and constraints."""
return self.sexpr()
def sexpr(self):
"""Return a formatted string (in Lisp-like format) with all added constraints. We say the string is in s-expression format.
"""
return Z3_optimize_to_string(self.ctx.ref(), self.optimize)
def statistics(self):
"""Return statistics for the last `query()`.
"""
return Statistics(Z3_optimize_get_statistics(self.ctx.ref(), self.optimize), self.ctx)
#########################################
#
# ApplyResult

View file

@ -842,6 +842,8 @@ class Formatter:
return self.pp_seq(a.assertions(), 0, [])
elif isinstance(a, z3.Fixedpoint):
return a.sexpr()
elif isinstance(a, z3.Optimize):
return a.sexpr()
elif isinstance(a, z3.ApplyResult):
return self.pp_seq_seq(a, 0, [])
elif isinstance(a, z3.ModelRef):

View file

@ -78,6 +78,10 @@ class FixedpointObj(ctypes.c_void_p):
def __init__(self, fixedpoint): self._as_parameter_ = fixedpoint
def from_param(obj): return obj
class OptimizeObj(ctypes.c_void_p):
def __init__(self, optimize): self._as_parameter_ = optimize
def from_param(obj): return obj
class ModelObj(ctypes.c_void_p):
def __init__(self, model): self._as_parameter_ = model
def from_param(obj): return obj

View file

@ -47,6 +47,7 @@ DEFINE_TYPE(Z3_func_interp);
#define Z3_func_interp_opt Z3_func_interp
DEFINE_TYPE(Z3_func_entry);
DEFINE_TYPE(Z3_fixedpoint);
DEFINE_TYPE(Z3_optimize);
DEFINE_TYPE(Z3_rcf_num);
DEFINE_VOID(Z3_theory_data);
#endif
@ -85,6 +86,7 @@ DEFINE_VOID(Z3_theory_data);
- \c Z3_func_interp: interpretation of a function in a model.
- \c Z3_func_entry: representation of the value of a \c Z3_func_interp at a particular point.
- \c Z3_fixedpoint: context for the recursive predicate solver.
- \c Z3_optimize: context for solving optimization queries.
- \c Z3_ast_vector: vector of \c Z3_ast objects.
- \c Z3_ast_map: mapping from \c Z3_ast to \c Z3_ast objects.
- \c Z3_goal: set of formulas that can be solved and/or transformed using tactics and solvers.
@ -875,6 +877,17 @@ typedef enum
- Z3_OP_DT_ACCESSOR: datatype accessor.
- Z3_OP_DT_UPDATE_FIELD: datatype field update.
- Z3_OP_PB_AT_MOST: Cardinality constraint.
E.g., x + y + z <= 2
- Z3_OP_PB_LE: Generalized Pseudo-Boolean cardinality constraint.
Example 2*x + 3*y <= 4
- Z3_OP_PB_GE: Generalized Pseudo-Boolean cardinality constraint.
Example 2*x + 3*y + 2*z >= 4
- Z3_OP_UNINTERPRETED: kind used for uninterpreted symbols.
*/
typedef enum {
@ -1055,6 +1068,12 @@ typedef enum {
Z3_OP_DT_CONSTRUCTOR=0x800,
Z3_OP_DT_RECOGNISER,
Z3_OP_DT_ACCESSOR,
Z3_OP_DT_UPDATE_FIELD,
// Pseudo Booleans
Z3_OP_PB_AT_MOST=0x900,
Z3_OP_PB_LE,
Z3_OP_PB_GE,
Z3_OP_UNINTERPRETED
} Z3_decl_kind;
@ -1192,6 +1211,7 @@ typedef enum
def_Type('FUNC_INTERP', 'Z3_func_interp', 'FuncInterpObj')
def_Type('FUNC_ENTRY', 'Z3_func_entry', 'FuncEntryObj')
def_Type('FIXEDPOINT', 'Z3_fixedpoint', 'FixedpointObj')
def_Type('OPTIMIZE', 'Z3_optimize', 'OptimizeObj')
def_Type('PARAM_DESCRS', 'Z3_param_descrs', 'ParamDescrs')
def_Type('RCF_NUM', 'Z3_rcf_num', 'RCFNumObj')
*/
@ -3734,6 +3754,28 @@ END_MLAPI_EXCLUDE
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor_accessor(
__in Z3_context c, __in Z3_sort t, unsigned idx_c, unsigned idx_a);
/**
\brief Update record field with a value.
This corresponds to the 'with' construct in OCaml.
It has the effect of updating a record field with a given value.
The remaining fields are left unchanged. It is the record
equivalent of an array store (see \sa Z3_mk_store).
If the datatype has more than one constructor, then the update function
behaves as identity if there is a miss-match between the accessor and
constructor. For example ((_ update-field car) nil 1) is nil,
while ((_ update-field car) (cons 2 nil) 1) is (cons 1 nil).
\pre Z3_get_sort_kind(Z3_get_sort(c, t)) == Z3_get_domain(c, field_access, 1) == Z3_DATATYPE_SORT
\pre Z3_get_sort(c, value) == Z3_get_range(c, field_access)
def_API('Z3_datatype_update_field', AST, (_in(CONTEXT), _in(FUNC_DECL), _in(AST), _in(AST)))
*/
Z3_ast Z3_API Z3_datatype_update_field(
__in Z3_context c, __in Z3_func_decl field_access,
__in Z3_ast t, __in Z3_ast value);
/**
\brief Return arity of relation.
@ -3759,6 +3801,29 @@ END_MLAPI_EXCLUDE
Z3_sort Z3_API Z3_get_relation_column(__in Z3_context c, __in Z3_sort s, unsigned col);
/**
\brief Pseudo-Boolean relations.
Encode p1 + p2 + ... + pn <= k
def_API('Z3_mk_atmost', AST, (_in(CONTEXT), _in(UINT), _in_array(1,AST), _in(UINT)))
*/
Z3_ast Z3_API Z3_mk_atmost(__in Z3_context c, __in unsigned num_args,
__in_ecount(num_args) Z3_ast const args[], __in unsigned k);
/**
\brief Pseudo-Boolean relations.
Encode k1*p1 + k2*p2 + ... + kn*pn <= k
def_API('Z3_mk_pble', AST, (_in(CONTEXT), _in(UINT), _in_array(1,AST), _in_array(1,INT), _in(INT)))
*/
Z3_ast Z3_API Z3_mk_pble(__in Z3_context c, __in unsigned num_args,
__in_ecount(num_args) Z3_ast const args[], __in_ecount(num_args) int coeffs[],
__in int k);
/**
\mlonly {3 {L Function Declarations}} \endmlonly
*/
@ -3988,6 +4053,12 @@ END_MLAPI_EXCLUDE
/**
\brief Return a unique identifier for \c t.
The identifier is unique up to structural equality. Thus, two ast nodes
created by the same context and having the same children and same function symbols
have the same identifiers. Ast nodes created in the same context, but having
different children or different functions have different identifiers.
Variables and quantifiers are also assigned different identifiers according to
their structure.
\mlonly \remark Implicitly used by [Pervasives.compare] for values of type [ast], [app], [sort], [func_decl], and [pattern]. \endmlonly
def_API('Z3_get_ast_id', UINT, (_in(CONTEXT), _in(AST)))
@ -3996,6 +4067,8 @@ END_MLAPI_EXCLUDE
/**
\brief Return a hash code for the given AST.
The hash code is structural. You can use Z3_get_ast_id interchangably with
this function.
\mlonly \remark Implicitly used by [Hashtbl.hash] for values of type [ast], [app], [sort], [func_decl], and [pattern]. \endmlonly
def_API('Z3_get_ast_hash', UINT, (_in(CONTEXT), _in(AST)))
@ -5904,6 +5977,197 @@ END_MLAPI_EXCLUDE
#endif
#endif
#ifdef CorML4
/**
@name Optimize facilities
*/
/*@{*/
/**
\brief Create a new optimize context.
\conly \remark User must use #Z3_optimize_inc_ref and #Z3_optimize_dec_ref to manage optimize objects.
\conly Even if the context was created using #Z3_mk_context instead of #Z3_mk_context_rc.
def_API('Z3_mk_optimize', OPTIMIZE, (_in(CONTEXT), ))
*/
Z3_optimize Z3_API Z3_mk_optimize(__in Z3_context c);
#ifdef Conly
/**
\brief Increment the reference counter of the given optimize context
def_API('Z3_optimize_inc_ref', VOID, (_in(CONTEXT), _in(OPTIMIZE)))
*/
void Z3_API Z3_optimize_inc_ref(__in Z3_context c,__in Z3_optimize d);
/**
\brief Decrement the reference counter of the given optimize context.
def_API('Z3_optimize_dec_ref', VOID, (_in(CONTEXT), _in(OPTIMIZE)))
*/
void Z3_API Z3_optimize_dec_ref(__in Z3_context c,__in Z3_optimize d);
#endif
/**
\brief Assert hard constraint to the optimization context.
def_API('Z3_optimize_assert', VOID, (_in(CONTEXT), _in(OPTIMIZE), _in(AST)))
*/
void Z3_API Z3_optimize_assert(Z3_context c, Z3_optimize o, Z3_ast a);
/**
\brief Assert soft constraint to the optimization context.
\param c - context
\param o - optimization context
\param a - formula
\param weight - a positive weight, penalty for violating soft constraint
\param id - optional identifier to group soft constraints
def_API('Z3_optimize_assert_soft', UINT, (_in(CONTEXT), _in(OPTIMIZE), _in(AST), _in(STRING), _in(SYMBOL)))
*/
unsigned Z3_API Z3_optimize_assert_soft(Z3_context c, Z3_optimize o, Z3_ast a, Z3_string weight, Z3_symbol id);
/**
\brief Add a maximization constraint.
\param c - context
\param o - optimization context
\param a - arithmetical term
def_API('Z3_optimize_maximize', UINT, (_in(CONTEXT), _in(OPTIMIZE), _in(AST)))
*/
unsigned Z3_API Z3_optimize_maximize(Z3_context c, Z3_optimize o, Z3_ast t);
/**
\brief Add a minimization constraint.
\param c - context
\param o - optimization context
\param a - arithmetical term
def_API('Z3_optimize_minimize', UINT, (_in(CONTEXT), _in(OPTIMIZE), _in(AST)))
*/
unsigned Z3_API Z3_optimize_minimize(Z3_context c, Z3_optimize o, Z3_ast t);
/**
\brief Create a backtracking point.
The optimize solver contains a set of rules, added facts and assertions.
The set of rules, facts and assertions are restored upon calling #Z3_optimize_pop.
\sa Z3_optimize_pop
def_API('Z3_optimize_push', VOID, (_in(CONTEXT), _in(OPTIMIZE)))
*/
void Z3_API Z3_optimize_push(Z3_context c,Z3_optimize d);
/**
\brief Backtrack one level.
\sa Z3_optimize_push
\pre The number of calls to pop cannot exceed calls to push.
def_API('Z3_optimize_pop', VOID, (_in(CONTEXT), _in(OPTIMIZE)))
*/
void Z3_API Z3_optimize_pop(Z3_context c,Z3_optimize d);
/**
\brief Check consistency and produce optimal values.
\param c - context
\param o - optimization context
def_API('Z3_optimize_check', INT, (_in(CONTEXT), _in(OPTIMIZE)))
*/
Z3_lbool Z3_API Z3_optimize_check(Z3_context c, Z3_optimize o);
/**
\brief Retrieve the model for the last #Z3_optimize_check
The error handler is invoked if a model is not available because
the commands above were not invoked for the given optimization
solver, or if the result was \c Z3_L_FALSE.
def_API('Z3_optimize_get_model', MODEL, (_in(CONTEXT), _in(OPTIMIZE)))
*/
Z3_model Z3_API Z3_optimize_get_model(Z3_context c, Z3_optimize o);
/**
\brief Set parameters on optimization context.
\param c - context
\param o - optimization context
\param p - parameters
def_API('Z3_optimize_set_params', VOID, (_in(CONTEXT), _in(OPTIMIZE), _in(PARAMS)))
*/
void Z3_API Z3_optimize_set_params(Z3_context c, Z3_optimize o, Z3_params p);
/**
\brief Return the parameter description set for the given optimize object.
\param c - context
\param o - optimization context
def_API('Z3_optimize_get_param_descrs', PARAM_DESCRS, (_in(CONTEXT), _in(OPTIMIZE)))
*/
Z3_param_descrs Z3_API Z3_optimize_get_param_descrs(Z3_context c, Z3_optimize o);
/**
\brief Retrieve lower bound value or approximation for the i'th optimization objective.
\param c - context
\param o - optimization context
\param idx - index of optimization objective
def_API('Z3_optimize_get_lower', AST, (_in(CONTEXT), _in(OPTIMIZE), _in(UINT)))
*/
Z3_ast Z3_API Z3_optimize_get_lower(Z3_context c, Z3_optimize o, unsigned idx);
/**
\brief Retrieve upper bound value or approximation for the i'th optimization objective.
\param c - context
\param o - optimization context
\param idx - index of optimization objective
def_API('Z3_optimize_get_upper', AST, (_in(CONTEXT), _in(OPTIMIZE), _in(UINT)))
*/
Z3_ast Z3_API Z3_optimize_get_upper(Z3_context c, Z3_optimize o, unsigned idx);
/**
\brief Print the current context as a string.
\param c - context.
\param o - optimization context.
def_API('Z3_optimize_to_string', STRING, (_in(CONTEXT), _in(OPTIMIZE)))
*/
Z3_string Z3_API Z3_optimize_to_string(
__in Z3_context c,
__in Z3_optimize o);
/**
\brief Return a string containing a description of parameters accepted by optimize.
def_API('Z3_optimize_get_help', STRING, (_in(CONTEXT), _in(OPTIMIZE)))
*/
Z3_string Z3_API Z3_optimize_get_help(__in Z3_context c, __in Z3_optimize t);
/**
\brief Retrieve statistics information from the last call to #Z3_optimize_check
def_API('Z3_optimize_get_statistics', STATS, (_in(CONTEXT), _in(OPTIMIZE)))
*/
Z3_stats Z3_API Z3_optimize_get_statistics(__in Z3_context c,__in Z3_optimize d);
#endif
#ifdef CorML4
/*@}*/

View file

@ -22,12 +22,14 @@ Notes:
#include"stream_buffer.h"
#include"symbol.h"
#include"trace.h"
#include<sstream>
void register_z3_replayer_cmds(z3_replayer & in);
void throw_invalid_reference() {
TRACE("z3_replayer", tout << "invalid argument reference\n";);
throw z3_replayer_exception("invalid argument reference");
throw z3_replayer_exception("invalid argument reference1");
}
struct z3_replayer::imp {
@ -44,7 +46,37 @@ struct z3_replayer::imp {
size_t_map<void *> m_heap;
svector<z3_replayer_cmd> 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, INT_ARRAY, SYMBOL_ARRAY, OBJECT_ARRAY };
char const* kind2string(value_kind k) const {
switch (k) {
case INT64: return "int64";
case UINT64: return "uint64";
case DOUBLE: return "double";
case STRING: return "string";
case SYMBOL: return "symbol";
case OBJECT: return "object";
case UINT_ARRAY: return "uint_array";
case INT_ARRAY: return "int_array";
case SYMBOL_ARRAY: return "symbol_array";
case OBJECT_ARRAY: return "object_array";
default: UNREACHABLE(); return "unknown";
}
}
void check_arg(unsigned pos, value_kind k) const {
if (pos >= m_args.size()) {
TRACE("z3_replayer", tout << "too few arguments " << m_args.size() << " expecting " << kind2string(k) << "\n";);
throw z3_replayer_exception("invalid argument reference2");
}
if (m_args[pos].m_kind != k) {
std::stringstream strm;
strm << "expecting " << kind2string(k) << " at position "
<< pos << " but got " << kind2string(m_args[pos].m_kind);
throw z3_replayer_exception(strm.str().c_str());
}
}
struct value {
value_kind m_kind;
@ -68,6 +100,7 @@ struct z3_replayer::imp {
vector<ptr_vector<void> > m_obj_arrays;
vector<svector<Z3_symbol> > m_sym_arrays;
vector<unsigned_vector> m_unsigned_arrays;
vector<svector<int> > m_int_arrays;
imp(z3_replayer & o, std::istream & in):
m_owner(o),
@ -295,6 +328,15 @@ struct z3_replayer::imp {
v.push_back(static_cast<unsigned>(m_args[i].m_uint));
}
}
if (k == INT64) {
aidx = m_int_arrays.size();
nk = INT_ARRAY;
m_int_arrays.push_back(svector<int>());
svector<int> & v = m_int_arrays.back();
for (unsigned i = asz - sz; i < asz; i++) {
v.push_back(static_cast<int>(m_args[i].m_int));
}
}
else if (k == SYMBOL) {
aidx = m_sym_arrays.size();
nk = SYMBOL_ARRAY;
@ -457,8 +499,7 @@ struct z3_replayer::imp {
next(); skip_blank(); read_ptr(); skip_blank(); read_uint64();
unsigned pos = static_cast<unsigned>(m_uint64);
TRACE("z3_replayer", tout << "[" << m_line << "] " << "* " << m_ptr << " " << pos << "\n";);
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT)
throw_invalid_reference();
check_arg(pos, OBJECT);
m_heap.insert(m_ptr, m_args[pos].m_obj);
break;
}
@ -467,8 +508,7 @@ struct z3_replayer::imp {
// @ obj_id array_pos idx
next(); skip_blank(); read_ptr(); skip_blank(); read_uint64();
unsigned pos = static_cast<unsigned>(m_uint64);
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT_ARRAY)
throw_invalid_reference();
check_arg(pos, OBJECT_ARRAY);
unsigned aidx = static_cast<unsigned>(m_args[pos].m_uint);
ptr_vector<void> & v = m_obj_arrays[aidx];
skip_blank(); read_uint64();
@ -493,70 +533,65 @@ struct z3_replayer::imp {
}
int get_int(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
throw_invalid_reference();
check_arg(pos, INT64);
return static_cast<int>(m_args[pos].m_int);
}
__int64 get_int64(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
throw_invalid_reference();
check_arg(pos, INT64);
return m_args[pos].m_int;
}
unsigned get_uint(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
throw_invalid_reference();
check_arg(pos, UINT64);
return static_cast<unsigned>(m_args[pos].m_uint);
}
__uint64 get_uint64(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
throw_invalid_reference();
check_arg(pos, UINT64);
return m_args[pos].m_uint;
}
double get_double(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != DOUBLE)
throw_invalid_reference();
check_arg(pos, DOUBLE);
return m_args[pos].m_double;
}
Z3_string get_str(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != STRING)
throw_invalid_reference();
check_arg(pos, STRING);
return m_args[pos].m_str;
}
Z3_symbol get_symbol(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != SYMBOL)
throw_invalid_reference();
check_arg(pos, SYMBOL);
return reinterpret_cast<Z3_symbol>(const_cast<char*>(m_args[pos].m_str));
}
void * get_obj(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT)
throw_invalid_reference();
check_arg(pos, OBJECT);
return m_args[pos].m_obj;
}
unsigned * get_uint_array(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != UINT_ARRAY)
throw_invalid_reference();
check_arg(pos, UINT_ARRAY);
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
return m_unsigned_arrays[idx].c_ptr();
}
int * get_int_array(unsigned pos) const {
check_arg(pos, INT_ARRAY);
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
return m_int_arrays[idx].c_ptr();
}
Z3_symbol * get_symbol_array(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != SYMBOL_ARRAY)
throw_invalid_reference();
check_arg(pos, SYMBOL_ARRAY);
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
return m_sym_arrays[idx].c_ptr();
}
void ** get_obj_array(unsigned pos) const {
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT_ARRAY)
throw_invalid_reference();
check_arg(pos, OBJECT_ARRAY);
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
ptr_vector<void> const & v = m_obj_arrays[idx];
TRACE("z3_replayer_bug", tout << "pos: " << pos << ", idx: " << idx << " size(): " << v.size() << "\n";
@ -565,38 +600,32 @@ struct z3_replayer::imp {
}
int * get_int_addr(unsigned pos) {
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
throw_invalid_reference();
check_arg(pos, INT64);
return reinterpret_cast<int*>(&(m_args[pos].m_int));
}
__int64 * get_int64_addr(unsigned pos) {
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
throw_invalid_reference();
check_arg(pos, INT64);
return &(m_args[pos].m_int);
}
unsigned * get_uint_addr(unsigned pos) {
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
throw_invalid_reference();
check_arg(pos, UINT64);
return reinterpret_cast<unsigned*>(&(m_args[pos].m_uint));
}
__uint64 * get_uint64_addr(unsigned pos) {
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
throw_invalid_reference();
check_arg(pos, UINT64);
return &(m_args[pos].m_uint);
}
Z3_string * get_str_addr(unsigned pos) {
if (pos >= m_args.size() || m_args[pos].m_kind != STRING)
throw_invalid_reference();
check_arg(pos, STRING);
return &(m_args[pos].m_str);
}
void ** get_obj_addr(unsigned pos) {
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT)
throw_invalid_reference();
check_arg(pos, OBJECT);
return &(m_args[pos].m_obj);
}
@ -615,6 +644,7 @@ struct z3_replayer::imp {
m_obj_arrays.reset();
m_sym_arrays.reset();
m_unsigned_arrays.reset();
m_int_arrays.reset();
}
@ -673,6 +703,10 @@ unsigned * z3_replayer::get_uint_array(unsigned pos) const {
return m_imp->get_uint_array(pos);
}
int * z3_replayer::get_int_array(unsigned pos) const {
return m_imp->get_int_array(pos);
}
Z3_symbol * z3_replayer::get_symbol_array(unsigned pos) const {
return m_imp->get_symbol_array(pos);
}

View file

@ -49,6 +49,7 @@ public:
void * get_obj(unsigned pos) const;
unsigned * get_uint_array(unsigned pos) const;
int * get_int_array(unsigned pos) const;
Z3_symbol * get_symbol_array(unsigned pos) const;
void ** get_obj_array(unsigned pos) const;