mirror of
https://github.com/Z3Prover/z3
synced 2026-05-19 16:39:32 +00:00
91 lines
3.4 KiB
C++
91 lines
3.4 KiB
C++
/*++
|
|
Copyright (c) 2026 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
theory_seq_len.h
|
|
|
|
Abstract:
|
|
|
|
Theory solver for sequence length constraints.
|
|
|
|
Handles the theory of sequences (seq_decl_plugin) using partial axiom
|
|
instantiation:
|
|
- Axiomatizes (seq.len S) >= 0 for all sequence variables S.
|
|
- Derives stronger lower/upper bounds on seq.len based on the structure of S.
|
|
- Axiomatizes S in RegEx by extracting semi-linear length constraints from
|
|
the regex. For example, if RegEx is (aa)*, it asserts (seq.len S) = 2*X_s
|
|
where X_s >= 0 is a fresh integer variable.
|
|
- Returns FC_DONE in final_check (incomplete but sound partial solver).
|
|
|
|
Author:
|
|
|
|
Nikolaj Bjorner (nbjorner) 2026-03-10
|
|
|
|
--*/
|
|
#pragma once
|
|
|
|
#include "ast/seq_decl_plugin.h"
|
|
#include "ast/arith_decl_plugin.h"
|
|
#include "model/seq_factory.h"
|
|
#include "smt/smt_theory.h"
|
|
#include "smt/smt_model_generator.h"
|
|
|
|
namespace smt {
|
|
|
|
class theory_seq_len : public theory {
|
|
seq_util m_util;
|
|
arith_util m_autil;
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Virtual overrides required by theory base class
|
|
// -----------------------------------------------------------------------
|
|
bool internalize_atom(app* atom, bool gate_ctx) override;
|
|
bool internalize_term(app* term) override;
|
|
void new_eq_eh(theory_var, theory_var) override {}
|
|
void new_diseq_eh(theory_var, theory_var) override {}
|
|
theory* mk_fresh(context* new_ctx) override;
|
|
char const* get_name() const override { return "seq-len"; }
|
|
void display(std::ostream& out) const override;
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Optional overrides
|
|
// -----------------------------------------------------------------------
|
|
void assign_eh(bool_var v, bool is_true) override;
|
|
final_check_status final_check_eh(unsigned) override { return FC_DONE; }
|
|
void push_scope_eh() override { theory::push_scope_eh(); }
|
|
void pop_scope_eh(unsigned num_scopes) override { theory::pop_scope_eh(num_scopes); }
|
|
void init_model(model_generator& mg) override;
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Axiom generation helpers
|
|
// -----------------------------------------------------------------------
|
|
|
|
// Assert (seq.len e) >= 0.
|
|
void add_length_non_neg(expr* e);
|
|
|
|
// Assert length axioms implied by S in R (when the membership is true).
|
|
// lit is the literal for (S in R).
|
|
void add_regex_length_axioms(expr* s, expr* r, literal lit);
|
|
|
|
// Returns true if the regex r has a fixed length (min==max).
|
|
bool has_fixed_length(expr* r, unsigned& len) const;
|
|
|
|
// Extract semi-linear length constraint for a regex.
|
|
// Returns true if a useful constraint can be extracted.
|
|
// If so, sets:
|
|
// period > 0: lengths are of the form (base + period*k), k >= 0
|
|
// period == 0: length is exactly base
|
|
bool get_length_constraint(expr* r, unsigned& base, unsigned& period) const;
|
|
|
|
// Helper: internalize and get literal for an expr.
|
|
literal mk_literal(expr* e);
|
|
|
|
// Helper: assert a clause (disjunction of literals).
|
|
void assert_axiom(literal_vector& lits);
|
|
|
|
public:
|
|
theory_seq_len(context& ctx);
|
|
};
|
|
|
|
}
|