@@ -33,7 +33,7 @@ Author: Alberto Griggio, alberto.griggio@gmail.com
3333static bool is_valid_string_constraint (
3434 messaget::mstreamt &stream,
3535 const namespacet &ns,
36- const string_constraintt &expr );
36+ const string_constraintt &constraint );
3737
3838static optionalt<exprt> find_counter_example (
3939 const namespacet &ns,
@@ -697,7 +697,7 @@ decision_proceduret::resultt string_refinementt::dec_solve()
697697 constraints.end (),
698698 std::back_inserter (axioms.universal ),
699699 [&](string_constraintt constraint) {
700- symbol_resolve .replace_expr (constraint );
700+ constraint .replace_expr (symbol_resolve );
701701 DATA_INVARIANT (
702702 is_valid_string_constraint (error (), ns, constraint),
703703 string_refinement_invariantt (
@@ -1238,34 +1238,23 @@ static exprt negation_of_not_contains_constraint(
12381238
12391239// / Debugging function which outputs the different steps an axiom goes through
12401240// / to be checked in check axioms.
1241+ // / \tparam T: can be either string_constraintt or
1242+ // / string_not_contains_constraintt
1243+ template <typename T>
12411244static void debug_check_axioms_step (
12421245 messaget::mstreamt &stream,
12431246 const namespacet &ns,
1244- const exprt &axiom,
1245- const exprt &axiom_in_model,
1247+ const T &axiom,
1248+ const T &axiom_in_model,
12461249 const exprt &negaxiom,
12471250 const exprt &with_concretized_arrays)
12481251{
12491252 static const std::string indent = " " ;
12501253 static const std::string indent2 = " " ;
12511254 stream << indent2 << " - axiom:\n " << indent2 << indent;
1252-
1253- if (axiom.id () == ID_string_constraint)
1254- stream << to_string (to_string_constraint (axiom));
1255- else if (axiom.id () == ID_string_not_contains_constraint)
1256- stream << to_string (to_string_not_contains_constraint (axiom));
1257- else
1258- stream << format (axiom);
1255+ stream << to_string (axiom);
12591256 stream << ' \n ' << indent2 << " - axiom_in_model:\n " << indent2 << indent;
1260-
1261- if (axiom_in_model.id () == ID_string_constraint)
1262- stream << to_string (to_string_constraint (axiom_in_model));
1263- else if (axiom_in_model.id () == ID_string_not_contains_constraint)
1264- stream << to_string (to_string_not_contains_constraint (axiom_in_model));
1265- else
1266- stream << format (axiom_in_model);
1267-
1268- stream << ' \n '
1257+ stream << to_string (axiom_in_model) << ' \n '
12691258 << indent2 << " - negated_axiom:\n "
12701259 << indent2 << indent << format (negaxiom) << ' \n ' ;
12711260 stream << indent2 << " - negated_axiom_with_concretized_arrays:\n "
@@ -1322,16 +1311,11 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
13221311 for (size_t i=0 ; i<axioms.universal .size (); i++)
13231312 {
13241313 const string_constraintt &axiom=axioms.universal [i];
1325- const symbol_exprt &univ_var=axiom.univ_var ();
1326- const exprt &bound_inf=axiom.lower_bound ();
1327- const exprt &bound_sup=axiom.upper_bound ();
1328- const exprt &prem=axiom.premise ();
1329- INVARIANT (
1330- prem == true_exprt (), " string constraint premises are not supported" );
1331- const exprt &body=axiom.body ();
1332-
13331314 const string_constraintt axiom_in_model (
1334- univ_var, get (bound_inf), get (bound_sup), get (body));
1315+ axiom.univ_var ,
1316+ get (axiom.lower_bound ),
1317+ get (axiom.upper_bound ),
1318+ get (axiom.body ));
13351319
13361320 exprt negaxiom = axiom_in_model.negation ();
13371321 negaxiom = simplify_expr (negaxiom, ns);
@@ -1342,11 +1326,12 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
13421326 debug_check_axioms_step (
13431327 stream, ns, axiom, axiom_in_model, negaxiom, with_concretized_arrays);
13441328
1345- if (const auto &witness=
1346- find_counter_example (ns, ui, with_concretized_arrays, univ_var))
1329+ if (
1330+ const auto &witness =
1331+ find_counter_example (ns, ui, with_concretized_arrays, axiom.univ_var ))
13471332 {
1348- stream << indent2 << " - violated_for: " << univ_var. get_identifier ()
1349- << " = " << format (*witness) << eom;
1333+ stream << indent2 << " - violated_for: " << format (axiom. univ_var ) << " = "
1334+ << format (*witness) << eom;
13501335 violated[i]=*witness;
13511336 }
13521337 else
@@ -1402,13 +1387,13 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
14021387 const exprt &val=v.second ;
14031388 const string_constraintt &axiom=axioms.universal [v.first ];
14041389
1405- implies_exprt instance (axiom.premise (), axiom. body () );
1406- replace_expr (axiom.univ_var () , val, instance);
1390+ exprt instance (axiom.body );
1391+ replace_expr (axiom.univ_var , val, instance);
14071392 // We are not sure the index set contains only positive numbers
14081393 and_exprt bounds (
14091394 axiom.univ_within_bounds (),
14101395 binary_relation_exprt (from_integer (0 , val.type ()), ID_le, val));
1411- replace_expr (axiom.univ_var () , val, bounds);
1396+ replace_expr (axiom.univ_var , val, bounds);
14121397 const implies_exprt counter (bounds, instance);
14131398 lemmas.push_back (counter);
14141399 }
@@ -1766,10 +1751,10 @@ static void initial_index_set(
17661751 const namespacet &ns,
17671752 const string_constraintt &axiom)
17681753{
1769- const symbol_exprt &qvar= axiom.univ_var () ;
1770- const auto &bound = axiom.upper_bound () ;
1771- auto it = axiom.body () .depth_begin ();
1772- const auto end = axiom.body () .depth_end ();
1754+ const symbol_exprt &qvar = axiom.univ_var ;
1755+ const auto &bound = axiom.upper_bound ;
1756+ auto it = axiom.body .depth_begin ();
1757+ const auto end = axiom.body .depth_end ();
17731758 while (it != end)
17741759 {
17751760 if (it->id () == ID_index && is_char_type (it->type ()))
@@ -1912,18 +1897,17 @@ static exprt instantiate(
19121897 const exprt &str,
19131898 const exprt &val)
19141899{
1915- const optionalt<exprt> idx = find_index (axiom.body () , str, axiom.univ_var () );
1900+ const optionalt<exprt> idx = find_index (axiom.body , str, axiom.univ_var );
19161901 if (!idx.has_value ())
19171902 return true_exprt ();
19181903
1919- const exprt r = compute_inverse_function (stream, axiom.univ_var () , val, *idx);
1904+ const exprt r = compute_inverse_function (stream, axiom.univ_var , val, *idx);
19201905 implies_exprt instance (
19211906 and_exprt (
1922- binary_relation_exprt (axiom.univ_var (), ID_ge, axiom.lower_bound ()),
1923- binary_relation_exprt (axiom.univ_var (), ID_lt, axiom.upper_bound ()),
1924- axiom.premise ()),
1925- axiom.body ());
1926- replace_expr (axiom.univ_var (), r, instance);
1907+ binary_relation_exprt (axiom.univ_var , ID_ge, axiom.lower_bound ),
1908+ binary_relation_exprt (axiom.univ_var , ID_lt, axiom.upper_bound )),
1909+ axiom.body );
1910+ replace_expr (axiom.univ_var , r, instance);
19271911 return instance;
19281912}
19291913
@@ -2175,11 +2159,11 @@ is_linear_arithmetic_expr(const exprt &expr, const symbol_exprt &var)
21752159// / \param [in] expr: The string constraint to check
21762160// / \return true if the universal variable only occurs in index expressions,
21772161// / false otherwise.
2178- static bool universal_only_in_index (const string_constraintt &expr )
2162+ static bool universal_only_in_index (const string_constraintt &constr )
21792163{
2180- for (auto it = expr .body () .depth_begin (); it != expr .body () .depth_end ();)
2164+ for (auto it = constr .body .depth_begin (); it != constr .body .depth_end ();)
21812165 {
2182- if (*it == expr .univ_var () )
2166+ if (*it == constr .univ_var )
21832167 return false ;
21842168 if (it->id () == ID_index)
21852169 it.next_sibling_or_parent ();
@@ -2193,35 +2177,20 @@ static bool universal_only_in_index(const string_constraintt &expr)
21932177// / \related string_constraintt
21942178// / \param stream: message stream
21952179// / \param ns: namespace
2196- // / \param [in] expr : the string constraint to check
2180+ // / \param [in] constraint : the string constraint to check
21972181// / \return whether the constraint satisfies the invariant
21982182static bool is_valid_string_constraint (
21992183 messaget::mstreamt &stream,
22002184 const namespacet &ns,
2201- const string_constraintt &expr )
2185+ const string_constraintt &constraint )
22022186{
22032187 const auto eom=messaget::eom;
2204- // Condition 1: The premise cannot contain any string indices
2205- const array_index_mapt premise_indices=gather_indices (expr.premise ());
2206- if (!premise_indices.empty ())
2207- {
2208- stream << " Premise has indices: " << format (expr) << " , map: {" ;
2209- for (const auto &pair : premise_indices)
2210- {
2211- stream << format (pair.first ) << " : {" ;
2212- for (const auto &i : pair.second )
2213- stream << format (i) << " , " ;
2214- }
2215- stream << " }}" << eom;
2216- return false ;
2217- }
2218-
2219- const array_index_mapt body_indices=gather_indices (expr.body ());
2188+ const array_index_mapt body_indices = gather_indices (constraint.body );
22202189 // Must validate for each string. Note that we have an invariant that the
22212190 // second value in the pair is non-empty.
22222191 for (const auto &pair : body_indices)
22232192 {
2224- // Condition 2 : All indices of the same string must be the of the same form
2193+ // Condition 1 : All indices of the same string must be the of the same form
22252194 const exprt rep=pair.second .back ();
22262195 for (size_t j=0 ; j<pair.second .size ()-1 ; j++)
22272196 {
@@ -2230,25 +2199,26 @@ static bool is_valid_string_constraint(
22302199 const exprt result=simplify_expr (equals, ns);
22312200 if (result.is_false ())
22322201 {
2233- stream << " Indices not equal: " << format (expr )
2202+ stream << " Indices not equal: " << to_string (constraint )
22342203 << " , str: " << format (pair.first ) << eom;
22352204 return false ;
22362205 }
22372206 }
22382207
2239- // Condition 3 : f must be linear in the quantified variable
2240- if (!is_linear_arithmetic_expr (rep, expr .univ_var () ))
2208+ // Condition 2 : f must be linear in the quantified variable
2209+ if (!is_linear_arithmetic_expr (rep, constraint .univ_var ))
22412210 {
2242- stream << " f is not linear: " << format (expr )
2211+ stream << " f is not linear: " << to_string (constraint )
22432212 << " , str: " << format (pair.first ) << eom;
22442213 return false ;
22452214 }
22462215
2247- // Condition 4 : the quantified variable can only occur in indices in the
2216+ // Condition 3 : the quantified variable can only occur in indices in the
22482217 // body
2249- if (!universal_only_in_index (expr ))
2218+ if (!universal_only_in_index (constraint ))
22502219 {
2251- stream << " Universal variable outside of index:" << format (expr) << eom;
2220+ stream << " Universal variable outside of index:" << to_string (constraint)
2221+ << eom;
22522222 return false ;
22532223 }
22542224 }
0 commit comments