mirror of
https://github.com/Z3Prover/z3
synced 2025-04-25 18:15:32 +00:00
use regex instead of head/tail split for string-integer conversion; check sort of refreshed vars; add intersection difficulty estimation
This commit is contained in:
parent
c01dda4e31
commit
1ee5ce96b8
2 changed files with 18 additions and 9 deletions
|
@ -287,11 +287,14 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void theory_str::refresh_theory_var(expr * e) {
|
void theory_str::refresh_theory_var(expr * e) {
|
||||||
|
ast_manager & m = get_manager();
|
||||||
enode * en = ensure_enode(e);
|
enode * en = ensure_enode(e);
|
||||||
theory_var v = mk_var(en); (void)v;
|
theory_var v = mk_var(en); (void)v;
|
||||||
TRACE("str", tout << "refresh " << mk_pp(e, get_manager()) << ": v#" << v << std::endl;);
|
TRACE("str", tout << "refresh " << mk_pp(e, get_manager()) << ": v#" << v << std::endl;);
|
||||||
|
if (m.get_sort(e) == u.str.mk_string_sort()) {
|
||||||
m_basicstr_axiom_todo.push_back(en);
|
m_basicstr_axiom_todo.push_back(en);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
theory_var theory_str::mk_var(enode* n) {
|
theory_var theory_str::mk_var(enode* n) {
|
||||||
TRACE("str", tout << "mk_var for " << mk_pp(n->get_owner(), get_manager()) << std::endl;);
|
TRACE("str", tout << "mk_var for " << mk_pp(n->get_owner(), get_manager()) << std::endl;);
|
||||||
|
@ -1628,12 +1631,11 @@ namespace smt {
|
||||||
|
|
||||||
{
|
{
|
||||||
expr_ref premise(m_autil.mk_ge(ex, m_autil.mk_numeral(rational::one(), true)), m);
|
expr_ref premise(m_autil.mk_ge(ex, m_autil.mk_numeral(rational::one(), true)), m);
|
||||||
expr_ref hd(mk_str_var("hd"), m);
|
// S >= 1 --> S in [1-9][0-9]*
|
||||||
expr_ref tl(mk_str_var("tl"), m);
|
expr_ref re_positiveInteger(u.re.mk_concat(
|
||||||
expr_ref conclusion1(ctx.mk_eq_atom(S, mk_concat(hd, tl)), m);
|
u.re.mk_range(mk_string("1"), mk_string("9")),
|
||||||
expr_ref conclusion2(ctx.mk_eq_atom(mk_strlen(hd), m_autil.mk_numeral(rational::one(), true)), m);
|
u.re.mk_star(u.re.mk_range(mk_string("0"), mk_string("9")))), m);
|
||||||
expr_ref conclusion3(mk_not(m, ctx.mk_eq_atom(hd, mk_string("0"))), m);
|
expr_ref conclusion(mk_RegexIn(S, re_positiveInteger), m);
|
||||||
expr_ref conclusion(m.mk_and(conclusion1, conclusion2, conclusion3), m);
|
|
||||||
SASSERT(premise);
|
SASSERT(premise);
|
||||||
SASSERT(conclusion);
|
SASSERT(conclusion);
|
||||||
assert_implication(premise, conclusion);
|
assert_implication(premise, conclusion);
|
||||||
|
@ -6614,6 +6616,12 @@ namespace smt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned theory_str::estimate_automata_intersection_difficulty(eautomaton * aut1, eautomaton * aut2) {
|
||||||
|
ENSURE(aut1 != NULL);
|
||||||
|
ENSURE(aut2 != NULL);
|
||||||
|
return _qmul(aut1->num_states(), aut2->num_states());
|
||||||
|
}
|
||||||
|
|
||||||
// Check whether a regex translates well to a linear set of length constraints.
|
// Check whether a regex translates well to a linear set of length constraints.
|
||||||
bool theory_str::check_regex_length_linearity(expr * re) {
|
bool theory_str::check_regex_length_linearity(expr * re) {
|
||||||
return check_regex_length_linearity_helper(re, false);
|
return check_regex_length_linearity_helper(re, false);
|
||||||
|
@ -10291,7 +10299,6 @@ namespace smt {
|
||||||
} else {
|
} else {
|
||||||
// TODO check negation?
|
// TODO check negation?
|
||||||
// TODO construct a partial automaton for R to the given lower bound?
|
// TODO construct a partial automaton for R to the given lower bound?
|
||||||
// TODO increment failure count
|
|
||||||
if (false) {
|
if (false) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -10424,7 +10431,8 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regex_get_counter(regex_length_attempt_count, aut.get_regex_term()) >= m_params.m_RegexAutomata_LengthAttemptThreshold) {
|
if (regex_get_counter(regex_length_attempt_count, aut.get_regex_term()) >= m_params.m_RegexAutomata_LengthAttemptThreshold) {
|
||||||
unsigned intersectionDifficulty = 0; // TODO EstimateIntersectionDifficulty
|
unsigned intersectionDifficulty = estimate_automata_intersection_difficulty(aut_inter, aut.get_automaton());
|
||||||
|
TRACE("str", tout << "intersection difficulty is " << intersectionDifficulty << std::endl;);
|
||||||
if (intersectionDifficulty <= m_params.m_RegexAutomata_IntersectionDifficultyThreshold
|
if (intersectionDifficulty <= m_params.m_RegexAutomata_IntersectionDifficultyThreshold
|
||||||
|| regex_get_counter(regex_intersection_fail_count, aut.get_regex_term()) >= m_params.m_RegexAutomata_FailedIntersectionThreshold) {
|
|| regex_get_counter(regex_intersection_fail_count, aut.get_regex_term()) >= m_params.m_RegexAutomata_FailedIntersectionThreshold) {
|
||||||
|
|
||||||
|
|
|
@ -555,6 +555,7 @@ protected:
|
||||||
// regex automata and length-aware regex
|
// regex automata and length-aware regex
|
||||||
unsigned estimate_regex_complexity(expr * re);
|
unsigned estimate_regex_complexity(expr * re);
|
||||||
unsigned estimate_regex_complexity_under_complement(expr * re);
|
unsigned estimate_regex_complexity_under_complement(expr * re);
|
||||||
|
unsigned estimate_automata_intersection_difficulty(eautomaton * aut1, eautomaton * aut2);
|
||||||
bool check_regex_length_linearity(expr * re);
|
bool check_regex_length_linearity(expr * re);
|
||||||
bool check_regex_length_linearity_helper(expr * re, bool already_star);
|
bool check_regex_length_linearity_helper(expr * re, bool already_star);
|
||||||
expr_ref infer_all_regex_lengths(expr * lenVar, expr * re, expr_ref_vector & freeVariables);
|
expr_ref infer_all_regex_lengths(expr * lenVar, expr * re, expr_ref_vector & freeVariables);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue