3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-08-03 04:33:28 +00:00

add undo trail

This commit is contained in:
Nikolaj Bjorner 2026-08-01 10:09:56 -07:00
parent 516a413559
commit 6e1ca006f1
4 changed files with 48 additions and 10 deletions

View file

@ -24,6 +24,10 @@ TODOs:
- create a validation harness: expose certificates for correctness that can be checked.
- extend with lower and upper bound constraints
- consider using expr_ref as alternative to pinned expressions
- change type of atom to use expr_ref and avoid pin. svector<atom> -> vector<atom>.
- revisit parse_term and "the_var" condition. A sequence of units should be allowed.
- support units of non-values (element variables).
Model construction would assign values to the elements.
- encapsulate within general interface:
create: undo_trail x dependency_manager x ast_manager -> regex_membership
add_constraint : expr* x expr* x dependency* -> void
@ -422,6 +426,7 @@ lbool seq_monadic::decide_dnf(vector<disjunct> const& dnf) {
void seq_monadic::add(expr* term, expr* regex, u_dependency* d) {
m_memberships.push_back({ expr_ref(term, m), expr_ref(regex, m), d });
m_undo_trail.push(push_back_vector(m_memberships));
}
lbool seq_monadic::decide(vector<std::tuple<expr_ref, expr_ref, u_dependency*>> const& memberships) {
@ -493,10 +498,8 @@ void seq_monadic::minimize_core(vector<std::tuple<expr_ref, expr_ref, u_dependen
lbool seq_monadic::check() {
m_core.reset();
vector<std::tuple<expr_ref, expr_ref, u_dependency*>> memberships;
memberships.swap(m_memberships); // consume the asserted memberships
lbool r = decide(memberships);
lbool r = decide(m_memberships);
if (r == l_false)
minimize_core(memberships);
minimize_core(m_memberships);
return r;
}

View file

@ -58,6 +58,7 @@ Author:
#include "util/lbool.h"
#include "util/obj_hashtable.h"
#include "util/dependency.h"
#include "util/trail.h"
#include <utility>
#include <tuple>
@ -73,6 +74,7 @@ private:
seq_rewriter& m_rw;
th_rewriter m_thrw; // normalizes constant-element derivatives (folds
// ground guards so dead states become re.empty)
trail_stack& m_undo_trail;
transition_mode m_mode;
sort* m_seq_sort = nullptr; // sequence sort of the regex under analysis
sort* m_elem_sort = nullptr; // element sort of that sequence sort
@ -153,8 +155,10 @@ private:
void minimize_core(vector<std::tuple<expr_ref, expr_ref, u_dependency*>> const& memberships);
public:
seq_monadic(seq_rewriter& rw, transition_mode mode = transition_mode::light_antimirov) :
m(rw.m()), m_rw(rw), m_thrw(rw.m()), m_mode(mode), m_pin(rw.m()) {}
seq_monadic(seq_rewriter& rw, trail_stack& undo_trail,
transition_mode mode = transition_mode::light_antimirov) :
m(rw.m()), m_rw(rw), m_thrw(rw.m()), m_undo_trail(undo_trail),
m_mode(mode), m_pin(rw.m()) {}
~seq_monadic() { reset_cofactor_cache(); }
@ -181,7 +185,7 @@ public:
// Assert a membership (term in regex) to be decided jointly by the next check().
// `d` carries the dependency used for unsat-core tracking and may be nullptr.
// Memberships accumulate until check() consumes them.
// Memberships remain asserted until the constructor-provided trail is popped.
void add(expr* term, expr* regex, u_dependency* d);
// Decide the CONJUNCTION of all memberships asserted via add() jointly: a variable
@ -190,7 +194,7 @@ public:
// membership solving to a Boolean combination of memberships (a disjunction is the
// union of DNFs; a negated membership ~(t in R) is just t in complement(R)).
// Per-variable extra constraints are expressed as extra memberships (v in R').
// Consumes the asserted memberships. l_true = sat (empty conjunction is sat),
// Leaves the asserted memberships unchanged. l_true = sat (empty conjunction is sat),
// l_false = unsat, l_undef = gave up. On l_false, core() holds the dependencies
// of a minimal unsatisfiable subset.
lbool check();