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

Merge branch 'master' of https://github.com/Z3Prover/z3 into jan4

This commit is contained in:
Christoph M. Wintersteiger 2016-01-05 11:34:35 +00:00
commit 8b47a84598
56 changed files with 5500 additions and 887 deletions

View file

@ -641,6 +641,12 @@ extern "C" {
else if (fid == mk_c(c)->get_fpa_fid() && k == ROUNDING_MODE_SORT) {
return Z3_ROUNDING_MODE_SORT;
}
else if (fid == mk_c(c)->get_seq_fid() && k == SEQ_SORT) {
return Z3_SEQ_SORT;
}
else if (fid == mk_c(c)->get_seq_fid() && k == RE_SORT) {
return Z3_RE_SORT;
}
else {
return Z3_UNKNOWN_SORT;
}
@ -776,6 +782,8 @@ extern "C" {
SET_ERROR_CODE(Z3_SORT_ERROR);
RETURN_Z3(of_expr(0));
}
SASSERT(from[i]->get_ref_count() > 0);
SASSERT(to[i]->get_ref_count() > 0);
}
expr_safe_replace subst(m);
for (unsigned i = 0; i < num_exprs; i++) {
@ -1106,6 +1114,32 @@ extern "C" {
}
}
if (mk_c(c)->get_seq_fid() == _d->get_family_id()) {
switch (_d->get_decl_kind()) {
case Z3_OP_SEQ_UNIT: return Z3_OP_SEQ_UNIT;
case Z3_OP_SEQ_EMPTY: return Z3_OP_SEQ_EMPTY;
case Z3_OP_SEQ_CONCAT: return Z3_OP_SEQ_CONCAT;
case Z3_OP_SEQ_PREFIX: return Z3_OP_SEQ_PREFIX;
case Z3_OP_SEQ_SUFFIX: return Z3_OP_SEQ_SUFFIX;
case Z3_OP_SEQ_CONTAINS: return Z3_OP_SEQ_CONTAINS;
case Z3_OP_SEQ_EXTRACT: return Z3_OP_SEQ_EXTRACT;
case Z3_OP_SEQ_REPLACE: return Z3_OP_SEQ_REPLACE;
case Z3_OP_SEQ_AT: return Z3_OP_SEQ_AT;
case Z3_OP_SEQ_LENGTH: return Z3_OP_SEQ_LENGTH;
case Z3_OP_SEQ_INDEX: return Z3_OP_SEQ_INDEX;
case Z3_OP_SEQ_TO_RE: return Z3_OP_SEQ_TO_RE;
case Z3_OP_SEQ_IN_RE: return Z3_OP_SEQ_IN_RE;
case Z3_OP_RE_PLUS: return Z3_OP_RE_PLUS;
case Z3_OP_RE_STAR: return Z3_OP_RE_STAR;
case Z3_OP_RE_OPTION: return Z3_OP_RE_OPTION;
case Z3_OP_RE_CONCAT: return Z3_OP_RE_CONCAT;
case Z3_OP_RE_UNION: return Z3_OP_RE_UNION;
default:
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;

View file

@ -73,6 +73,7 @@ namespace api {
m_datalog_util(m()),
m_fpa_util(m()),
m_dtutil(m()),
m_sutil(m()),
m_last_result(m()),
m_ast_trail(m()),
m_replay_stack(),
@ -97,6 +98,7 @@ namespace api {
m_dt_fid = m().mk_family_id("datatype");
m_datalog_fid = m().mk_family_id("datalog_relation");
m_fpa_fid = m().mk_family_id("fpa");
m_seq_fid = m().mk_family_id("seq");
m_dt_plugin = static_cast<datatype_decl_plugin*>(m().get_plugin(m_dt_fid));
if (!m_user_ref_count) {

View file

@ -25,6 +25,7 @@ Revision History:
#include"api_util.h"
#include"arith_decl_plugin.h"
#include"bv_decl_plugin.h"
#include"seq_decl_plugin.h"
#include"datatype_decl_plugin.h"
#include"dl_decl_plugin.h"
#include"fpa_decl_plugin.h"
@ -58,6 +59,7 @@ namespace api {
datalog::dl_decl_util m_datalog_util;
fpa_util m_fpa_util;
datatype_util m_dtutil;
seq_util m_sutil;
// Support for old solver API
smt_params m_fparams;
@ -78,6 +80,7 @@ namespace api {
family_id m_datalog_fid;
family_id m_pb_fid;
family_id m_fpa_fid;
family_id m_seq_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 +124,7 @@ namespace api {
datalog::dl_decl_util & datalog_util() { return m_datalog_util; }
fpa_util & fpautil() { return m_fpa_util; }
datatype_util& dtutil() { return m_dtutil; }
seq_util& sutil() { return m_sutil; }
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; }
@ -129,6 +133,7 @@ namespace api {
family_id get_datalog_fid() const { return m_datalog_fid; }
family_id get_pb_fid() const { return m_pb_fid; }
family_id get_fpa_fid() const { return m_fpa_fid; }
family_id get_seq_fid() const { return m_seq_fid; }
datatype_decl_plugin * get_dt_plugin() const { return m_dt_plugin; }
Z3_error_code get_error_code() const { return m_error_code; }

151
src/api/api_seq.cpp Normal file
View file

@ -0,0 +1,151 @@
/*++
Copyright (c) 2016 Microsoft Corporation
Module Name:
api_seq.cpp
Abstract:
API for sequences and regular expressions.
Author:
Nikolaj Bjorner (nbjorner) 2016-01-02.
Revision History:
--*/
#include<iostream>
#include"z3.h"
#include"api_log_macros.h"
#include"api_context.h"
#include"api_util.h"
#include"ast_pp.h"
extern "C" {
Z3_sort Z3_API Z3_mk_seq_sort(Z3_context c, Z3_sort domain) {
Z3_TRY;
LOG_Z3_mk_seq_sort(c, domain);
RESET_ERROR_CODE();
sort * ty = mk_c(c)->sutil().str.mk_seq(to_sort(domain));
mk_c(c)->save_ast_trail(ty);
RETURN_Z3(of_sort(ty));
Z3_CATCH_RETURN(0);
}
Z3_sort Z3_API Z3_mk_re_sort(Z3_context c, Z3_sort domain) {
Z3_TRY;
LOG_Z3_mk_re_sort(c, domain);
RESET_ERROR_CODE();
sort * ty = mk_c(c)->sutil().re.mk_re(to_sort(domain));
mk_c(c)->save_ast_trail(ty);
RETURN_Z3(of_sort(ty));
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_API Z3_mk_string(Z3_context c, Z3_string str) {
Z3_TRY;
LOG_Z3_mk_string(c, str);
RESET_ERROR_CODE();
zstring s(str, zstring::ascii);
app* a = mk_c(c)->sutil().str.mk_string(s);
mk_c(c)->save_ast_trail(a);
RETURN_Z3(of_ast(a));
Z3_CATCH_RETURN(0);
}
Z3_sort Z3_API Z3_mk_string_sort(Z3_context c) {
Z3_TRY;
LOG_Z3_mk_string_sort(c);
RESET_ERROR_CODE();
sort* ty = mk_c(c)->sutil().str.mk_string_sort();
mk_c(c)->save_ast_trail(ty);
RETURN_Z3(of_sort(ty));
Z3_CATCH_RETURN(0);
}
Z3_bool Z3_API Z3_is_seq_sort(Z3_context c, Z3_sort s) {
Z3_TRY;
LOG_Z3_is_seq_sort(c, s);
RESET_ERROR_CODE();
bool result = mk_c(c)->sutil().is_seq(to_sort(s));
return result?Z3_TRUE:Z3_FALSE;
Z3_CATCH_RETURN(Z3_FALSE);
}
Z3_bool Z3_API Z3_is_re_sort(Z3_context c, Z3_sort s) {
Z3_TRY;
LOG_Z3_is_re_sort(c, s);
RESET_ERROR_CODE();
bool result = mk_c(c)->sutil().is_re(to_sort(s));
return result?Z3_TRUE:Z3_FALSE;
Z3_CATCH_RETURN(Z3_FALSE);
}
Z3_bool Z3_API Z3_is_string_sort(Z3_context c, Z3_sort s) {
Z3_TRY;
LOG_Z3_is_string_sort(c, s);
RESET_ERROR_CODE();
bool result = mk_c(c)->sutil().is_string(to_sort(s));
return result?Z3_TRUE:Z3_FALSE;
Z3_CATCH_RETURN(Z3_FALSE);
}
Z3_bool Z3_API Z3_is_string(Z3_context c, Z3_ast s) {
Z3_TRY;
LOG_Z3_is_string(c, s);
RESET_ERROR_CODE();
bool result = mk_c(c)->sutil().str.is_string(to_expr(s));
return result?Z3_TRUE:Z3_FALSE;
Z3_CATCH_RETURN(Z3_FALSE);
}
Z3_string Z3_API Z3_get_string(Z3_context c, Z3_ast s) {
Z3_TRY;
LOG_Z3_get_string(c, s);
RESET_ERROR_CODE();
zstring str;
if (!mk_c(c)->sutil().str.is_string(to_expr(s), str)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
return "";
}
std::string result = str.encode();
return mk_c(c)->mk_external_string(result);
Z3_CATCH_RETURN("");
}
Z3_ast Z3_API Z3_mk_seq_empty(Z3_context c, Z3_sort seq) {
Z3_TRY;
LOG_Z3_mk_seq_empty(c, seq);
RESET_ERROR_CODE();
app* a = mk_c(c)->sutil().str.mk_empty(to_sort(seq));
mk_c(c)->save_ast_trail(a);
RETURN_Z3(of_ast(a));
Z3_CATCH_RETURN(0);
}
MK_UNARY(Z3_mk_seq_unit, mk_c(c)->get_seq_fid(), OP_SEQ_UNIT, SKIP);
MK_NARY(Z3_mk_seq_concat, mk_c(c)->get_seq_fid(), OP_SEQ_CONCAT, SKIP);
MK_BINARY(Z3_mk_seq_prefix, mk_c(c)->get_seq_fid(), OP_SEQ_PREFIX, SKIP);
MK_BINARY(Z3_mk_seq_suffix, mk_c(c)->get_seq_fid(), OP_SEQ_SUFFIX, SKIP);
MK_BINARY(Z3_mk_seq_contains, mk_c(c)->get_seq_fid(), OP_SEQ_CONTAINS, SKIP);
MK_TERNARY(Z3_mk_seq_extract, mk_c(c)->get_seq_fid(), OP_SEQ_EXTRACT, SKIP);
MK_TERNARY(Z3_mk_seq_replace, mk_c(c)->get_seq_fid(), OP_SEQ_REPLACE, SKIP);
MK_BINARY(Z3_mk_seq_at, mk_c(c)->get_seq_fid(), OP_SEQ_AT, SKIP);
MK_UNARY(Z3_mk_seq_length, mk_c(c)->get_seq_fid(), OP_SEQ_LENGTH, SKIP);
MK_TERNARY(Z3_mk_seq_index, mk_c(c)->get_seq_fid(), OP_SEQ_INDEX, SKIP);
MK_UNARY(Z3_mk_seq_to_re, mk_c(c)->get_seq_fid(), OP_SEQ_TO_RE, SKIP);
MK_BINARY(Z3_mk_seq_in_re, mk_c(c)->get_seq_fid(), OP_SEQ_IN_RE, SKIP);
MK_UNARY(Z3_mk_re_plus, mk_c(c)->get_seq_fid(), OP_RE_PLUS, SKIP);
MK_UNARY(Z3_mk_re_star, mk_c(c)->get_seq_fid(), OP_RE_STAR, SKIP);
MK_UNARY(Z3_mk_re_option, mk_c(c)->get_seq_fid(), OP_RE_OPTION, SKIP);
MK_NARY(Z3_mk_re_union, mk_c(c)->get_seq_fid(), OP_RE_UNION, SKIP);
MK_NARY(Z3_mk_re_concat, mk_c(c)->get_seq_fid(), OP_RE_CONCAT, SKIP);
};

View file

@ -135,6 +135,23 @@ Z3_ast Z3_API NAME(Z3_context c, Z3_ast n1, Z3_ast n2) { \
MK_BINARY_BODY(NAME, FID, OP, EXTRA_CODE); \
}
#define MK_TERNARY_BODY(NAME, FID, OP, EXTRA_CODE) \
Z3_TRY; \
RESET_ERROR_CODE(); \
EXTRA_CODE; \
expr * args[3] = { to_expr(n1), to_expr(n2), to_expr(n3) }; \
ast* a = mk_c(c)->m().mk_app(FID, OP, 0, 0, 3, args); \
mk_c(c)->save_ast_trail(a); \
check_sorts(c, a); \
RETURN_Z3(of_ast(a)); \
Z3_CATCH_RETURN(0);
#define MK_TERNARY(NAME, FID, OP, EXTRA_CODE) \
Z3_ast Z3_API NAME(Z3_context c, Z3_ast n1, Z3_ast n2, Z3_ast n3) { \
LOG_ ## NAME(c, n1, n2, n3); \
MK_TERNARY_BODY(NAME, FID, OP, EXTRA_CODE); \
}
#define MK_NARY(NAME, FID, OP, EXTRA_CODE) \
Z3_ast Z3_API NAME(Z3_context c, unsigned num_args, Z3_ast const* args) { \
Z3_TRY; \

View file

@ -205,6 +205,18 @@ namespace z3 {
\brief Return the Bit-vector sort of size \c sz. That is, the sort for bit-vectors of size \c sz.
*/
sort bv_sort(unsigned sz);
/**
\brief Return the sort for ASCII strings.
*/
sort string_sort();
/**
\brief Return a sequence sort over base sort \c s.
*/
sort seq_sort(sort& s);
/**
\brief Return a regular expression sort over sequences \c seq_sort.
*/
sort re_sort(sort& seq_sort);
/**
\brief Return an array sort for arrays from \c d to \c r.
@ -261,6 +273,9 @@ namespace z3 {
expr bv_val(__uint64 n, unsigned sz);
expr bv_val(char const * n, unsigned sz);
expr string_val(char const* s);
expr string_val(std::string const& s);
expr num_val(int n, sort const & s);
/**
@ -425,6 +440,14 @@ namespace z3 {
\brief Return true if this sort is a Relation sort.
*/
bool is_relation() const { return sort_kind() == Z3_RELATION_SORT; }
/**
\brief Return true if this sort is a Sequence sort.
*/
bool is_seq() const { return sort_kind() == Z3_SEQ_SORT; }
/**
\brief Return true if this sort is a regular expression sort.
*/
bool is_re() const { return sort_kind() == Z3_RE_SORT; }
/**
\brief Return true if this sort is a Finite domain sort.
*/
@ -532,6 +555,15 @@ namespace z3 {
\brief Return true if this is a Relation expression.
*/
bool is_relation() const { return get_sort().is_relation(); }
/**
\brief Return true if this is a sequence expression.
*/
bool is_seq() const { return get_sort().is_seq(); }
/**
\brief Return true if this is a regular expression.
*/
bool is_re() const { return get_sort().is_re(); }
/**
\brief Return true if this is a Finite-domain expression.
@ -663,6 +695,7 @@ namespace z3 {
friend expr distinct(expr_vector const& args);
friend expr concat(expr const& a, expr const& b);
friend expr concat(expr_vector const& args);
friend expr operator==(expr const & a, expr const & b);
friend expr operator==(expr const & a, int b);
@ -728,10 +761,50 @@ namespace z3 {
friend expr operator|(int a, expr const & b);
friend expr operator~(expr const & a);
expr extract(unsigned hi, unsigned lo) const { Z3_ast r = Z3_mk_extract(ctx(), hi, lo, *this); return expr(ctx(), r); }
expr extract(unsigned hi, unsigned lo) const { Z3_ast r = Z3_mk_extract(ctx(), hi, lo, *this); ctx().check_error(); return expr(ctx(), r); }
unsigned lo() const { assert (is_app() && Z3_get_decl_num_parameters(ctx(), decl()) == 2); return static_cast<unsigned>(Z3_get_decl_int_parameter(ctx(), decl(), 1)); }
unsigned hi() const { assert (is_app() && Z3_get_decl_num_parameters(ctx(), decl()) == 2); return static_cast<unsigned>(Z3_get_decl_int_parameter(ctx(), decl(), 0)); }
/**
\brief sequence and regular expression operations.
+ is overloaeded as sequence concatenation and regular expression union.
concat is overloaded to handle sequences and regular expressions
*/
expr extract(expr const& offset, expr const& length) const {
check_context(*this, offset); check_context(offset, length);
Z3_ast r = Z3_mk_seq_extract(ctx(), *this, offset, length); check_error(); return expr(ctx(), r);
}
expr replace(expr const& src, expr const& dst) const {
check_context(*this, src); check_context(src, dst);
Z3_ast r = Z3_mk_seq_replace(ctx(), *this, src, dst);
check_error();
return expr(ctx(), r);
}
expr unit() const {
Z3_ast r = Z3_mk_seq_unit(ctx(), *this);
check_error();
return expr(ctx(), r);
}
expr contains(expr const& s) {
check_context(*this, s);
Z3_ast r = Z3_mk_seq_contains(ctx(), *this, s);
check_error();
return expr(ctx(), r);
}
expr at(expr const& index) const {
check_context(*this, index);
Z3_ast r = Z3_mk_seq_at(ctx(), *this, index);
check_error();
return expr(ctx(), r);
}
expr length() const {
Z3_ast r = Z3_mk_seq_length(ctx(), *this);
check_error();
return expr(ctx(), r);
}
/**
\brief Return a simplified version of this expression.
*/
@ -835,6 +908,13 @@ namespace z3 {
else if (a.is_bv() && b.is_bv()) {
r = Z3_mk_bvadd(a.ctx(), a, b);
}
else if (a.is_seq() && b.is_seq()) {
return concat(a, b);
}
else if (a.is_re() && b.is_re()) {
Z3_ast _args[2] = { a, b };
r = Z3_mk_re_union(a.ctx(), 2, _args);
}
else {
// operator is not supported by given arguments.
assert(false);
@ -1219,11 +1299,48 @@ namespace z3 {
inline expr concat(expr const& a, expr const& b) {
check_context(a, b);
Z3_ast r = Z3_mk_concat(a.ctx(), a, b);
Z3_ast r;
if (Z3_is_seq_sort(a.ctx(), a.get_sort())) {
Z3_ast _args[2] = { a, b };
r = Z3_mk_seq_concat(a.ctx(), 2, _args);
}
else if (Z3_is_re_sort(a.ctx(), a.get_sort())) {
Z3_ast _args[2] = { a, b };
r = Z3_mk_re_concat(a.ctx(), 2, _args);
}
else {
r = Z3_mk_concat(a.ctx(), a, b);
}
a.ctx().check_error();
return expr(a.ctx(), r);
}
inline expr concat(expr_vector const& args) {
Z3_ast r;
assert(args.size() > 0);
if (args.size() == 1) {
return args[0];
}
context& ctx = args[0].ctx();
array<Z3_ast> _args(args);
if (Z3_is_seq_sort(ctx, args[0].get_sort())) {
r = Z3_mk_seq_concat(ctx, _args.size(), _args.ptr());
}
else if (Z3_is_re_sort(ctx, args[0].get_sort())) {
r = Z3_mk_re_concat(ctx, _args.size(), _args.ptr());
}
else {
r = _args[args.size()-1];
for (unsigned i = args.size()-1; i > 0; ) {
--i;
r = Z3_mk_concat(ctx, _args[i], r);
ctx.check_error();
}
}
ctx.check_error();
return expr(ctx, r);
}
class func_entry : public object {
Z3_func_entry m_entry;
void init(Z3_func_entry e) {
@ -1762,6 +1879,10 @@ namespace z3 {
inline sort context::int_sort() { Z3_sort s = Z3_mk_int_sort(m_ctx); check_error(); return sort(*this, s); }
inline sort context::real_sort() { Z3_sort s = Z3_mk_real_sort(m_ctx); check_error(); return sort(*this, s); }
inline sort context::bv_sort(unsigned sz) { Z3_sort s = Z3_mk_bv_sort(m_ctx, sz); check_error(); return sort(*this, s); }
inline sort context::string_sort() { Z3_sort s = Z3_mk_string_sort(m_ctx); check_error(); return sort(*this, s); }
inline sort context::seq_sort(sort& s) { Z3_sort r = Z3_mk_seq_sort(m_ctx, s); check_error(); return sort(*this, r); }
inline sort context::re_sort(sort& s) { Z3_sort r = Z3_mk_re_sort(m_ctx, s); check_error(); return sort(*this, r); }
inline sort context::array_sort(sort d, sort r) { Z3_sort s = Z3_mk_array_sort(m_ctx, d, r); check_error(); return sort(*this, s); }
inline sort context::enumeration_sort(char const * name, unsigned n, char const * const * enum_names, func_decl_vector & cs, func_decl_vector & ts) {
array<Z3_symbol> _enum_names(n);
@ -1885,6 +2006,9 @@ namespace z3 {
inline expr context::bv_val(__uint64 n, unsigned sz) { Z3_ast r = Z3_mk_unsigned_int64(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); }
inline expr context::bv_val(char const * n, unsigned sz) { Z3_ast r = Z3_mk_numeral(m_ctx, n, bv_sort(sz)); check_error(); return expr(*this, r); }
inline expr context::string_val(char const* s) { Z3_ast r = Z3_mk_string(m_ctx, s); check_error(); return expr(*this, r); }
inline expr context::string_val(std::string const& s) { Z3_ast r = Z3_mk_string(m_ctx, s.c_str()); check_error(); return expr(*this, r); }
inline expr context::num_val(int n, sort const & s) { Z3_ast r = Z3_mk_int(m_ctx, n, s); check_error(); return expr(*this, r); }
inline expr func_decl::operator()(unsigned n, expr const * args) const {
@ -2017,6 +2141,62 @@ namespace z3 {
d.check_error();
return expr(d.ctx(), r);
}
// sequence and regular expression operations.
// union is +
// concat is overloaded to handle sequences and regular expressions
inline expr empty(sort const& s) {
Z3_ast r = Z3_mk_seq_empty(s.ctx(), s);
s.check_error();
return expr(s.ctx(), r);
}
inline expr suffixof(expr const& a, expr const& b) {
check_context(a, b);
Z3_ast r = Z3_mk_seq_suffix(a.ctx(), a, b);
a.check_error();
return expr(a.ctx(), r);
}
inline expr prefixof(expr const& a, expr const& b) {
check_context(a, b);
Z3_ast r = Z3_mk_seq_prefix(a.ctx(), a, b);
a.check_error();
return expr(a.ctx(), r);
}
inline expr indexof(expr const& s, expr const& substr, expr const& offset) {
check_context(s, substr); check_context(s, offset);
Z3_ast r = Z3_mk_seq_index(s.ctx(), s, substr, offset);
s.check_error();
return expr(s.ctx(), r);
}
inline expr to_re(expr const& s) {
Z3_ast r = Z3_mk_seq_to_re(s.ctx(), s);
s.check_error();
return expr(s.ctx(), r);
}
inline expr in_re(expr const& s, expr const& re) {
check_context(s, re);
Z3_ast r = Z3_mk_seq_in_re(s.ctx(), s, re);
s.check_error();
return expr(s.ctx(), r);
}
inline expr plus(expr const& re) {
Z3_ast r = Z3_mk_re_plus(re.ctx(), re);
re.check_error();
return expr(re.ctx(), r);
}
inline expr option(expr const& re) {
Z3_ast r = Z3_mk_re_option(re.ctx(), re);
re.check_error();
return expr(re.ctx(), r);
}
inline expr star(expr const& re) {
Z3_ast r = Z3_mk_re_star(re.ctx(), re);
re.check_error();
return expr(re.ctx(), r);
}
inline expr interpolant(expr const& a) {
return expr(a.ctx(), Z3_mk_interpolant(a.ctx(), a));
}

View file

@ -125,6 +125,7 @@ namespace Microsoft.Z3
private BoolSort m_boolSort = null;
private IntSort m_intSort = null;
private RealSort m_realSort = null;
private SeqSort m_stringSort = null;
/// <summary>
/// Retrieves the Boolean sort of the context.
@ -163,6 +164,20 @@ namespace Microsoft.Z3
}
}
/// <summary>
/// Retrieves the String sort of the context.
/// </summary>
public SeqSort StringSort
{
get
{
Contract.Ensures(Contract.Result<SeqSort>() != null);
if (m_stringSort == null) m_stringSort = new SeqSort(this, Native.Z3_mk_string_sort(nCtx));
return m_stringSort;
}
}
/// <summary>
/// Create a new Boolean sort.
/// </summary>
@ -223,6 +238,27 @@ namespace Microsoft.Z3
return new BitVecSort(this, Native.Z3_mk_bv_sort(nCtx, size));
}
/// <summary>
/// Create a new sequence sort.
/// </summary>
public SeqSort MkSeqSort(Sort s)
{
Contract.Requires(s != null);
Contract.Ensures(Contract.Result<SeqSort>() != null);
return new SeqSort(this, Native.Z3_mk_seq_sort(nCtx, s.NativeObject));
}
/// <summary>
/// Create a new regular expression sort.
/// </summary>
public ReSort MkReSort(SeqSort s)
{
Contract.Requires(s != null);
Contract.Ensures(Contract.Result<ReSort>() != null);
return new ReSort(this, Native.Z3_mk_re_sort(nCtx, s.NativeObject));
}
/// <summary>
/// Create a new array sort.
/// </summary>
@ -2286,6 +2322,230 @@ namespace Microsoft.Z3
#endregion
#region Sequence, string and regular expresions
/// <summary>
/// Create the empty sequence.
/// </summary>
public SeqExpr MkEmptySeq(Sort s)
{
Contract.Requires(s != null);
Contract.Ensures(Contract.Result<SeqExpr>() != null);
return new SeqExpr(this, Native.Z3_mk_seq_empty(nCtx, s.NativeObject));
}
/// <summary>
/// Create the singleton sequence.
/// </summary>
public SeqExpr MkUnit(Expr elem)
{
Contract.Requires(elem != null);
Contract.Ensures(Contract.Result<SeqExpr>() != null);
return new SeqExpr(this, Native.Z3_mk_seq_unit(nCtx, elem.NativeObject));
}
/// <summary>
/// Create a string constant.
/// </summary>
public SeqExpr MkString(string s)
{
Contract.Requires(s != null);
Contract.Ensures(Contract.Result<SeqExpr>() != null);
return new SeqExpr(this, Native.Z3_mk_string(nCtx, s));
}
/// <summary>
/// Concatentate sequences.
/// </summary>
public SeqExpr MkConcat(params SeqExpr[] t)
{
Contract.Requires(t != null);
Contract.Requires(Contract.ForAll(t, a => a != null));
Contract.Ensures(Contract.Result<SeqExpr>() != null);
CheckContextMatch(t);
return new SeqExpr(this, Native.Z3_mk_seq_concat(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
}
/// <summary>
/// Retrieve the length of a given sequence.
/// </summary>
public IntExpr MkLength(SeqExpr s)
{
Contract.Requires(s != null);
Contract.Ensures(Contract.Result<IntExpr>() != null);
return (IntExpr) Expr.Create(this, Native.Z3_mk_seq_length(nCtx, s.NativeObject));
}
/// <summary>
/// Check for sequence prefix.
/// </summary>
public BoolExpr MkPrefixOf(SeqExpr s1, SeqExpr s2)
{
Contract.Requires(s1 != null);
Contract.Requires(s2 != null);
Contract.Ensures(Contract.Result<BoolExpr>() != null);
CheckContextMatch(s1, s2);
return new BoolExpr(this, Native.Z3_mk_seq_prefix(nCtx, s1.NativeObject, s2.NativeObject));
}
/// <summary>
/// Check for sequence suffix.
/// </summary>
public BoolExpr MkSuffixOf(SeqExpr s1, SeqExpr s2)
{
Contract.Requires(s1 != null);
Contract.Requires(s2 != null);
Contract.Ensures(Contract.Result<BoolExpr>() != null);
CheckContextMatch(s1, s2);
return new BoolExpr(this, Native.Z3_mk_seq_suffix(nCtx, s1.NativeObject, s2.NativeObject));
}
/// <summary>
/// Check for sequence containment of s2 in s1.
/// </summary>
public BoolExpr MkContains(SeqExpr s1, SeqExpr s2)
{
Contract.Requires(s1 != null);
Contract.Requires(s2 != null);
Contract.Ensures(Contract.Result<BoolExpr>() != null);
CheckContextMatch(s1, s2);
return new BoolExpr(this, Native.Z3_mk_seq_contains(nCtx, s1.NativeObject, s2.NativeObject));
}
/// <summary>
/// Retrieve sequence of length one at index.
/// </summary>
public SeqExpr MkAt(SeqExpr s, IntExpr index)
{
Contract.Requires(s != null);
Contract.Requires(index != null);
Contract.Ensures(Contract.Result<SeqExpr>() != null);
CheckContextMatch(s, index);
return new SeqExpr(this, Native.Z3_mk_seq_at(nCtx, s.NativeObject, index.NativeObject));
}
/// <summary>
/// Extract subsequence.
/// </summary>
public SeqExpr MkExtract(SeqExpr s, IntExpr offset, IntExpr length)
{
Contract.Requires(s != null);
Contract.Requires(offset != null);
Contract.Requires(length != null);
Contract.Ensures(Contract.Result<SeqExpr>() != null);
CheckContextMatch(s, offset, length);
return new SeqExpr(this, Native.Z3_mk_seq_extract(nCtx, s.NativeObject, offset.NativeObject, length.NativeObject));
}
/// <summary>
/// Extract index of sub-string starting at offset.
/// </summary>
public IntExpr MkIndexOf(SeqExpr s, SeqExpr substr, ArithExpr offset)
{
Contract.Requires(s != null);
Contract.Requires(offset != null);
Contract.Requires(substr != null);
Contract.Ensures(Contract.Result<IntExpr>() != null);
CheckContextMatch(s, substr, offset);
return new IntExpr(this, Native.Z3_mk_seq_index(nCtx, s.NativeObject, substr.NativeObject, offset.NativeObject));
}
/// <summary>
/// Replace the first occurrence of src by dst in s.
/// </summary>
public SeqExpr MkReplace(SeqExpr s, SeqExpr src, SeqExpr dst)
{
Contract.Requires(s != null);
Contract.Requires(src != null);
Contract.Requires(dst != null);
Contract.Ensures(Contract.Result<SeqExpr>() != null);
CheckContextMatch(s, src, dst);
return new SeqExpr(this, Native.Z3_mk_seq_replace(nCtx, s.NativeObject, src.NativeObject, dst.NativeObject));
}
/// <summary>
/// Convert a regular expression that accepts sequence s.
/// </summary>
public ReExpr MkToRe(SeqExpr s)
{
Contract.Requires(s != null);
Contract.Ensures(Contract.Result<ReExpr>() != null);
return new ReExpr(this, Native.Z3_mk_seq_to_re(nCtx, s.NativeObject));
}
/// <summary>
/// Check for regular expression membership.
/// </summary>
public BoolExpr MkInRe(SeqExpr s, ReExpr re)
{
Contract.Requires(s != null);
Contract.Requires(re != null);
Contract.Ensures(Contract.Result<BoolExpr>() != null);
CheckContextMatch(s, re);
return new BoolExpr(this, Native.Z3_mk_seq_in_re(nCtx, s.NativeObject, re.NativeObject));
}
/// <summary>
/// Take the Kleene star of a regular expression.
/// </summary>
public ReExpr MkStar(ReExpr re)
{
Contract.Requires(re != null);
Contract.Ensures(Contract.Result<ReExpr>() != null);
return new ReExpr(this, Native.Z3_mk_re_star(nCtx, re.NativeObject));
}
/// <summary>
/// Take the Kleene plus of a regular expression.
/// </summary>
public ReExpr MPlus(ReExpr re)
{
Contract.Requires(re != null);
Contract.Ensures(Contract.Result<ReExpr>() != null);
return new ReExpr(this, Native.Z3_mk_re_plus(nCtx, re.NativeObject));
}
/// <summary>
/// Create the optional regular expression.
/// </summary>
public ReExpr MOption(ReExpr re)
{
Contract.Requires(re != null);
Contract.Ensures(Contract.Result<ReExpr>() != null);
return new ReExpr(this, Native.Z3_mk_re_option(nCtx, re.NativeObject));
}
/// <summary>
/// Create the concatenation of regular languages.
/// </summary>
public ReExpr MkConcat(params ReExpr[] t)
{
Contract.Requires(t != null);
Contract.Requires(Contract.ForAll(t, a => a != null));
Contract.Ensures(Contract.Result<ReExpr>() != null);
CheckContextMatch(t);
return new ReExpr(this, Native.Z3_mk_re_concat(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
}
/// <summary>
/// Create the union of regular languages.
/// </summary>
public ReExpr MkUnion(params ReExpr[] t)
{
Contract.Requires(t != null);
Contract.Requires(Contract.ForAll(t, a => a != null));
Contract.Ensures(Contract.Result<ReExpr>() != null);
CheckContextMatch(t);
return new ReExpr(this, Native.Z3_mk_re_union(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
}
#endregion
#region Pseudo-Boolean constraints
/// <summary>
@ -4448,6 +4708,26 @@ namespace Microsoft.Z3
throw new Z3Exception("Context mismatch");
}
[Pure]
internal void CheckContextMatch(Z3Object other1, Z3Object other2)
{
Contract.Requires(other1 != null);
Contract.Requires(other2 != null);
CheckContextMatch(other1);
CheckContextMatch(other2);
}
[Pure]
internal void CheckContextMatch(Z3Object other1, Z3Object other2, Z3Object other3)
{
Contract.Requires(other1 != null);
Contract.Requires(other2 != null);
Contract.Requires(other3 != null);
CheckContextMatch(other1);
CheckContextMatch(other2);
CheckContextMatch(other3);
}
[Pure]
internal void CheckContextMatch(Z3Object[] arr)
{
@ -4628,6 +4908,7 @@ namespace Microsoft.Z3
m_boolSort = null;
m_intSort = null;
m_realSort = null;
m_stringSort = null;
}
#endregion
}

View file

@ -1826,6 +1826,8 @@ namespace Microsoft.Z3
case Z3_sort_kind.Z3_FLOATING_POINT_SORT: return new FPExpr(ctx, obj);
case Z3_sort_kind.Z3_ROUNDING_MODE_SORT: return new FPRMExpr(ctx, obj);
case Z3_sort_kind.Z3_FINITE_DOMAIN_SORT: return new FiniteDomainExpr(ctx, obj);
case Z3_sort_kind.Z3_RE_SORT: return new ReExpr(ctx, obj);
case Z3_sort_kind.Z3_SEQ_SORT: return new SeqExpr(ctx, obj);
}
return new Expr(ctx, obj);

42
src/api/dotnet/ReExpr.cs Normal file
View file

@ -0,0 +1,42 @@
/*++
Copyright (<c>) 2016 Microsoft Corporation
Module Name:
ReExpr.cs
Abstract:
Z3 Managed API: Regular Expressions
Author:
Christoph Wintersteiger (cwinter) 2012-11-23
Notes:
--*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;
namespace Microsoft.Z3
{
/// <summary>
/// Regular expression expressions
/// </summary>
public class ReExpr : Expr
{
#region Internal
/// <summary> Constructor for ReExpr </summary>
internal ReExpr(Context ctx, IntPtr obj)
: base(ctx, obj)
{
Contract.Requires(ctx != null);
}
#endregion
}
}

43
src/api/dotnet/ReSort.cs Normal file
View file

@ -0,0 +1,43 @@
/*++
Copyright (c) 2016 Microsoft Corporation
Module Name:
ReSort.cs
Abstract:
Z3 Managed API: Regular expression Sorts
Author:
Christoph Wintersteiger (cwinter) 2012-11-23
Notes:
--*/
using System;
using System.Diagnostics.Contracts;
namespace Microsoft.Z3
{
/// <summary>
/// A regular expression sort
/// </summary>
public class ReSort : Sort
{
#region Internal
internal ReSort(Context ctx, IntPtr obj)
: base(ctx, obj)
{
Contract.Requires(ctx != null);
}
internal ReSort(Context ctx)
: base(ctx, Native.Z3_mk_int_sort(ctx.nCtx))
{
Contract.Requires(ctx != null);
}
#endregion
}
}

42
src/api/dotnet/SeqExpr.cs Normal file
View file

@ -0,0 +1,42 @@
/*++
Copyright (<c>) 2016 Microsoft Corporation
Module Name:
SeqExpr.cs
Abstract:
Z3 Managed API: Sequence Expressions
Author:
Christoph Wintersteiger (cwinter) 2012-11-23
Notes:
--*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;
namespace Microsoft.Z3
{
/// <summary>
/// Sequence expressions
/// </summary>
public class SeqExpr : Expr
{
#region Internal
/// <summary> Constructor for SeqExpr </summary>
internal SeqExpr(Context ctx, IntPtr obj)
: base(ctx, obj)
{
Contract.Requires(ctx != null);
}
#endregion
}
}

43
src/api/dotnet/SeqSort.cs Normal file
View file

@ -0,0 +1,43 @@
/*++
Copyright (c) 2016 Microsoft Corporation
Module Name:
SeqSort.cs
Abstract:
Z3 Managed API: Sequence Sorts
Author:
Christoph Wintersteiger (cwinter) 2012-11-23
Notes:
--*/
using System;
using System.Diagnostics.Contracts;
namespace Microsoft.Z3
{
/// <summary>
/// A Sequence sort
/// </summary>
public class SeqSort : Sort
{
#region Internal
internal SeqSort(Context ctx, IntPtr obj)
: base(ctx, obj)
{
Contract.Requires(ctx != null);
}
internal SeqSort(Context ctx)
: base(ctx, Native.Z3_mk_int_sort(ctx.nCtx))
{
Contract.Requires(ctx != null);
}
#endregion
}
}

View file

@ -147,6 +147,8 @@ namespace Microsoft.Z3
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);
case Z3_sort_kind.Z3_SEQ_SORT: return new SeqSort(ctx, obj);
case Z3_sort_kind.Z3_RE_SORT: return new ReSort(ctx, obj);
default:
throw new Z3Exception("Unknown sort kind");
}

View file

@ -103,6 +103,7 @@ public class Context extends IDisposable
private BoolSort m_boolSort = null;
private IntSort m_intSort = null;
private RealSort m_realSort = null;
private SeqSort m_stringSort = null;
/**
* Retrieves the Boolean sort of the context.
@ -142,6 +143,16 @@ public class Context extends IDisposable
return new BoolSort(this);
}
/**
* Retrieves the Integer sort of the context.
**/
public SeqSort getStringSort()
{
if (m_stringSort == null)
m_stringSort = mkStringSort();
return m_stringSort;
}
/**
* Create a new uninterpreted sort.
**/
@ -193,6 +204,31 @@ public class Context extends IDisposable
return new ArraySort(this, domain, range);
}
/**
* Create a new string sort
**/
public SeqSort mkStringSort()
{
return new SeqSort(this, Native.mkStringSort(nCtx()));
}
/**
* Create a new sequence sort
**/
public SeqSort mkSeqSort(Sort s)
{
return new SeqSort(this, Native.mkSeqSort(nCtx(), s.getNativeObject()));
}
/**
* Create a new regular expression sort
**/
public ReSort mkReSort(Sort s)
{
return new ReSort(this, Native.mkReSort(nCtx(), s.getNativeObject()));
}
/**
* Create a new tuple sort.
**/
@ -1849,6 +1885,184 @@ public class Context extends IDisposable
arg2.getNativeObject()));
}
/**
* Sequences, Strings and regular expressions.
*/
/**
* Create the empty sequence.
*/
public SeqExpr MkEmptySeq(Sort s)
{
checkContextMatch(s);
return new SeqExpr(this, Native.mkSeqEmpty(nCtx(), s.getNativeObject()));
}
/**
* Create the singleton sequence.
*/
public SeqExpr MkUnit(Expr elem)
{
checkContextMatch(elem);
return new SeqExpr(this, Native.mkSeqUnit(nCtx(), elem.getNativeObject()));
}
/**
* Create a string constant.
*/
public SeqExpr MkString(String s)
{
return new SeqExpr(this, Native.mkString(nCtx(), s));
}
/**
* Concatentate sequences.
*/
public SeqExpr MkConcat(SeqExpr... t)
{
checkContextMatch(t);
return new SeqExpr(this, Native.mkSeqConcat(nCtx(), (int)t.length, AST.arrayToNative(t)));
}
/**
* Retrieve the length of a given sequence.
*/
public IntExpr MkLength(SeqExpr s)
{
checkContextMatch(s);
return (IntExpr) Expr.create(this, Native.mkSeqLength(nCtx(), s.getNativeObject()));
}
/**
* Check for sequence prefix.
*/
public BoolExpr MkPrefixOf(SeqExpr s1, SeqExpr s2)
{
checkContextMatch(s1, s2);
return new BoolExpr(this, Native.mkSeqPrefix(nCtx(), s1.getNativeObject(), s2.getNativeObject()));
}
/**
* Check for sequence suffix.
*/
public BoolExpr MkSuffixOf(SeqExpr s1, SeqExpr s2)
{
checkContextMatch(s1, s2);
return new BoolExpr(this, Native.mkSeqSuffix(nCtx(), s1.getNativeObject(), s2.getNativeObject()));
}
/**
* Check for sequence containment of s2 in s1.
*/
public BoolExpr MkContains(SeqExpr s1, SeqExpr s2)
{
checkContextMatch(s1, s2);
return new BoolExpr(this, Native.mkSeqContains(nCtx(), s1.getNativeObject(), s2.getNativeObject()));
}
/**
* Retrieve sequence of length one at index.
*/
public SeqExpr MkAt(SeqExpr s, IntExpr index)
{
checkContextMatch(s, index);
return new SeqExpr(this, Native.mkSeqAt(nCtx(), s.getNativeObject(), index.getNativeObject()));
}
/**
* Extract subsequence.
*/
public SeqExpr MkExtract(SeqExpr s, IntExpr offset, IntExpr length)
{
checkContextMatch(s, offset, length);
return new SeqExpr(this, Native.mkSeqExtract(nCtx(), s.getNativeObject(), offset.getNativeObject(), length.getNativeObject()));
}
/**
* Extract index of sub-string starting at offset.
*/
public IntExpr MkIndexOf(SeqExpr s, SeqExpr substr, ArithExpr offset)
{
checkContextMatch(s, substr, offset);
return new IntExpr(this, Native.mkSeqIndex(nCtx(), s.getNativeObject(), substr.getNativeObject(), offset.getNativeObject()));
}
/**
* Replace the first occurrence of src by dst in s.
*/
public SeqExpr MkReplace(SeqExpr s, SeqExpr src, SeqExpr dst)
{
checkContextMatch(s, src, dst);
return new SeqExpr(this, Native.mkSeqReplace(nCtx(), s.getNativeObject(), src.getNativeObject(), dst.getNativeObject()));
}
/**
* Convert a regular expression that accepts sequence s.
*/
public ReExpr MkToRe(SeqExpr s)
{
checkContextMatch(s);
return new ReExpr(this, Native.mkSeqToRe(nCtx(), s.getNativeObject()));
}
/**
* Check for regular expression membership.
*/
public BoolExpr MkInRe(SeqExpr s, ReExpr re)
{
checkContextMatch(s, re);
return new BoolExpr(this, Native.mkSeqInRe(nCtx(), s.getNativeObject(), re.getNativeObject()));
}
/**
* Take the Kleene star of a regular expression.
*/
public ReExpr MkStar(ReExpr re)
{
checkContextMatch(re);
return new ReExpr(this, Native.mkReStar(nCtx(), re.getNativeObject()));
}
/**
* Take the Kleene plus of a regular expression.
*/
public ReExpr MPlus(ReExpr re)
{
checkContextMatch(re);
return new ReExpr(this, Native.mkRePlus(nCtx(), re.getNativeObject()));
}
/**
* Create the optional regular expression.
*/
public ReExpr MOption(ReExpr re)
{
checkContextMatch(re);
return new ReExpr(this, Native.mkReOption(nCtx(), re.getNativeObject()));
}
/**
* Create the concatenation of regular languages.
*/
public ReExpr MkConcat(ReExpr... t)
{
checkContextMatch(t);
return new ReExpr(this, Native.mkReConcat(nCtx(), (int)t.length, AST.arrayToNative(t)));
}
/**
* Create the union of regular languages.
*/
public ReExpr MkUnion(ReExpr... t)
{
checkContextMatch(t);
return new ReExpr(this, Native.mkReUnion(nCtx(), (int)t.length, AST.arrayToNative(t)));
}
/**
* 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
@ -3683,6 +3897,19 @@ public class Context extends IDisposable
throw new Z3Exception("Context mismatch");
}
void checkContextMatch(Z3Object other1, Z3Object other2)
{
checkContextMatch(other1);
checkContextMatch(other2);
}
void checkContextMatch(Z3Object other1, Z3Object other2, Z3Object other3)
{
checkContextMatch(other1);
checkContextMatch(other2);
checkContextMatch(other3);
}
void checkContextMatch(Z3Object[] arr)
{
if (arr != null)
@ -3822,6 +4049,7 @@ public class Context extends IDisposable
m_Params_DRQ.clear(this);
m_Probe_DRQ.clear(this);
m_Solver_DRQ.clear(this);
m_Optimize_DRQ.clear(this);
m_Statistics_DRQ.clear(this);
m_Tactic_DRQ.clear(this);
m_Fixedpoint_DRQ.clear(this);
@ -3829,6 +4057,7 @@ public class Context extends IDisposable
m_boolSort = null;
m_intSort = null;
m_realSort = null;
m_stringSort = null;
synchronized (creation_lock) {
if (m_refCount.get() == 0 && m_ctx != 0) {

View file

@ -2186,6 +2186,10 @@ public class Expr extends AST
return new FPRMExpr(ctx, obj);
case Z3_FINITE_DOMAIN_SORT:
return new FiniteDomainExpr(ctx, obj);
case Z3_SEQ_SORT:
return new SeqExpr(ctx, obj);
case Z3_RE_SORT:
return new ReExpr(ctx, obj);
default: ;
}

View file

@ -141,6 +141,10 @@ public class Sort extends AST
return new FPSort(ctx, obj);
case Z3_ROUNDING_MODE_SORT:
return new FPRMSort(ctx, obj);
case Z3_SEQ_SORT:
return new SeqSort(ctx, obj);
case Z3_RE_SORT:
return new ReSort(ctx, obj);
default:
throw new Z3Exception("Unknown sort kind");
}

View file

@ -87,6 +87,8 @@ struct
(z3obj_sno res ctx no) ;
(z3obj_create res) ;
res
end
open Internal
@ -833,6 +835,13 @@ end = struct
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 apply1 ctx f t = expr_of_ptr ctx (f (context_gno ctx) (gno t)) in
let apply2 ctx f t1 t2 = expr_of_ptr ctx (f (context_gno ctx) (gno t1) (gno t2)) in
let apply3 ctx f t1 t2 t3 = expr_of_ptr ctx (f (context_gno ctx) (gno t1) (gno t2) (gno t3)) in
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))
@ -854,13 +863,13 @@ end = struct
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))
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_))
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_ ]
@ -872,7 +881,7 @@ end = struct
if (Expr.gc x) == to_ctx then
x
else
expr_of_ptr to_ctx (Z3native.translate (gnc x) (gno 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 (gnc x) (gno x)
@ -933,34 +942,33 @@ struct
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_not ( ctx : context ) ( a : expr ) = apply1 ctx Z3native.mk_not 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_ite ( ctx : context ) ( t1 : expr ) ( t2 : expr ) ( t3 : expr ) =
apply3 ctx Z3native.mk_ite t1 t2 t3
let mk_iff ( ctx : context ) ( t1 : expr ) ( t2 : expr ) =
expr_of_ptr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2))
apply2 ctx Z3native.mk_iff t1 t2
let mk_implies ( ctx : context ) ( t1 : expr ) ( t2 : expr ) =
expr_of_ptr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2))
apply2 ctx Z3native.mk_implies t1 t2
let mk_xor ( ctx : context ) ( t1 : expr ) ( t2 : expr ) =
expr_of_ptr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2))
apply2 ctx Z3native.mk_xor t1 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)))
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)))
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))
apply2 ctx Z3native.mk_eq x 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))
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))
@ -1066,10 +1074,10 @@ struct
mk_list f n
let get_body ( x : quantifier ) =
expr_of_ptr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x))
apply1 (gc x) Z3native.get_quantifier_body x
let mk_bound ( ctx : context ) ( index : int ) ( ty : Sort.sort ) =
expr_of_ptr ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty))
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
@ -1194,23 +1202,23 @@ struct
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))
apply2 ctx Z3native.mk_select a 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))
apply3 ctx Z3native.mk_store a i v
let mk_const_array ( ctx : context ) ( domain : Sort.sort ) ( v : expr ) =
expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (Expr.gno 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 : 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))
apply1 ctx Z3native.mk_array_default arg
let mk_array_ext ( ctx : context) ( arg1 : expr ) ( arg2 : expr ) =
expr_of_ptr ctx (Z3native.mk_array_ext (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2))
apply2 ctx Z3native.mk_array_ext arg1 arg2
end
@ -1233,13 +1241,14 @@ 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) (Expr.gno set) (Expr.gno element))
apply2 ctx Z3native.mk_set_add set 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))
apply2 Z3native.mk_set_del set 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 r = expr_of_ptr ctx (Z3native.mk_set_union (context_gno ctx) (List.length args) (expr_lton args)) in
r
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))

View file

@ -930,6 +930,10 @@ def _to_expr_ref(a, ctx):
return FiniteDomainRef(a, ctx)
if sk == Z3_ROUNDING_MODE_SORT:
return FPRMRef(a, ctx)
if sk == Z3_SEQ_SORT:
return SeqRef(a, ctx)
if sk == Z3_RE_SORT:
return ReRef(a, ctx)
return ExprRef(a, ctx)
def _coerce_expr_merge(s, a):
@ -3562,24 +3566,56 @@ def Concat(*args):
121
"""
args = _get_args(args)
sz = len(args)
if __debug__:
_z3_assert(sz >= 2, "At least two arguments expected.")
ctx = args[0].ctx
if is_seq(args[0]):
if __debug__:
_z3_assert(all([is_seq(a) for a in args]), "All arguments must be sequence expressions.")
v = (Ast * sz)()
for i in range(sz):
v[i] = args[i].as_ast()
return SeqRef(Z3_mk_seq_concat(ctx.ref(), sz, v), ctx)
if is_re(args[0]):
if __debug__:
_z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
v = (Ast * sz)()
for i in range(sz):
v[i] = args[i].as_ast()
return ReRef(Z3_mk_re_concat(ctx.ref(), sz, v), ctx)
if __debug__:
_z3_assert(all([is_bv(a) for a in args]), "All arguments must be Z3 bit-vector expressions.")
_z3_assert(len(args) >= 2, "At least two arguments expected.")
ctx = args[0].ctx
r = args[0]
for i in range(len(args) - 1):
for i in range(sz - 1):
r = BitVecRef(Z3_mk_concat(ctx.ref(), r.as_ast(), args[i+1].as_ast()), ctx)
return r
def Extract(high, low, a):
"""Create a Z3 bit-vector extraction expression.
"""Create a Z3 bit-vector extraction expression, or create a string extraction expression.
>>> x = BitVec('x', 8)
>>> Extract(6, 2, x)
Extract(6, 2, x)
>>> Extract(6, 2, x).sort()
BitVec(5)
>>> simplify(Extract(StringVal("abcd"),2,1))
"c"
"""
if isinstance(high, str):
high = StringVal(high)
if is_seq(high):
s = high
offset = _py2expr(low, high.ctx)
length = _py2expr(a, high.ctx)
if __debug__:
_z3_assert(is_int(offset) and is_int(length), "Second and third arguments must be integers")
return SeqRef(Z3_mk_seq_extract(s.ctx_ref(), s.as_ast(), offset.as_ast(), length.as_ast()), s.ctx)
if __debug__:
_z3_assert(low <= high, "First argument must be greater than or equal to second argument")
_z3_assert(isinstance(high, int) and high >= 0 and isinstance(low, int) and low >= 0, "First and second arguments must be non negative integers")
@ -7781,7 +7817,7 @@ def binary_interpolant(a,b,p=None,ctx=None):
solver that determines satisfiability.
x = Int('x')
print binary_interpolant(x<0,x>2)
print(binary_interpolant(x<0,x>2))
Not(x >= 0)
"""
f = And(Interpolant(a),b)
@ -7821,6 +7857,7 @@ def sequence_interpolant(v,p=None,ctx=None):
f = And(Interpolant(f),v[i])
return tree_interpolant(f,p,ctx)
#########################################
#
# Floating-Point Arithmetic
@ -8901,3 +8938,339 @@ def fpToIEEEBV(x):
if __debug__:
_z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression")
return BitVecRef(Z3_mk_fpa_to_ieee_bv(x.ctx_ref(), x.ast), x.ctx)
#########################################
#
# Strings, Sequences and Regular expressions
#
#########################################
class SeqSortRef(SortRef):
"""Sequence sort."""
def is_string(self):
"""Determine if sort is a string
>>> s = StringSort()
>>> s.is_string()
True
>>> s = SeqSort(IntSort())
>>> s.is_string()
False
"""
return Z3_is_string_sort(self.ctx_ref(), self.ast)
def StringSort(ctx=None):
"""Create a string sort
>>> s = StringSort()
>>> print(s)
String
"""
ctx = _get_ctx(ctx)
return SeqSortRef(Z3_mk_string_sort(ctx.ref()), ctx)
def SeqSort(s):
"""Create a sequence sort over elements provided in the argument
>>> s = SeqSort(IntSort())
>>> s == Unit(IntVal(1)).sort()
True
"""
return SeqSortRef(Z3_mk_seq_sort(s.ctx_ref(), s.ast), s.ctx)
class SeqRef(ExprRef):
"""Sequence expression."""
def sort(self):
return SeqSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx)
def __add__(self, other):
return Concat(self, other)
def __getitem__(self, i):
return SeqRef(Z3_mk_seq_at(self.ctx_ref(), self.as_ast(), i.as_ast()), self.ctx)
def is_string(self):
return Z3_is_string_sort(self.ctx_ref(), Z3_get_sort(self.ctx_ref(), self.as_ast()))
def is_string_value(self):
return Z3_is_string(self.ctx_ref(), self.as_ast())
def as_string(self):
"""Return a string representation of sequence expression."""
return Z3_ast_to_string(self.ctx_ref(), self.as_ast())
def _coerce_seq(s, ctx=None):
if isinstance(s, str):
ctx = _get_ctx(ctx)
s = StringVal(s, ctx)
return s
def _get_ctx2(a, b, ctx=None):
if is_expr(a):
return a.ctx
if is_expr(b):
return b.ctx
if ctx is None:
ctx = main_ctx()
return ctx
def is_seq(a):
"""Return `True` if `a` is a Z3 sequence expression.
>>> print (is_seq(Unit(IntVal(0))))
True
>>> print (is_seq(StringVal("abc")))
True
"""
return isinstance(a, SeqRef)
def is_string(a):
"""Return `True` if `a` is a Z3 string expression.
>>> print (is_string(StringVal("ab")))
True
"""
return isinstance(a, SeqRef) and a.is_string()
def is_string_value(a):
"""return 'True' if 'a' is a Z3 string constant expression.
>>> print (is_string_value(StringVal("a")))
True
>>> print (is_string_value(StringVal("a") + StringVal("b")))
False
"""
return isinstance(a, SeqRef) and a.is_string_value()
def StringVal(s, ctx=None):
"""create a string expression"""
ctx = _get_ctx(ctx)
return SeqRef(Z3_mk_string(ctx.ref(), s), ctx)
def String(name, ctx=None):
"""Return a string constant named `name`. If `ctx=None`, then the global context is used.
>>> x = String('x')
"""
ctx = _get_ctx(ctx)
return SeqRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), StringSort(ctx).ast), ctx)
def Strings(names, ctx=None):
"""Return a tuple of String constants. """
ctx = _get_ctx(ctx)
if isinstance(names, str):
names = names.split(" ")
return [String(name, ctx) for name in names]
def Empty(s):
"""Create the empty sequence of the given sort
>>> e = Empty(StringSort())
>>> print(e)
""
>>> e2 = StringVal("")
>>> print(e.eq(e2))
True
>>> e3 = Empty(SeqSort(IntSort()))
>>> print(e3)
seq.empty
"""
return SeqRef(Z3_mk_seq_empty(s.ctx_ref(), s.ast), s.ctx)
def Unit(a):
"""Create a singleton sequence"""
return SeqRef(Z3_mk_seq_unit(a.ctx_ref(), a.as_ast()), a.ctx)
def PrefixOf(a, b):
"""Check if 'a' is a prefix of 'b'
>>> s1 = PrefixOf("ab", "abc")
>>> simplify(s1)
True
>>> s2 = PrefixOf("bc", "abc")
>>> simplify(s2)
False
"""
ctx = _get_ctx2(a, b)
a = _coerce_seq(a, ctx)
b = _coerce_seq(b, ctx)
return BoolRef(Z3_mk_seq_prefix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
def SuffixOf(a, b):
"""Check if 'a' is a suffix of 'b'
>>> s1 = SuffixOf("ab", "abc")
>>> simplify(s1)
False
>>> s2 = SuffixOf("bc", "abc")
>>> simplify(s2)
True
"""
ctx = _get_ctx2(a, b)
a = _coerce_seq(a, ctx)
b = _coerce_seq(b, ctx)
return BoolRef(Z3_mk_seq_suffix(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
def Contains(a, b):
"""Check if 'a' contains 'b'
>>> s1 = Contains("abc", "ab")
>>> simplify(s1)
True
>>> s2 = Contains("abc", "bc")
>>> simplify(s2)
True
>>> x, y, z = Strings('x y z')
>>> s3 = Contains(Concat(x,y,z), y)
>>> simplify(s3)
True
"""
ctx = _get_ctx2(a, b)
a = _coerce_seq(a, ctx)
b = _coerce_seq(b, ctx)
return BoolRef(Z3_mk_seq_contains(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx)
def Replace(s, src, dst):
"""Replace the first occurrence of 'src' by 'dst' in 's'
>>> r = Replace("aaa", "a", "b")
>>> simplify(r)
"baa"
"""
ctx = _get_ctx2(dst, s)
if ctx is None and is_expr(src):
ctx = src.ctx
src = _coerce_seq(src, ctx)
dst = _coerce_seq(dst, ctx)
s = _coerce_seq(s, ctx)
return SeqRef(Z3_mk_seq_replace(src.ctx_ref(), s.as_ast(), src.as_ast(), dst.as_ast()), s.ctx)
def IndexOf(s, substr):
return IndexOf(s, substr, IntVal(0))
def IndexOf(s, substr, offset):
"""Retrieve the index of substring within a string starting at a specified offset.
>>> simplify(IndexOf("abcabc", "bc", 0))
1
>>> simplify(IndexOf("abcabc", "bc", 2))
4
"""
ctx = None
if is_expr(offset):
ctx = offset.ctx
ctx = _get_ctx2(s, substr, ctx)
s = _coerce_seq(s, ctx)
substr = _coerce_seq(substr, ctx)
if isinstance(offset, int):
offset = IntVal(offset, ctx)
return SeqRef(Z3_mk_seq_index(s.ctx_ref(), s.as_ast(), substr.as_ast(), offset.as_ast()), s.ctx)
def Length(s):
"""Obtain the length of a sequence 's'
>>> l = Length(StringVal("abc"))
>>> simplify(l)
3
"""
s = _coerce_seq(s)
return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
def Re(s, ctx=None):
"""The regular expression that accepts sequence 's'
>>> s1 = Re("ab")
>>> s2 = Re(StringVal("ab"))
>>> s3 = Re(Unit(BoolVal(True)))
"""
s = _coerce_seq(s, ctx)
return ReRef(Z3_mk_seq_to_re(s.ctx_ref(), s.as_ast()), s.ctx)
## Regular expressions
class ReSortRef(SortRef):
"""Regular expression sort."""
def ReSort(s):
if is_ast(s):
return ReSortRef(Z3_mk_re_sort(s.ctx.ref(), s.as_ast()), ctx)
if s is None or isinstance(s, Context):
ctx = _get_ctx(s)
return ReSortRef(Z3_mk_re_sort(ctx.ref(), Z3_mk_string_sort(ctx.ref())), ctx)
raise Z3Exception("Regular expression sort constructor expects either a string or a context or no argument")
class ReRef(ExprRef):
"""Regular expressions."""
def __add__(self, other):
return Union(self, other)
def is_re(s):
return isinstance(s, ReRef)
def InRe(s, re):
"""Create regular expression membership test
>>> re = Union(Re("a"),Re("b"))
>>> print (simplify(InRe("a", re)))
True
>>> print (simplify(InRe("b", re)))
True
>>> print (simplify(InRe("c", re)))
False
"""
s = _coerce_seq(s, re.ctx)
return BoolRef(Z3_mk_seq_in_re(s.ctx_ref(), s.as_ast(), re.as_ast()), s.ctx)
def Union(*args):
"""Create union of regular expressions.
>>> re = Union(Re("a"), Re("b"), Re("c"))
>>> print (simplify(InRe("d", re)))
False
"""
args = _get_args(args)
sz = len(args)
if __debug__:
_z3_assert(sz >= 2, "At least two arguments expected.")
_z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
ctx = args[0].ctx
v = (Ast * sz)()
for i in range(sz):
v[i] = args[i].as_ast()
return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
def Plus(re):
"""Create the regular expression accepting one or more repetitions of argument.
>>> re = Plus(Re("a"))
>>> print(simplify(InRe("aa", re)))
True
>>> print(simplify(InRe("ab", re)))
False
>>> print(simplify(InRe("", re)))
False
"""
return ReRef(Z3_mk_re_plus(re.ctx_ref(), re.as_ast()), re.ctx)
def Option(re):
"""Create the regular expression that optionally accepts the argument.
>>> re = Option(Re("a"))
>>> print(simplify(InRe("a", re)))
True
>>> print(simplify(InRe("", re)))
True
>>> print(simplify(InRe("aa", re)))
False
"""
return ReRef(Z3_mk_re_option(re.ctx_ref(), re.as_ast()), re.ctx)
def Star(re):
"""Create the regular expression accepting zero or more repetitions of argument.
>>> re = Star(Re("a"))
>>> print(simplify(InRe("aa", re)))
True
>>> print(simplify(InRe("ab", re)))
False
>>> print(simplify(InRe("", re)))
True
"""
return ReRef(Z3_mk_re_star(re.ctx_ref(), re.as_ast()), re.ctx)

View file

@ -570,6 +570,9 @@ class Formatter:
def pp_algebraic(self, a):
return to_format(a.as_decimal(self.precision))
def pp_string(self, a):
return to_format(a.as_string())
def pp_bv(self, a):
return to_format(a.as_string())
@ -875,6 +878,8 @@ class Formatter:
return self.pp_fp_value(a)
elif z3.is_fp(a):
return self.pp_fp(a, d, xs)
elif z3.is_string_value(a):
return self.pp_string(a)
elif z3.is_const(a):
return self.pp_const(a)
else:

View file

@ -161,6 +161,8 @@ typedef enum
Z3_FINITE_DOMAIN_SORT,
Z3_FLOATING_POINT_SORT,
Z3_ROUNDING_MODE_SORT,
Z3_SEQ_SORT,
Z3_RE_SORT,
Z3_UNKNOWN_SORT = 1000
} Z3_sort_kind;
@ -1098,7 +1100,7 @@ typedef enum {
Z3_OP_PR_TH_LEMMA,
Z3_OP_PR_HYPER_RESOLVE,
// Sequences
// Relational algebra
Z3_OP_RA_STORE = 0x600,
Z3_OP_RA_EMPTY,
Z3_OP_RA_IS_EMPTY,
@ -1115,6 +1117,28 @@ typedef enum {
Z3_OP_FD_CONSTANT,
Z3_OP_FD_LT,
// Sequences
Z3_OP_SEQ_UNIT,
Z3_OP_SEQ_EMPTY,
Z3_OP_SEQ_CONCAT,
Z3_OP_SEQ_PREFIX,
Z3_OP_SEQ_SUFFIX,
Z3_OP_SEQ_CONTAINS,
Z3_OP_SEQ_EXTRACT,
Z3_OP_SEQ_REPLACE,
Z3_OP_SEQ_AT,
Z3_OP_SEQ_LENGTH,
Z3_OP_SEQ_INDEX,
Z3_OP_SEQ_TO_RE,
Z3_OP_SEQ_IN_RE,
// regular expressions
Z3_OP_RE_PLUS,
Z3_OP_RE_STAR,
Z3_OP_RE_OPTION,
Z3_OP_RE_CONCAT,
Z3_OP_RE_UNION,
// Auxiliary
Z3_OP_LABEL = 0x700,
Z3_OP_LABEL_LIT,
@ -3093,6 +3117,222 @@ extern "C" {
/*@}*/
/** @name Sequences and regular expressions */
/*@{*/
/**
\brief Create a sequence sort out of the sort for the elements.
def_API('Z3_mk_seq_sort', SORT, (_in(CONTEXT), _in(SORT)))
*/
Z3_sort Z3_API Z3_mk_seq_sort(Z3_context c, Z3_sort s);
/**
\brief Check if \c s is a sequence sort.
def_API('Z3_is_seq_sort', BOOL, (_in(CONTEXT), _in(SORT)))
*/
Z3_bool Z3_API Z3_is_seq_sort(Z3_context c, Z3_sort s);
/**
\brief Create a regular expression sort out of a sequence sort.
def_API('Z3_mk_re_sort', SORT, (_in(CONTEXT), _in(SORT)))
*/
Z3_sort Z3_API Z3_mk_re_sort(Z3_context c, Z3_sort seq);
/**
\brief Check if \c s is a regular expression sort.
def_API('Z3_is_re_sort', BOOL, (_in(CONTEXT), _in(SORT)))
*/
Z3_bool Z3_API Z3_is_re_sort(Z3_context c, Z3_sort s);
/**
\brief Create a sort for 8 bit strings.
This function creates a sort for ASCII strings.
Each character is 8 bits.
def_API('Z3_mk_string_sort', SORT ,(_in(CONTEXT), ))
*/
Z3_sort Z3_API Z3_mk_string_sort(Z3_context c);
/**
\brief Check if \c s is a string sort.
def_API('Z3_is_string_sort', BOOL, (_in(CONTEXT), _in(SORT)))
*/
Z3_bool Z3_API Z3_is_string_sort(Z3_context c, Z3_sort s);
/**
\brief Create a string constant out of the string that is passed in
def_API('Z3_mk_string' ,AST ,(_in(CONTEXT), _in(STRING)))
*/
Z3_ast Z3_API Z3_mk_string(Z3_context c, Z3_string s);
/**
\brief Determine if \c s is a string constant.
def_API('Z3_is_string', BOOL, (_in(CONTEXT), _in(AST)))
*/
Z3_bool Z3_API Z3_is_string(Z3_context c, Z3_ast s);
/**
\brief Retrieve the string constant stored in \c s.
\pre Z3_is_string(c, s)
def_API('Z3_get_string' ,STRING ,(_in(CONTEXT), _in(AST)))
*/
Z3_string Z3_API Z3_get_string(Z3_context c, Z3_ast s);
/**
\brief Create an empty sequence of the sequence sort \c seq.
\pre s is a sequence sort.
def_API('Z3_mk_seq_empty' ,AST ,(_in(CONTEXT), _in(SORT)))
*/
Z3_ast Z3_API Z3_mk_seq_empty(Z3_context c, Z3_sort seq);
/**
\brief Create a unit sequence of \c a.
def_API('Z3_mk_seq_unit' ,AST ,(_in(CONTEXT), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_seq_unit(Z3_context c, Z3_ast a);
/**
\brief Concatenate sequences.
\pre n > 0
def_API('Z3_mk_seq_concat' ,AST ,(_in(CONTEXT), _in(UINT), _in_array(1, AST)))
*/
Z3_ast Z3_API Z3_mk_seq_concat(Z3_context c, unsigned n, Z3_ast const args[]);
/**
\brief Check if \c prefix is a prefix of \c s.
\pre prefix and s are the same sequence sorts.
def_API('Z3_mk_seq_prefix' ,AST ,(_in(CONTEXT), _in(AST), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_seq_prefix(Z3_context c, Z3_ast prefix, Z3_ast s);
/**
\brief Check if \c suffix is a suffix of \c s.
\pre \c suffix and \c s are the same sequence sorts.
def_API('Z3_mk_seq_suffix' ,AST ,(_in(CONTEXT), _in(AST), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_seq_suffix(Z3_context c, Z3_ast suffix, Z3_ast s);
/**
\brief Check if \c container contains \c containee.
\pre \c container and \c containee are the same sequence sorts.
def_API('Z3_mk_seq_contains' ,AST ,(_in(CONTEXT), _in(AST), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_seq_contains(Z3_context c, Z3_ast container, Z3_ast containee);
/**
\brief Extract subsequence starting at \c offset of \c length.
def_API('Z3_mk_seq_extract' ,AST ,(_in(CONTEXT), _in(AST), _in(AST), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_seq_extract(Z3_context c, Z3_ast s, Z3_ast offset, Z3_ast length);
/**
\brief Replace the first occurrence of \c src with \c dst in \c s.
def_API('Z3_mk_seq_replace' ,AST ,(_in(CONTEXT), _in(AST), _in(AST), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_seq_replace(Z3_context c, Z3_ast s, Z3_ast src, Z3_ast dst);
/**
\brief Retrieve from \s the unit sequence positioned at position \c index.
def_API('Z3_mk_seq_at' ,AST ,(_in(CONTEXT), _in(AST), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_seq_at(Z3_context c, Z3_ast s, Z3_ast index);
/**
\brief Return the length of the sequence \c s.
def_API('Z3_mk_seq_length' ,AST ,(_in(CONTEXT), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_seq_length(Z3_context c, Z3_ast s);
/**
\brief Return index of first occurrence of \c substr in \c s starting from offset \c offset.
If \c s does not contain \c substr, then the value is -1, if \c offset is the length of \c s, then the value is -1 as well.
The function is under-specified if \c offset is negative or larger than the length of \c s.
def_API('Z3_mk_seq_index' ,AST ,(_in(CONTEXT), _in(AST), _in(AST), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_seq_index(Z3_context c, Z3_ast s, Z3_ast substr, Z3_ast offset);
/**
\brief Create a regular expression that accepts the sequence \c seq.
def_API('Z3_mk_seq_to_re' ,AST ,(_in(CONTEXT), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_seq_to_re(Z3_context c, Z3_ast seq);
/**
\brief Check if \c seq is in the language generated by the regular expression \c re.
def_API('Z3_mk_seq_in_re' ,AST ,(_in(CONTEXT), _in(AST), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_seq_in_re(Z3_context c, Z3_ast seq, Z3_ast re);
/**
\brief Create the regular language \c re+.
def_API('Z3_mk_re_plus' ,AST ,(_in(CONTEXT), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_re_plus(Z3_context c, Z3_ast re);
/**
\brief Create the regular language \c re*.
def_API('Z3_mk_re_star' ,AST ,(_in(CONTEXT), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_re_star(Z3_context c, Z3_ast re);
/**
\brief Create the regular language \c [re].
def_API('Z3_mk_re_option' ,AST ,(_in(CONTEXT), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_re_option(Z3_context c, Z3_ast re);
/**
\brief Create the union of the regular languages.
\pre n > 0
def_API('Z3_mk_re_union' ,AST ,(_in(CONTEXT), _in(UINT), _in_array(1, AST)))
*/
Z3_ast Z3_API Z3_mk_re_union(Z3_context c, unsigned n, Z3_ast const args[]);
/**
\brief Create the concatenation of the regular languages.
\pre n > 0
def_API('Z3_mk_re_concat' ,AST ,(_in(CONTEXT), _in(UINT), _in_array(1, AST)))
*/
Z3_ast Z3_API Z3_mk_re_concat(Z3_context c, unsigned n, Z3_ast const args[]);
/*@}*/
/** @name Quantifiers */
/*@{*/
/**

View file

@ -46,6 +46,7 @@ struct z3_replayer::imp {
size_t m_ptr;
size_t_map<void *> m_heap;
svector<z3_replayer_cmd> m_cmds;
vector<std::string> m_cmds_names;
enum value_kind { INT64, UINT64, DOUBLE, STRING, SYMBOL, OBJECT, UINT_ARRAY, INT_ARRAY, SYMBOL_ARRAY, OBJECT_ARRAY, FLOAT };
@ -509,6 +510,7 @@ struct z3_replayer::imp {
if (idx >= m_cmds.size())
throw z3_replayer_exception("invalid command");
try {
TRACE("z3_replayer_cmd", tout << m_cmds_names[idx] << "\n";);
m_cmds[idx](m_owner);
}
catch (z3_error & ex) {
@ -672,9 +674,11 @@ struct z3_replayer::imp {
m_result = obj;
}
void register_cmd(unsigned id, z3_replayer_cmd cmd) {
void register_cmd(unsigned id, z3_replayer_cmd cmd, char const* name) {
m_cmds.reserve(id+1, 0);
m_cmds_names.reserve(id+1, "");
m_cmds[id] = cmd;
m_cmds_names[id] = name;
}
void reset() {
@ -786,8 +790,8 @@ void z3_replayer::store_result(void * obj) {
return m_imp->store_result(obj);
}
void z3_replayer::register_cmd(unsigned id, z3_replayer_cmd cmd) {
return m_imp->register_cmd(id, cmd);
void z3_replayer::register_cmd(unsigned id, z3_replayer_cmd cmd, char const* name) {
return m_imp->register_cmd(id, cmd, name);
}
void z3_replayer::parse() {

View file

@ -62,7 +62,7 @@ public:
void ** get_obj_addr(unsigned pos);
void store_result(void * obj);
void register_cmd(unsigned id, z3_replayer_cmd cmd);
void register_cmd(unsigned id, z3_replayer_cmd cmd, char const* name);
};
#endif