3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-26 18:45:33 +00:00

add facility for incremental parsing #6123

Adding new API object to maintain state between calls to parser.
The state is incremental: all declarations of sorts and functions are valid in the next parse. The parser produces an ast-vector of assertions that are parsed in the current calls.

The following is a unit test:

```
from z3 import *

pc = ParserContext()

A = DeclareSort('A')

pc.add_sort(A)
print(pc.from_string("(declare-const x A) (declare-const y A) (assert (= x y))"))
print(pc.from_string("(declare-const z A) (assert (= x z))"))

print(parse_smt2_string("(declare-const x Int) (declare-const y Int) (assert (= x y))"))

s = Solver()
s.from_string("(declare-sort A)")
s.from_string("(declare-const x A)")
s.from_string("(declare-const y A)")
s.from_string("(assert (= x y))")
print(s.assertions())
s.from_string("(declare-const z A)")
print(s.assertions())
s.from_string("(assert (= x z))")
print(s.assertions())
```

It produces results of the form

```
[x == y]
[x == z]
[x == y]
[x == y]
[x == y]
[x == y, x == z]
```
Thus, the set of assertions returned by a parse call is just the set of assertions added.
The solver maintains state between parser calls so that declarations made in a previous call are still available when declaring the constant 'z'.
The same holds for the parser_context_from_string function: function and sort declarations either added externally or declared using SMTLIB2 command line format as strings are valid for later calls.
This commit is contained in:
Nikolaj Bjorner 2022-07-01 20:27:06 -07:00
parent 8c2ba3d47e
commit 815518dc02
8 changed files with 235 additions and 73 deletions

View file

@ -9192,6 +9192,25 @@ def _dict2darray(decls, ctx):
i = i + 1
return sz, _names, _decls
class ParserContext:
def __init__(self, ctx= None):
self.ctx = _get_ctx(ctx)
self.pctx = Z3_mk_parser_context(self.ctx.ref())
Z3_parser_context_inc_ref(self.ctx.ref(), self.pctx)
def __del__(self):
if self.ctx.ref() is not None and self.pctx is not None and Z3_parser_context_dec_ref is not None:
Z3_parser_context_dec_ref(self.ctx.ref(), self.pctx)
self.pctx = None
def add_sort(self, sort):
Z3_parser_context_add_sort(self.ctx.ref(), self.pctx, sort.as_ast())
def add_decl(self, decl):
Z3_parser_context_add_decl(self.ctx.ref(), self.pctx, decl.as_ast())
def from_string(self, s):
return AstVector(Z3_parser_context_from_string(self.ctx.ref(), self.pctx, s), self.ctx)
def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
"""Parse a string in SMT 2.0 format using the given sorts and decls.

View file

@ -216,6 +216,13 @@ class ParamDescrs(ctypes.c_void_p):
def from_param(obj):
return obj
class ParserContextObj(ctypes.c_void_p):
def __init__(self, pc):
self._as_parameter_ = pc
def from_param(obj):
return obj
class FuncInterpObj(ctypes.c_void_p):
def __init__(self, f):