mirror of
https://github.com/Z3Prover/z3
synced 2025-08-02 01:13:18 +00:00
Integrate new regex solver (#4602)
* std::cout debugging statements * comment out std::cout debugging as this is now a shared fork * convert std::cout to TRACE statements for seq_rewriter and seq_regex * add cases to min_length and max_length for regexes * bug fix * update min_length and max_length functions for REs * initial pass on simplifying derivative normal forms by eliminating redundant predicates locally * add seq_regex_brief trace statements * working on debugging ref count issue * fix ref count bug and convert trace statements to seq_regex_brief * add compact tracing for cache hits/misses * seq_regex fix cache hit/miss tracing and wrapper around is_nullable * minor * label and disable more experimental changes for testing * minor documentation / tracing * a few more @EXP annotations * dead state elimination skeleton code * progress on dead state elimination * more progress on dead state elimination * refactor dead state class to separate self-contained state_graph class * finish factoring state_graph to only work with unsigned values, and implement separate functionality for expr* logic * implement get_all_derivatives, add debug tracing * trace statements for debugging is_nullable loop bug * fix is_nullable loop bug * comment out local nullable change and mark experimental * pretty printing for state_graph * rewrite state graph to remove the fragile assumption that all edges from a state are added at a time * start of general cycle detection check + fix some comments * implement full cycle detection procedure * normalize derivative conditions to form 'ele <= a' * order derivative conditions by character code * fix confusing names m_to and m_from * assign increasing state IDs from 1 instead of using get_id on AST node * remove elim_condition call in get_dall_derivatives * use u_map instead of uint_map to avoid memory leak * remove unnecessary call to is_ground * debugging * small improvements to seq_regex_brief tracing * fix bug on evil2 example * save work * new propagate code * work in progress on using same seq sort for deriv calls * avoid re-computing derivatives: use same head var for every derivative call * use min_length on regexes to prune search * simple implementation of can_be_in_cycle using rank function idea * add a disabled experimental change * minor cleanup comments, etc. * seq_rewriter cleanup for PR * typo noticed by Nikolaj * move state graph to util/state_graph * re-add accidentally removed line * clean up seq_regex code removing obsolete functions and comments * a few more cleanup items * remove experimental functionality for integration * fix compilation * remove some tracing and TODOs * remove old comment * update copyright dates to 2020 * feedback from Nikolaj * use [] for map access * make state_graph methods constant * avoid recursion in mark_dead_recursive and mark_live_recursive * a possible bug fix in propagate_nonempty * write down list of invariants in state_graph * implement partial invariant check and insert CASSERT statements * expand on invariant check and tracing * finish state graph invariant check * minor tweaks * regex propagation: convert first two axioms to propagations * remove obsolete regex solver functionality Co-authored-by: calebstanford-msr <t-casta@microsoft.com>
This commit is contained in:
parent
293b0b8cc2
commit
976e4c91b0
8 changed files with 922 additions and 257 deletions
|
@ -1,5 +1,5 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
Copyright (c) 2020 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
|
@ -17,6 +17,7 @@ Author:
|
|||
#pragma once
|
||||
|
||||
#include "util/scoped_vector.h"
|
||||
#include "util/state_graph.h"
|
||||
#include "ast/seq_decl_plugin.h"
|
||||
#include "ast/rewriter/seq_rewriter.h"
|
||||
#include "smt/smt_context.h"
|
||||
|
@ -27,6 +28,7 @@ namespace smt {
|
|||
class theory_seq;
|
||||
|
||||
class seq_regex {
|
||||
// Data about a constraint of the form (str.in_re s R)
|
||||
struct s_in_re {
|
||||
literal m_lit;
|
||||
expr* m_s;
|
||||
|
@ -36,20 +38,34 @@ namespace smt {
|
|||
m_lit(l), m_s(s), m_re(r), m_active(true) {}
|
||||
};
|
||||
|
||||
struct propagation_lit {
|
||||
literal m_lit;
|
||||
literal m_trigger;
|
||||
propagation_lit(literal lit, literal t): m_lit(lit), m_trigger(t) {}
|
||||
propagation_lit(literal lit): m_lit(lit), m_trigger(null_literal) {}
|
||||
propagation_lit(): m_lit(null_literal), m_trigger(null_literal) {}
|
||||
};
|
||||
theory_seq& th;
|
||||
context& ctx;
|
||||
ast_manager& m;
|
||||
vector<s_in_re> m_s_in_re;
|
||||
|
||||
theory_seq& th;
|
||||
context& ctx;
|
||||
ast_manager& m;
|
||||
vector<s_in_re> m_s_in_re;
|
||||
scoped_vector<propagation_lit> m_to_propagate;
|
||||
/*
|
||||
state_graph for dead state detection, and associated methods
|
||||
*/
|
||||
state_graph m_state_graph;
|
||||
ptr_addr_map<expr, unsigned> m_expr_to_state;
|
||||
expr_ref_vector m_state_to_expr;
|
||||
unsigned m_max_state_graph_size { 10000 };
|
||||
// Convert between expressions and states (IDs)
|
||||
unsigned get_state_id(expr* e);
|
||||
expr* get_expr_from_id(unsigned id);
|
||||
// Cycle-detection heuristic
|
||||
// Note: Doesn't need to be sound or complete (doesn't affect soundness)
|
||||
bool can_be_in_cycle(expr* r1, expr* r2);
|
||||
// Update the graph
|
||||
bool update_state_graph(expr* r);
|
||||
|
||||
// Printing expressions for seq_regex_brief
|
||||
std::string state_str(expr* e);
|
||||
std::string expr_id_str(expr* e);
|
||||
|
||||
/*
|
||||
Solvers and utilities
|
||||
*/
|
||||
seq_util& u();
|
||||
class seq_util::re& re();
|
||||
class seq_util::str& str();
|
||||
|
@ -63,42 +79,32 @@ namespace smt {
|
|||
|
||||
bool coallesce_in_re(literal lit);
|
||||
|
||||
bool propagate(literal lit, literal& trigger);
|
||||
|
||||
bool block_unfolding(literal lit, unsigned i);
|
||||
|
||||
void propagate_nullable(literal lit, expr* s, unsigned idx, expr* r);
|
||||
|
||||
bool propagate_derivative(literal lit, expr* e, expr* s, expr* i, unsigned idx, expr* r, literal& trigger);
|
||||
|
||||
expr_ref mk_first(expr* r, expr* n);
|
||||
|
||||
expr_ref unroll_non_empty(expr* r, expr_mark& seen, unsigned depth);
|
||||
|
||||
bool is_member(expr* r, expr* u);
|
||||
|
||||
expr_ref symmetric_diff(expr* r1, expr* r2);
|
||||
|
||||
expr_ref is_nullable_wrapper(expr* r);
|
||||
expr_ref derivative_wrapper(expr* hd, expr* r);
|
||||
|
||||
void get_cofactors(expr* r, expr_ref_vector& conds, expr_ref_pair_vector& result);
|
||||
|
||||
void get_cofactors(expr* r, expr_ref_pair_vector& result) {
|
||||
expr_ref_vector conds(m);
|
||||
get_cofactors(r, conds, result);
|
||||
}
|
||||
void get_all_derivatives(expr* r, expr_ref_vector& results);
|
||||
|
||||
public:
|
||||
|
||||
seq_regex(theory_seq& th);
|
||||
|
||||
void push_scope() { m_to_propagate.push_scope(); }
|
||||
|
||||
void pop_scope(unsigned num_scopes) { m_to_propagate.pop_scope(num_scopes); }
|
||||
|
||||
bool can_propagate() const;
|
||||
|
||||
bool propagate();
|
||||
void push_scope() {}
|
||||
void pop_scope(unsigned num_scopes) {}
|
||||
bool can_propagate() const { return false; }
|
||||
bool propagate() const { return false; }
|
||||
|
||||
void propagate_in_re(literal lit);
|
||||
|
||||
|
@ -117,4 +123,3 @@ namespace smt {
|
|||
};
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue