33
33
static bool is_valid_string_constraint (
34
34
messaget::mstreamt &stream,
35
35
const namespacet &ns,
36
- const string_constraintt &expr );
36
+ const string_constraintt &constraint );
37
37
38
38
static optionalt<exprt> find_counter_example (
39
39
const namespacet &ns,
@@ -697,7 +697,7 @@ decision_proceduret::resultt string_refinementt::dec_solve()
697
697
constraints.end (),
698
698
std::back_inserter (axioms.universal ),
699
699
[&](string_constraintt constraint) {
700
- symbol_resolve .replace_expr (constraint );
700
+ constraint .replace_expr (symbol_resolve );
701
701
DATA_INVARIANT (
702
702
is_valid_string_constraint (error (), ns, constraint),
703
703
string_refinement_invariantt (
@@ -1238,34 +1238,23 @@ static exprt negation_of_not_contains_constraint(
1238
1238
1239
1239
// / Debugging function which outputs the different steps an axiom goes through
1240
1240
// / to be checked in check axioms.
1241
+ // / \tparam T: can be either string_constraintt or
1242
+ // / string_not_contains_constraintt
1243
+ template <typename T>
1241
1244
static void debug_check_axioms_step (
1242
1245
messaget::mstreamt &stream,
1243
1246
const namespacet &ns,
1244
- const exprt &axiom,
1245
- const exprt &axiom_in_model,
1247
+ const T &axiom,
1248
+ const T &axiom_in_model,
1246
1249
const exprt &negaxiom,
1247
1250
const exprt &with_concretized_arrays)
1248
1251
{
1249
1252
static const std::string indent = " " ;
1250
1253
static const std::string indent2 = " " ;
1251
1254
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);
1259
1256
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 '
1269
1258
<< indent2 << " - negated_axiom:\n "
1270
1259
<< indent2 << indent << format (negaxiom) << ' \n ' ;
1271
1260
stream << indent2 << " - negated_axiom_with_concretized_arrays:\n "
@@ -1322,16 +1311,11 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
1322
1311
for (size_t i=0 ; i<axioms.universal .size (); i++)
1323
1312
{
1324
1313
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
-
1333
1314
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 ));
1335
1319
1336
1320
exprt negaxiom = axiom_in_model.negation ();
1337
1321
negaxiom = simplify_expr (negaxiom, ns);
@@ -1342,11 +1326,12 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
1342
1326
debug_check_axioms_step (
1343
1327
stream, ns, axiom, axiom_in_model, negaxiom, with_concretized_arrays);
1344
1328
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 ))
1347
1332
{
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;
1350
1335
violated[i]=*witness;
1351
1336
}
1352
1337
else
@@ -1402,13 +1387,13 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
1402
1387
const exprt &val=v.second ;
1403
1388
const string_constraintt &axiom=axioms.universal [v.first ];
1404
1389
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);
1407
1392
// We are not sure the index set contains only positive numbers
1408
1393
and_exprt bounds (
1409
1394
axiom.univ_within_bounds (),
1410
1395
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);
1412
1397
const implies_exprt counter (bounds, instance);
1413
1398
lemmas.push_back (counter);
1414
1399
}
@@ -1766,10 +1751,10 @@ static void initial_index_set(
1766
1751
const namespacet &ns,
1767
1752
const string_constraintt &axiom)
1768
1753
{
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 ();
1773
1758
while (it != end)
1774
1759
{
1775
1760
if (it->id () == ID_index && is_char_type (it->type ()))
@@ -1912,18 +1897,17 @@ static exprt instantiate(
1912
1897
const exprt &str,
1913
1898
const exprt &val)
1914
1899
{
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 );
1916
1901
if (!idx.has_value ())
1917
1902
return true_exprt ();
1918
1903
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);
1920
1905
implies_exprt instance (
1921
1906
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);
1927
1911
return instance;
1928
1912
}
1929
1913
@@ -2175,11 +2159,11 @@ is_linear_arithmetic_expr(const exprt &expr, const symbol_exprt &var)
2175
2159
// / \param [in] expr: The string constraint to check
2176
2160
// / \return true if the universal variable only occurs in index expressions,
2177
2161
// / false otherwise.
2178
- static bool universal_only_in_index (const string_constraintt &expr )
2162
+ static bool universal_only_in_index (const string_constraintt &constr )
2179
2163
{
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 ();)
2181
2165
{
2182
- if (*it == expr .univ_var () )
2166
+ if (*it == constr .univ_var )
2183
2167
return false ;
2184
2168
if (it->id () == ID_index)
2185
2169
it.next_sibling_or_parent ();
@@ -2193,35 +2177,20 @@ static bool universal_only_in_index(const string_constraintt &expr)
2193
2177
// / \related string_constraintt
2194
2178
// / \param stream: message stream
2195
2179
// / \param ns: namespace
2196
- // / \param [in] expr : the string constraint to check
2180
+ // / \param [in] constraint : the string constraint to check
2197
2181
// / \return whether the constraint satisfies the invariant
2198
2182
static bool is_valid_string_constraint (
2199
2183
messaget::mstreamt &stream,
2200
2184
const namespacet &ns,
2201
- const string_constraintt &expr )
2185
+ const string_constraintt &constraint )
2202
2186
{
2203
2187
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 );
2220
2189
// Must validate for each string. Note that we have an invariant that the
2221
2190
// second value in the pair is non-empty.
2222
2191
for (const auto &pair : body_indices)
2223
2192
{
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
2225
2194
const exprt rep=pair.second .back ();
2226
2195
for (size_t j=0 ; j<pair.second .size ()-1 ; j++)
2227
2196
{
@@ -2230,25 +2199,26 @@ static bool is_valid_string_constraint(
2230
2199
const exprt result=simplify_expr (equals, ns);
2231
2200
if (result.is_false ())
2232
2201
{
2233
- stream << " Indices not equal: " << format (expr )
2202
+ stream << " Indices not equal: " << to_string (constraint )
2234
2203
<< " , str: " << format (pair.first ) << eom;
2235
2204
return false ;
2236
2205
}
2237
2206
}
2238
2207
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 ))
2241
2210
{
2242
- stream << " f is not linear: " << format (expr )
2211
+ stream << " f is not linear: " << to_string (constraint )
2243
2212
<< " , str: " << format (pair.first ) << eom;
2244
2213
return false ;
2245
2214
}
2246
2215
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
2248
2217
// body
2249
- if (!universal_only_in_index (expr ))
2218
+ if (!universal_only_in_index (constraint ))
2250
2219
{
2251
- stream << " Universal variable outside of index:" << format (expr) << eom;
2220
+ stream << " Universal variable outside of index:" << to_string (constraint)
2221
+ << eom;
2252
2222
return false ;
2253
2223
}
2254
2224
}
0 commit comments