mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 01:25:31 +00:00
seq API, tuning
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
8e80fb830b
commit
a3c4972c85
3 changed files with 237 additions and 14 deletions
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue