mirror of
https://github.com/Z3Prover/z3
synced 2025-04-27 02:45:51 +00:00
completing user print experience with seq/re #2200
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
fca8ffd948
commit
dc0e9c1919
9 changed files with 115 additions and 11 deletions
|
@ -609,6 +609,10 @@ def _to_sort_ref(s, ctx):
|
|||
return FPSortRef(s, ctx)
|
||||
elif k == Z3_ROUNDING_MODE_SORT:
|
||||
return FPRMSortRef(s, ctx)
|
||||
elif k == Z3_RE_SORT:
|
||||
return ReSortRef(s, ctx)
|
||||
elif k == Z3_SEQ_SORT:
|
||||
return SeqSortRef(s, ctx)
|
||||
return SortRef(s, ctx)
|
||||
|
||||
def _sort(ctx, a):
|
||||
|
@ -9908,6 +9912,9 @@ class SeqSortRef(SortRef):
|
|||
False
|
||||
"""
|
||||
return Z3_is_string_sort(self.ctx_ref(), self.ast)
|
||||
|
||||
def basis(self):
|
||||
return _to_sort_ref(Z3_get_seq_sort_basis(self.ctx_ref(), self.ast), self.ctx)
|
||||
|
||||
|
||||
def StringSort(ctx=None):
|
||||
|
@ -10062,7 +10069,7 @@ def Full(s):
|
|||
re.all
|
||||
>>> e1 = Full(ReSort(StringSort()))
|
||||
>>> print(e1)
|
||||
re.all
|
||||
rel.all
|
||||
"""
|
||||
if isinstance(s, ReSortRef):
|
||||
return ReRef(Z3_mk_re_full(s.ctx_ref(), s.ast), s.ctx)
|
||||
|
@ -10212,6 +10219,8 @@ def Re(s, ctx=None):
|
|||
class ReSortRef(SortRef):
|
||||
"""Regular expression sort."""
|
||||
|
||||
def basis(self):
|
||||
return _to_sort_ref(Z3_get_re_sort_basis(self.ctx_ref(), self.ast), self.ctx)
|
||||
|
||||
def ReSort(s):
|
||||
if is_ast(s):
|
||||
|
@ -10228,7 +10237,6 @@ class ReRef(ExprRef):
|
|||
def __add__(self, other):
|
||||
return Union(self, other)
|
||||
|
||||
|
||||
def is_re(s):
|
||||
return isinstance(s, ReRef)
|
||||
|
||||
|
@ -10265,6 +10273,24 @@ def Union(*args):
|
|||
v[i] = args[i].as_ast()
|
||||
return ReRef(Z3_mk_re_union(ctx.ref(), sz, v), ctx)
|
||||
|
||||
def Intersect(*args):
|
||||
"""Create intersection of regular expressions.
|
||||
>>> re = Intersect(Re("a"), Re("b"), Re("c"))
|
||||
Intersect(Re("a"), Re("b"), Re("c"))
|
||||
"""
|
||||
args = _get_args(args)
|
||||
sz = len(args)
|
||||
if __debug__:
|
||||
_z3_assert(sz > 0, "At least one argument expected.")
|
||||
_z3_assert(all([is_re(a) for a in args]), "All arguments must be regular expressions.")
|
||||
if sz == 1:
|
||||
return args[0]
|
||||
ctx = args[0].ctx
|
||||
v = (Ast * sz)()
|
||||
for i in range(sz):
|
||||
v[i] = args[i].as_ast()
|
||||
return ReRef(Z3_mk_re_intersect(ctx.ref(), sz, v), ctx)
|
||||
|
||||
def Plus(re):
|
||||
"""Create the regular expression accepting one or more repetitions of argument.
|
||||
>>> re = Plus(Re("a"))
|
||||
|
|
|
@ -36,7 +36,15 @@ _z3_op_to_str = {
|
|||
Z3_OP_CONCAT : 'Concat', Z3_OP_EXTRACT : 'Extract', Z3_OP_BV2INT : 'BV2Int',
|
||||
Z3_OP_ARRAY_MAP : 'Map', Z3_OP_SELECT : 'Select', Z3_OP_STORE : 'Store',
|
||||
Z3_OP_CONST_ARRAY : 'K', Z3_OP_ARRAY_EXT : 'Ext',
|
||||
Z3_OP_PB_AT_MOST : 'AtMost', Z3_OP_PB_LE : 'PbLe', Z3_OP_PB_GE : 'PbGe', Z3_OP_PB_EQ : 'PbEq'
|
||||
Z3_OP_PB_AT_MOST : 'AtMost', Z3_OP_PB_LE : 'PbLe', Z3_OP_PB_GE : 'PbGe', Z3_OP_PB_EQ : 'PbEq',
|
||||
Z3_OP_SEQ_CONCAT : 'Concat', Z3_OP_SEQ_PREFIX : 'PrefixOf', Z3_OP_SEQ_SUFFIX : 'SuffixOf',
|
||||
Z3_OP_SEQ_UNIT : 'Unit', Z3_OP_SEQ_CONTAINS : 'Contains' , Z3_OP_SEQ_REPLACE : 'Replace',
|
||||
Z3_OP_SEQ_AT : 'At', Z3_OP_SEQ_NTH : 'Nth', Z3_OP_SEQ_INDEX : 'IndexOf',
|
||||
Z3_OP_SEQ_LAST_INDEX : 'LastIndexOf', Z3_OP_SEQ_LENGTH : 'Length', Z3_OP_STR_TO_INT : 'StrToInt', Z3_OP_INT_TO_STR : 'IntToStr',
|
||||
Z3_OP_SEQ_IN_RE : 'InRe', Z3_OP_SEQ_TO_RE : 'Re',
|
||||
Z3_OP_RE_PLUS : 'Plus', Z3_OP_RE_STAR : 'Star', Z3_OP_RE_OPTION : 'Option', Z3_OP_RE_UNION : 'Union', Z3_OP_RE_RANGE : 'Range',
|
||||
Z3_OP_RE_INTERSECT : 'Intersect', Z3_OP_RE_COMPLEMENT : 'Complement',
|
||||
|
||||
}
|
||||
|
||||
# List of infix operators
|
||||
|
@ -486,7 +494,7 @@ class PP:
|
|||
|
||||
def pp(self, f, indent):
|
||||
if isinstance(f, str):
|
||||
sef.pp_string(f, indent)
|
||||
self.pp_string(f, indent)
|
||||
elif f.is_string():
|
||||
self.pp_string(f, indent)
|
||||
elif f.is_indent():
|
||||
|
@ -558,10 +566,23 @@ class Formatter:
|
|||
return seq1('BitVec', (to_format(s.size()), ))
|
||||
elif isinstance(s, z3.FPSortRef):
|
||||
return seq1('FPSort', (to_format(s.ebits()), to_format(s.sbits())))
|
||||
elif isinstance(s, z3.ReSortRef):
|
||||
return seq1('ReSort', (self.pp_sort(s.basis()), ))
|
||||
elif isinstance(s, z3.SeqSortRef):
|
||||
if s.is_string():
|
||||
return to_format("String")
|
||||
return seq1('Seq', (self.pp_sort(s.basis()), ))
|
||||
else:
|
||||
return to_format(s.name())
|
||||
|
||||
def pp_const(self, a):
|
||||
k = a.decl().kind()
|
||||
if k == Z3_OP_RE_EMPTY_SET:
|
||||
return self.pp_set("Empty", a)
|
||||
elif k == Z3_OP_SEQ_EMPTY:
|
||||
return self.pp_set("Empty", a)
|
||||
elif k == Z3_OP_RE_FULL_SET:
|
||||
return self.pp_set("Full", a)
|
||||
return self.pp_name(a)
|
||||
|
||||
def pp_int(self, a):
|
||||
|
@ -577,7 +598,7 @@ class Formatter:
|
|||
return to_format(a.as_decimal(self.precision))
|
||||
|
||||
def pp_string(self, a):
|
||||
return to_format(a.as_string())
|
||||
return to_format("\"" + a.as_string() + "\"")
|
||||
|
||||
def pp_bv(self, a):
|
||||
return to_format(a.as_string())
|
||||
|
@ -842,6 +863,17 @@ class Formatter:
|
|||
arg = self.pp_expr(a.arg(0), d+1, xs)
|
||||
return seq1(self.pp_name(a), [ to_format(h), to_format(l), arg ])
|
||||
|
||||
def pp_loop(self, a, d, xs):
|
||||
l = Z3_get_decl_int_parameter(a.ctx_ref(), a.decl().ast, 0)
|
||||
arg = self.pp_expr(a.arg(0), d+1, xs)
|
||||
if Z3_get_decl_num_parameters(a.ctx_ref(), a.decl().ast) > 1:
|
||||
h = Z3_get_decl_int_parameter(a.ctx_ref(), a.decl().ast, 1)
|
||||
return seq1("Loop", [ arg, to_format(l), to_format(h) ])
|
||||
return seq1("Loop", [ arg, to_format(l) ])
|
||||
|
||||
def pp_set(self, id, a):
|
||||
return seq1(id, [self.pp_sort(a.sort())])
|
||||
|
||||
def pp_pattern(self, a, d, xs):
|
||||
if a.num_args() == 1:
|
||||
return self.pp_expr(a.arg(0), d, xs)
|
||||
|
@ -918,6 +950,8 @@ class Formatter:
|
|||
return self.pp_unary_param(a, d, xs)
|
||||
elif k == Z3_OP_EXTRACT:
|
||||
return self.pp_extract(a, d, xs)
|
||||
elif k == Z3_OP_RE_LOOP:
|
||||
return self.pp_loop(a, d, xs)
|
||||
elif k == Z3_OP_DT_IS:
|
||||
return self.pp_is(a, d, xs)
|
||||
elif k == Z3_OP_ARRAY_MAP:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue