mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 09:05:31 +00:00
Merge branch 'master' of https://github.com/Z3Prover/z3
This commit is contained in:
commit
216e17e5e2
25 changed files with 580 additions and 67 deletions
|
@ -1110,29 +1110,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 OP_SEQ_UNIT: return Z3_OP_SEQ_UNIT;
|
||||
case OP_SEQ_EMPTY: return Z3_OP_SEQ_EMPTY;
|
||||
case OP_SEQ_CONCAT: return Z3_OP_SEQ_CONCAT;
|
||||
case OP_SEQ_PREFIX: return Z3_OP_SEQ_PREFIX;
|
||||
case OP_SEQ_SUFFIX: return Z3_OP_SEQ_SUFFIX;
|
||||
case OP_SEQ_CONTAINS: return Z3_OP_SEQ_CONTAINS;
|
||||
case OP_SEQ_EXTRACT: return Z3_OP_SEQ_EXTRACT;
|
||||
case OP_SEQ_REPLACE: return Z3_OP_SEQ_REPLACE;
|
||||
case OP_SEQ_AT: return Z3_OP_SEQ_AT;
|
||||
case OP_SEQ_LENGTH: return Z3_OP_SEQ_LENGTH;
|
||||
case OP_SEQ_INDEX: return Z3_OP_SEQ_INDEX;
|
||||
case OP_SEQ_TO_RE: return Z3_OP_SEQ_TO_RE;
|
||||
case 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;
|
||||
case Z3_OP_RE_INTERSECT: return Z3_OP_RE_INTERSECT;
|
||||
case Z3_OP_RE_LOOP: return Z3_OP_RE_LOOP;
|
||||
case Z3_OP_RE_FULL_SET: return Z3_OP_RE_FULL_SET;
|
||||
case Z3_OP_RE_EMPTY_SET: return Z3_OP_RE_EMPTY_SET;
|
||||
case OP_STRING_STOI: return Z3_OP_STR_TO_INT;
|
||||
case OP_STRING_ITOS: return Z3_OP_INT_TO_STR;
|
||||
|
||||
case OP_RE_PLUS: return Z3_OP_RE_PLUS;
|
||||
case OP_RE_STAR: return Z3_OP_RE_STAR;
|
||||
case OP_RE_OPTION: return Z3_OP_RE_OPTION;
|
||||
case OP_RE_CONCAT: return Z3_OP_RE_CONCAT;
|
||||
case OP_RE_UNION: return Z3_OP_RE_UNION;
|
||||
case OP_RE_INTERSECT: return Z3_OP_RE_INTERSECT;
|
||||
case OP_RE_LOOP: return Z3_OP_RE_LOOP;
|
||||
case OP_RE_FULL_SET: return Z3_OP_RE_FULL_SET;
|
||||
case OP_RE_EMPTY_SET: return Z3_OP_RE_EMPTY_SET;
|
||||
default:
|
||||
return Z3_OP_INTERNAL;
|
||||
}
|
||||
|
|
|
@ -141,6 +141,10 @@ extern "C" {
|
|||
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_int_to_str, mk_c(c)->get_seq_fid(), OP_STRING_ITOS, SKIP);
|
||||
MK_UNARY(Z3_mk_str_to_int, mk_c(c)->get_seq_fid(), OP_STRING_STOI, SKIP);
|
||||
|
||||
|
||||
Z3_ast Z3_API Z3_mk_re_loop(Z3_context c, Z3_ast r, unsigned lo, unsigned hi) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_re_loop(c, r, lo, hi);
|
||||
|
|
|
@ -435,6 +435,8 @@ namespace z3 {
|
|||
Z3_ast_kind kind() const { Z3_ast_kind r = Z3_get_ast_kind(ctx(), m_ast); check_error(); return r; }
|
||||
unsigned hash() const { unsigned r = Z3_get_ast_hash(ctx(), m_ast); check_error(); return r; }
|
||||
friend std::ostream & operator<<(std::ostream & out, ast const & n);
|
||||
std::string to_string() const { return std::string(Z3_ast_to_string(ctx(), m_ast)); }
|
||||
|
||||
|
||||
/**
|
||||
\brief Return true if the ASTs are structurally identical.
|
||||
|
@ -757,7 +759,25 @@ namespace z3 {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Z3_lbool bool_value() const {
|
||||
return Z3_get_bool_value(ctx(), m_ast);
|
||||
}
|
||||
|
||||
expr numerator() const {
|
||||
assert(is_numeral());
|
||||
Z3_ast r = Z3_get_numerator(ctx(), m_ast);
|
||||
check_error();
|
||||
return expr(ctx(),r);
|
||||
}
|
||||
|
||||
|
||||
expr denominator() const {
|
||||
assert(is_numeral());
|
||||
Z3_ast r = Z3_get_denominator(ctx(), m_ast);
|
||||
check_error();
|
||||
return expr(ctx(),r);
|
||||
}
|
||||
|
||||
operator Z3_app() const { assert(is_app()); return reinterpret_cast<Z3_app>(m_ast); }
|
||||
|
||||
|
@ -875,13 +895,23 @@ namespace z3 {
|
|||
friend expr operator*(expr const & a, int b);
|
||||
friend expr operator*(int a, expr const & b);
|
||||
|
||||
/**
|
||||
\brief Power operator
|
||||
*/
|
||||
/* \brief Power operator */
|
||||
friend expr pw(expr const & a, expr const & b);
|
||||
friend expr pw(expr const & a, int b);
|
||||
friend expr pw(int a, expr const & b);
|
||||
|
||||
/* \brief mod operator */
|
||||
friend expr mod(expr const& a, expr const& b);
|
||||
friend expr mod(expr const& a, int b);
|
||||
friend expr mod(int a, expr const& b);
|
||||
|
||||
/* \brief rem operator */
|
||||
friend expr rem(expr const& a, expr const& b);
|
||||
friend expr rem(expr const& a, int b);
|
||||
friend expr rem(int a, expr const& b);
|
||||
|
||||
friend expr is_int(expr const& e);
|
||||
|
||||
friend expr operator/(expr const & a, expr const & b);
|
||||
friend expr operator/(expr const & a, int b);
|
||||
friend expr operator/(int a, expr const & b);
|
||||
|
@ -964,6 +994,17 @@ namespace z3 {
|
|||
check_error();
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
expr stoi() const {
|
||||
Z3_ast r = Z3_mk_str_to_int(ctx(), *this);
|
||||
check_error();
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
expr itos() const {
|
||||
Z3_ast r = Z3_mk_int_to_str(ctx(), *this);
|
||||
check_error();
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
|
||||
friend expr range(expr const& lo, expr const& hi);
|
||||
/**
|
||||
\brief create a looping regular expression.
|
||||
|
@ -1001,34 +1042,46 @@ namespace z3 {
|
|||
|
||||
};
|
||||
|
||||
#define _Z3_MK_BIN_(a, b, binop) \
|
||||
check_context(a, b); \
|
||||
Z3_ast r = binop(a.ctx(), a, b); \
|
||||
a.check_error(); \
|
||||
return expr(a.ctx(), r); \
|
||||
|
||||
|
||||
inline expr implies(expr const & a, expr const & b) {
|
||||
check_context(a, b);
|
||||
assert(a.is_bool() && b.is_bool());
|
||||
Z3_ast r = Z3_mk_implies(a.ctx(), a, b);
|
||||
a.check_error();
|
||||
return expr(a.ctx(), r);
|
||||
assert(a.is_bool() && b.is_bool());
|
||||
_Z3_MK_BIN_(a, b, Z3_mk_implies);
|
||||
}
|
||||
inline expr implies(expr const & a, bool b) { return implies(a, a.ctx().bool_val(b)); }
|
||||
inline expr implies(bool a, expr const & b) { return implies(b.ctx().bool_val(a), b); }
|
||||
|
||||
|
||||
inline expr pw(expr const & a, expr const & b) {
|
||||
assert(a.is_arith() && b.is_arith());
|
||||
check_context(a, b);
|
||||
Z3_ast r = Z3_mk_power(a.ctx(), a, b);
|
||||
a.check_error();
|
||||
return expr(a.ctx(), r);
|
||||
}
|
||||
inline expr pw(expr const & a, expr const & b) { _Z3_MK_BIN_(a, b, Z3_mk_power); }
|
||||
inline expr pw(expr const & a, int b) { return pw(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr pw(int a, expr const & b) { return pw(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
inline expr mod(expr const& a, expr const& b) { _Z3_MK_BIN_(a, b, Z3_mk_mod); }
|
||||
inline expr mod(expr const & a, int b) { return mod(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr mod(int a, expr const & b) { return mod(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
inline expr operator!(expr const & a) {
|
||||
assert(a.is_bool());
|
||||
Z3_ast r = Z3_mk_not(a.ctx(), a);
|
||||
a.check_error();
|
||||
return expr(a.ctx(), r);
|
||||
}
|
||||
inline expr rem(expr const& a, expr const& b) { _Z3_MK_BIN_(a, b, Z3_mk_rem); }
|
||||
inline expr rem(expr const & a, int b) { return rem(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr rem(int a, expr const & b) { return rem(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
#undef _Z3_MK_BIN_
|
||||
|
||||
#define _Z3_MK_UN_(a, mkun) \
|
||||
Z3_ast r = mkun(a.ctx(), a); \
|
||||
a.check_error(); \
|
||||
return expr(a.ctx(), r); \
|
||||
|
||||
|
||||
inline expr operator!(expr const & a) { assert(a.is_bool()); _Z3_MK_UN_(a, Z3_mk_not); }
|
||||
|
||||
inline expr is_int(expr const& e) { _Z3_MK_UN_(e, Z3_mk_is_int); }
|
||||
|
||||
#undef _Z3_MK_UN_
|
||||
|
||||
inline expr operator&&(expr const & a, expr const & b) {
|
||||
check_context(a, b);
|
||||
|
|
|
@ -2420,6 +2420,29 @@ namespace Microsoft.Z3
|
|||
return new SeqExpr(this, Native.Z3_mk_string(nCtx, s));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert an integer expression to a string.
|
||||
/// </summary>
|
||||
public SeqExpr IntToString(Expr e)
|
||||
{
|
||||
Contract.Requires(e != null);
|
||||
Contract.Requires(e is ArithExpr);
|
||||
Contract.Ensures(Contract.Result<SeqExpr>() != null);
|
||||
return new SeqExpr(this, Native.Z3_mk_int_to_str(nCtx, e.NativeObject));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert an integer expression to a string.
|
||||
/// </summary>
|
||||
public IntExpr StringToInt(Expr e)
|
||||
{
|
||||
Contract.Requires(e != null);
|
||||
Contract.Requires(e is SeqExpr);
|
||||
Contract.Ensures(Contract.Result<IntExpr>() != null);
|
||||
return new IntExpr(this, Native.Z3_mk_str_to_int(nCtx, e.NativeObject));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Concatentate sequences.
|
||||
/// </summary>
|
||||
|
|
|
@ -868,6 +868,9 @@ class ExprRef(AstRef):
|
|||
_args, sz = _to_ast_array((a, b))
|
||||
return BoolRef(Z3_mk_distinct(self.ctx_ref(), 2, _args), self.ctx)
|
||||
|
||||
def params(self):
|
||||
return self.decl().params()
|
||||
|
||||
def decl(self):
|
||||
"""Return the Z3 function declaration associated with a Z3 application.
|
||||
|
||||
|
@ -1011,6 +1014,7 @@ def _coerce_exprs(a, b, ctx=None):
|
|||
b = s.cast(b)
|
||||
return (a, b)
|
||||
|
||||
|
||||
def _reduce(f, l, a):
|
||||
r = a
|
||||
for e in l:
|
||||
|
@ -1296,7 +1300,7 @@ class BoolSortRef(SortRef):
|
|||
if isinstance(val, bool):
|
||||
return BoolVal(val, self.ctx)
|
||||
if __debug__:
|
||||
_z3_assert(is_expr(val), "True, False or Z3 Boolean expression expected")
|
||||
_z3_assert(is_expr(val), "True, False or Z3 Boolean expression expected. Received %s" % val)
|
||||
_z3_assert(self.eq(val.sort()), "Value cannot be converted into a Z3 Boolean value")
|
||||
return val
|
||||
|
||||
|
@ -2012,7 +2016,7 @@ class ArithSortRef(SortRef):
|
|||
if self.is_real():
|
||||
return RealVal(val, self.ctx)
|
||||
if __debug__:
|
||||
_z3_assert(False, "int, long, float, string (numeral), or Z3 Integer/Real expression expected")
|
||||
_z3_assert(False, "int, long, float, string (numeral), or Z3 Integer/Real expression expected. Got %s" % self)
|
||||
|
||||
def is_arith_sort(s):
|
||||
"""Return `True` if s is an arithmetical sort (type).
|
||||
|
@ -9660,6 +9664,29 @@ def Length(s):
|
|||
s = _coerce_seq(s)
|
||||
return ArithRef(Z3_mk_seq_length(s.ctx_ref(), s.as_ast()), s.ctx)
|
||||
|
||||
def StrToInt(s):
|
||||
"""Convert string expression to integer
|
||||
>>> a = StrToInt("1")
|
||||
>>> simplify(1 == a)
|
||||
True
|
||||
>>> b = StrToInt("2")
|
||||
>>> simplify(1 == b)
|
||||
False
|
||||
>>> c = StrToInt(IntToStr(2))
|
||||
>>> simplify(1 == c)
|
||||
False
|
||||
"""
|
||||
s = _coerce_seq(s)
|
||||
return ArithRef(Z3_mk_str_to_int(s.ctx_ref(), s.as_ast()), s.ctx)
|
||||
|
||||
|
||||
def IntToStr(s):
|
||||
"""Convert integer expression to string"""
|
||||
if not is_expr(s):
|
||||
s = _py2expr(s)
|
||||
return SeqRef(Z3_mk_int_to_str(s.ctx_ref(), s.as_ast()), s.ctx)
|
||||
|
||||
|
||||
def Re(s, ctx=None):
|
||||
"""The regular expression that accepts sequence 's'
|
||||
>>> s1 = Re("ab")
|
||||
|
|
|
@ -1152,6 +1152,10 @@ typedef enum {
|
|||
Z3_OP_SEQ_TO_RE,
|
||||
Z3_OP_SEQ_IN_RE,
|
||||
|
||||
// strings
|
||||
Z3_OP_STR_TO_INT,
|
||||
Z3_OP_INT_TO_STR,
|
||||
|
||||
// regular expressions
|
||||
Z3_OP_RE_PLUS,
|
||||
Z3_OP_RE_STAR,
|
||||
|
@ -3325,6 +3329,21 @@ extern "C" {
|
|||
*/
|
||||
Z3_ast Z3_API Z3_mk_seq_index(Z3_context c, Z3_ast s, Z3_ast substr, Z3_ast offset);
|
||||
|
||||
/**
|
||||
\brief Convert string to integer.
|
||||
|
||||
def_API('Z3_mk_str_to_int' ,AST ,(_in(CONTEXT), _in(AST)))
|
||||
*/
|
||||
Z3_ast Z3_API Z3_mk_str_to_int(Z3_context c, Z3_ast s);
|
||||
|
||||
|
||||
/**
|
||||
\brief Integer to string conversion.
|
||||
|
||||
def_API('Z3_mk_int_to_str' ,AST ,(_in(CONTEXT), _in(AST)))
|
||||
*/
|
||||
Z3_ast Z3_API Z3_mk_int_to_str(Z3_context c, Z3_ast s);
|
||||
|
||||
/**
|
||||
\brief Create a regular expression that accepts the sequence \c seq.
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue