mirror of
https://github.com/Z3Prover/z3
synced 2025-04-16 13:58:45 +00:00
z3str3: detect and give up when symbolic automaton construction fails (#4384)
typically this will happen due to non-constant terms in a RegLan expression
This commit is contained in:
parent
ccebd4db59
commit
71ea7287bb
|
@ -8594,7 +8594,10 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
|
||||
solve_regex_automata();
|
||||
if (!solve_regex_automata()) {
|
||||
TRACE("str", tout << "regex engine requested to give up!" << std::endl;);
|
||||
return FC_GIVEUP;
|
||||
}
|
||||
|
||||
bool needToAssignFreeVars = false;
|
||||
expr_ref_vector free_variables(m);
|
||||
|
|
|
@ -623,7 +623,7 @@ protected:
|
|||
void instantiate_axiom_RegexIn(enode * e);
|
||||
|
||||
// regex automata and length-aware regex
|
||||
void solve_regex_automata();
|
||||
bool solve_regex_automata();
|
||||
unsigned estimate_regex_complexity(expr * re);
|
||||
unsigned estimate_regex_complexity_under_complement(expr * re);
|
||||
unsigned estimate_automata_intersection_difficulty(eautomaton * aut1, eautomaton * aut2);
|
||||
|
|
|
@ -46,8 +46,8 @@ namespace smt {
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
void theory_str::solve_regex_automata() {
|
||||
// Returns false if we need to give up solving, e.g. because we found symbolic expressions in an automaton.
|
||||
bool theory_str::solve_regex_automata() {
|
||||
ast_manager & m = get_manager();
|
||||
|
||||
// TODO since heuristics might fail, the "no progress" flag might need to be handled specially here
|
||||
|
@ -216,6 +216,10 @@ namespace smt {
|
|||
CTRACE("str", regex_get_counter(regex_fail_count, str_in_re) >= m_params.m_RegexAutomata_FailedAutomatonThreshold,
|
||||
tout << "failed automaton threshold reached for " << mk_pp(str_in_re, m) << " -- automatically constructing full automaton" << std::endl;);
|
||||
eautomaton * aut = m_mk_aut(re);
|
||||
if (aut == nullptr) {
|
||||
TRACE("str", tout << "ERROR: symbolic automaton construction failed, likely due to non-constant term in regex" << std::endl;);
|
||||
return false;
|
||||
}
|
||||
aut->compress();
|
||||
regex_automata.push_back(aut);
|
||||
regex_automaton_under_assumptions new_aut(re, aut, true);
|
||||
|
@ -354,6 +358,10 @@ namespace smt {
|
|||
bool failureThresholdExceeded = (regex_get_counter(regex_fail_count, str_in_re) >= m_params.m_RegexAutomata_FailedAutomatonThreshold);
|
||||
if (expected_complexity <= m_params.m_RegexAutomata_DifficultyThreshold || failureThresholdExceeded) {
|
||||
eautomaton * aut = m_mk_aut(re);
|
||||
if (aut == nullptr) {
|
||||
TRACE("str", tout << "ERROR: symbolic automaton construction failed, likely due to non-constant term in regex" << std::endl;);
|
||||
return false;
|
||||
}
|
||||
aut->compress();
|
||||
regex_automata.push_back(aut);
|
||||
regex_automaton_under_assumptions new_aut(re, aut, true);
|
||||
|
@ -475,6 +483,10 @@ namespace smt {
|
|||
bool failureThresholdExceeded = (regex_get_counter(regex_fail_count, str_in_re) >= m_params.m_RegexAutomata_FailedAutomatonThreshold);
|
||||
if (expected_complexity <= m_params.m_RegexAutomata_DifficultyThreshold || failureThresholdExceeded) {
|
||||
eautomaton * aut = m_mk_aut(re);
|
||||
if (aut == nullptr) {
|
||||
TRACE("str", tout << "ERROR: symbolic automaton construction failed, likely due to non-constant term in regex" << std::endl;);
|
||||
return false;
|
||||
}
|
||||
aut->compress();
|
||||
regex_automata.push_back(aut);
|
||||
regex_automaton_under_assumptions new_aut(re, aut, true);
|
||||
|
@ -508,6 +520,10 @@ namespace smt {
|
|||
if (expected_complexity <= m_params.m_RegexAutomata_DifficultyThreshold
|
||||
|| failureThresholdExceeded) {
|
||||
eautomaton * aut = m_mk_aut(re);
|
||||
if (aut == nullptr) {
|
||||
TRACE("str", tout << "ERROR: symbolic automaton construction failed, likely due to non-constant term in regex" << std::endl;);
|
||||
return false;
|
||||
}
|
||||
aut->compress();
|
||||
regex_automata.push_back(aut);
|
||||
regex_automaton_under_assumptions new_aut(re, aut, true);
|
||||
|
@ -640,6 +656,10 @@ namespace smt {
|
|||
// need to complement first
|
||||
expr_ref rc(u.re.mk_complement(aut.get_regex_term()), m);
|
||||
eautomaton * aut_c = m_mk_aut(rc);
|
||||
if (aut_c == nullptr) {
|
||||
TRACE("str", tout << "ERROR: symbolic automaton construction failed, likely due to non-constant term in regex" << std::endl;);
|
||||
return false;
|
||||
}
|
||||
regex_automata.push_back(aut_c);
|
||||
// TODO is there any way to build a complement automaton from an existing one?
|
||||
// this discards length information
|
||||
|
@ -713,9 +733,7 @@ namespace smt {
|
|||
regex_axiom_add = true;
|
||||
}
|
||||
} // foreach (entry in regex_terms_by_string)
|
||||
if (regex_axiom_add) {
|
||||
//return FC_CONTINUE;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned theory_str::estimate_regex_complexity(expr * re) {
|
||||
|
|
Loading…
Reference in a new issue