3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-05-12 18:24:43 +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

@ -2203,22 +2203,25 @@ expr_ref_vector cmd_context::tracked_assertions() {
for (unsigned i = 0; i < assertions().size(); ++i) {
expr* an = assertion_names()[i];
expr* asr = assertions()[i];
if (an) {
if (an)
result.push_back(m().mk_implies(an, asr));
}
else {
else
result.push_back(asr);
}
}
}
else {
for (expr * e : assertions()) {
for (expr * e : assertions())
result.push_back(e);
}
}
return result;
}
void cmd_context::reset_tracked_assertions() {
m_assertion_names.reset();
for (expr* a : m_assertions)
m().dec_ref(a);
m_assertions.reset();
}
void cmd_context::display_assertions() {
if (!m_interactive_mode)
@ -2254,9 +2257,8 @@ format_ns::format * cmd_context::pp(sort * s) const {
}
cmd_context::pp_env & cmd_context::get_pp_env() const {
if (m_pp_env.get() == nullptr) {
if (m_pp_env.get() == nullptr)
const_cast<cmd_context*>(this)->m_pp_env = alloc(pp_env, *const_cast<cmd_context*>(this));
}
return *(m_pp_env.get());
}
@ -2314,9 +2316,8 @@ void cmd_context::display_smt2_benchmark(std::ostream & out, unsigned num, expr
out << "(set-logic " << logic << ")" << std::endl;
// collect uninterpreted function declarations
decl_collector decls(m());
for (unsigned i = 0; i < num; i++) {
for (unsigned i = 0; i < num; i++)
decls.visit(assertions[i]);
}
// TODO: display uninterpreted sort decls, and datatype decls.
@ -2342,9 +2343,8 @@ void cmd_context::slow_progress_sample() {
svector<symbol> labels;
m_solver->get_labels(labels);
regular_stream() << "(labels";
for (symbol const& s : labels) {
for (symbol const& s : labels)
regular_stream() << " " << s;
}
regular_stream() << "))" << std::endl;
}

View file

@ -485,6 +485,7 @@ public:
ptr_vector<expr> const& assertions() const { return m_assertions; }
ptr_vector<expr> const& assertion_names() const { return m_assertion_names; }
expr_ref_vector tracked_assertions();
void reset_tracked_assertions();
/**
\brief Hack: consume assertions if there are no scopes.