3232static bool is_valid_string_constraint (
3333 messaget::mstreamt &stream,
3434 const namespacet &ns,
35- const string_constraintt &expr );
35+ const string_constraintt &constraint );
3636
3737static optionalt<exprt> find_counter_example (
3838 const namespacet &ns,
@@ -693,7 +693,7 @@ decision_proceduret::resultt string_refinementt::dec_solve()
693693 constraints.end (),
694694 std::back_inserter (axioms.universal ),
695695 [&](string_constraintt constraint) { // NOLINT
696- symbol_resolve .replace_expr (constraint );
696+ constraint .replace_expr (symbol_resolve );
697697 DATA_INVARIANT (
698698 is_valid_string_constraint (error (), ns, constraint),
699699 string_refinement_invariantt (
@@ -1243,34 +1243,22 @@ static exprt negation_of_not_contains_constraint(
12431243
12441244// / Debugging function which outputs the different steps an axiom goes through
12451245// / to be checked in check axioms.
1246+ // / \tparam T: can be either string_constraintt or string_not_contains_constraintt
1247+ template <typename T>
12461248static void debug_check_axioms_step (
12471249 messaget::mstreamt &stream,
12481250 const namespacet &ns,
1249- const exprt &axiom,
1250- const exprt &axiom_in_model,
1251+ const T &axiom,
1252+ const T &axiom_in_model,
12511253 const exprt &negaxiom,
12521254 const exprt &with_concretized_arrays)
12531255{
12541256 static const std::string indent = " " ;
12551257 static const std::string indent2 = " " ;
12561258 stream << indent2 << " - axiom:\n " << indent2 << indent;
1257-
1258- if (axiom.id () == ID_string_constraint)
1259- stream << to_string (to_string_constraint (axiom));
1260- else if (axiom.id () == ID_string_not_contains_constraint)
1261- stream << to_string (to_string_not_contains_constraint (axiom));
1262- else
1263- stream << format (axiom);
1259+ stream << to_string (axiom);
12641260 stream << ' \n ' << indent2 << " - axiom_in_model:\n " << indent2 << indent;
1265-
1266- if (axiom_in_model.id () == ID_string_constraint)
1267- stream << to_string (to_string_constraint (axiom_in_model));
1268- else if (axiom_in_model.id () == ID_string_not_contains_constraint)
1269- stream << to_string (to_string_not_contains_constraint (axiom_in_model));
1270- else
1271- stream << format (axiom_in_model);
1272-
1273- stream << ' \n '
1261+ stream << to_string (axiom_in_model) << ' \n '
12741262 << indent2 << " - negated_axiom:\n "
12751263 << indent2 << indent << format (negaxiom) << ' \n ' ;
12761264 stream << indent2 << " - negated_axiom_with_concretized_arrays:\n "
@@ -1327,16 +1315,11 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
13271315 for (size_t i=0 ; i<axioms.universal .size (); i++)
13281316 {
13291317 const string_constraintt &axiom=axioms.universal [i];
1330- const symbol_exprt &univ_var=axiom.univ_var ();
1331- const exprt &bound_inf=axiom.lower_bound ();
1332- const exprt &bound_sup=axiom.upper_bound ();
1333- const exprt &prem=axiom.premise ();
1334- INVARIANT (
1335- prem == true_exprt (), " string constraint premises are not supported" );
1336- const exprt &body=axiom.body ();
1337-
13381318 const string_constraintt axiom_in_model (
1339- univ_var, get (bound_inf), get (bound_sup), get (body));
1319+ axiom.univ_var ,
1320+ get (axiom.lower_bound ),
1321+ get (axiom.upper_bound ),
1322+ get (axiom.body ));
13401323
13411324 exprt negaxiom = axiom_in_model.negation ();
13421325 negaxiom = simplify_expr (negaxiom, ns);
@@ -1347,11 +1330,12 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
13471330 debug_check_axioms_step (
13481331 stream, ns, axiom, axiom_in_model, negaxiom, with_concretized_arrays);
13491332
1350- if (const auto &witness=
1351- find_counter_example (ns, ui, with_concretized_arrays, univ_var))
1333+ if (
1334+ const auto &witness =
1335+ find_counter_example (ns, ui, with_concretized_arrays, axiom.univ_var ))
13521336 {
1353- stream << indent2 << " - violated_for: " << univ_var. get_identifier ()
1354- << " = " << format (*witness) << eom;
1337+ stream << indent2 << " - violated_for: " << format (axiom. univ_var ) << " = "
1338+ << format (*witness) << eom;
13551339 violated[i]=*witness;
13561340 }
13571341 else
@@ -1430,13 +1414,13 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
14301414 const exprt &val=v.second ;
14311415 const string_constraintt &axiom=axioms.universal [v.first ];
14321416
1433- implies_exprt instance (axiom.premise (), axiom. body () );
1434- replace_expr (axiom.univ_var () , val, instance);
1417+ exprt instance (axiom.body );
1418+ replace_expr (axiom.univ_var , val, instance);
14351419 // We are not sure the index set contains only positive numbers
14361420 and_exprt bounds (
14371421 axiom.univ_within_bounds (),
14381422 binary_relation_exprt (from_integer (0 , val.type ()), ID_le, val));
1439- replace_expr (axiom.univ_var () , val, bounds);
1423+ replace_expr (axiom.univ_var , val, bounds);
14401424 const implies_exprt counter (bounds, instance);
14411425 lemmas.push_back (counter);
14421426 }
@@ -1794,10 +1778,10 @@ static void initial_index_set(
17941778 const namespacet &ns,
17951779 const string_constraintt &axiom)
17961780{
1797- const symbol_exprt &qvar= axiom.univ_var () ;
1798- const auto &bound = axiom.upper_bound () ;
1799- auto it = axiom.body () .depth_begin ();
1800- const auto end = axiom.body () .depth_end ();
1781+ const symbol_exprt &qvar = axiom.univ_var ;
1782+ const auto &bound = axiom.upper_bound ;
1783+ auto it = axiom.body .depth_begin ();
1784+ const auto end = axiom.body .depth_end ();
18011785 while (it != end)
18021786 {
18031787 if (it->id () == ID_index && is_char_type (it->type ()))
@@ -1940,18 +1924,17 @@ static exprt instantiate(
19401924 const exprt &str,
19411925 const exprt &val)
19421926{
1943- const optionalt<exprt> idx = find_index (axiom.body () , str, axiom.univ_var () );
1927+ const optionalt<exprt> idx = find_index (axiom.body , str, axiom.univ_var );
19441928 if (!idx.has_value ())
19451929 return true_exprt ();
19461930
1947- const exprt r = compute_inverse_function (stream, axiom.univ_var () , val, *idx);
1931+ const exprt r = compute_inverse_function (stream, axiom.univ_var , val, *idx);
19481932 implies_exprt instance (
19491933 and_exprt (
1950- binary_relation_exprt (axiom.univ_var (), ID_ge, axiom.lower_bound ()),
1951- binary_relation_exprt (axiom.univ_var (), ID_lt, axiom.upper_bound ()),
1952- axiom.premise ()),
1953- axiom.body ());
1954- replace_expr (axiom.univ_var (), r, instance);
1934+ binary_relation_exprt (axiom.univ_var , ID_ge, axiom.lower_bound ),
1935+ binary_relation_exprt (axiom.univ_var , ID_lt, axiom.upper_bound )),
1936+ axiom.body );
1937+ replace_expr (axiom.univ_var , r, instance);
19551938 return instance;
19561939}
19571940
@@ -2208,11 +2191,11 @@ is_linear_arithmetic_expr(const exprt &expr, const symbol_exprt &var)
22082191// / \param [in] expr: The string constraint to check
22092192// / \return true if the universal variable only occurs in index expressions,
22102193// / false otherwise.
2211- static bool universal_only_in_index (const string_constraintt &expr )
2194+ static bool universal_only_in_index (const string_constraintt &constr )
22122195{
2213- for (auto it = expr .body () .depth_begin (); it != expr .body () .depth_end ();)
2196+ for (auto it = constr .body .depth_begin (); it != constr .body .depth_end ();)
22142197 {
2215- if (*it == expr .univ_var () )
2198+ if (*it == constr .univ_var )
22162199 return false ;
22172200 if (it->id () == ID_index)
22182201 it.next_sibling_or_parent ();
@@ -2226,35 +2209,20 @@ static bool universal_only_in_index(const string_constraintt &expr)
22262209// / \related string_constraintt
22272210// / \param stream: message stream
22282211// / \param ns: namespace
2229- // / \param [in] expr : the string constraint to check
2212+ // / \param [in] constraint : the string constraint to check
22302213// / \return whether the constraint satisfies the invariant
22312214static bool is_valid_string_constraint (
22322215 messaget::mstreamt &stream,
22332216 const namespacet &ns,
2234- const string_constraintt &expr )
2217+ const string_constraintt &constraint )
22352218{
22362219 const auto eom=messaget::eom;
2237- // Condition 1: The premise cannot contain any string indices
2238- const array_index_mapt premise_indices=gather_indices (expr.premise ());
2239- if (!premise_indices.empty ())
2240- {
2241- stream << " Premise has indices: " << format (expr) << " , map: {" ;
2242- for (const auto &pair : premise_indices)
2243- {
2244- stream << format (pair.first ) << " : {" ;
2245- for (const auto &i : pair.second )
2246- stream << format (i) << " , " ;
2247- }
2248- stream << " }}" << eom;
2249- return false ;
2250- }
2251-
2252- const array_index_mapt body_indices=gather_indices (expr.body ());
2220+ const array_index_mapt body_indices = gather_indices (constraint.body );
22532221 // Must validate for each string. Note that we have an invariant that the
22542222 // second value in the pair is non-empty.
22552223 for (const auto &pair : body_indices)
22562224 {
2257- // Condition 2 : All indices of the same string must be the of the same form
2225+ // Condition 1 : All indices of the same string must be the of the same form
22582226 const exprt rep=pair.second .back ();
22592227 for (size_t j=0 ; j<pair.second .size ()-1 ; j++)
22602228 {
@@ -2263,25 +2231,26 @@ static bool is_valid_string_constraint(
22632231 const exprt result=simplify_expr (equals, ns);
22642232 if (result.is_false ())
22652233 {
2266- stream << " Indices not equal: " << format (expr )
2234+ stream << " Indices not equal: " << to_string (constraint )
22672235 << " , str: " << format (pair.first ) << eom;
22682236 return false ;
22692237 }
22702238 }
22712239
2272- // Condition 3 : f must be linear in the quantified variable
2273- if (!is_linear_arithmetic_expr (rep, expr .univ_var () ))
2240+ // Condition 2 : f must be linear in the quantified variable
2241+ if (!is_linear_arithmetic_expr (rep, constraint .univ_var ))
22742242 {
2275- stream << " f is not linear: " << format (expr )
2243+ stream << " f is not linear: " << to_string (constraint )
22762244 << " , str: " << format (pair.first ) << eom;
22772245 return false ;
22782246 }
22792247
2280- // Condition 4 : the quantified variable can only occur in indices in the
2248+ // Condition 3 : the quantified variable can only occur in indices in the
22812249 // body
2282- if (!universal_only_in_index (expr ))
2250+ if (!universal_only_in_index (constraint ))
22832251 {
2284- stream << " Universal variable outside of index:" << format (expr) << eom;
2252+ stream << " Universal variable outside of index:" << to_string (constraint)
2253+ << eom;
22852254 return false ;
22862255 }
22872256 }
0 commit comments