@@ -29,11 +29,6 @@ Author: Alberto Griggio, alberto.griggio@gmail.com
2929#include < solvers/refinement/string_constraint_instantiation.h>
3030#include < unordered_set>
3131
32- static bool is_valid_string_constraint (
33- messaget::mstreamt &stream,
34- const namespacet &ns,
35- const string_constraintt &constraint);
36-
3732static optionalt<exprt> find_counter_example (
3833 const namespacet &ns,
3934 ui_message_handlert::uit ui,
@@ -2327,138 +2322,3 @@ static optionalt<exprt> find_counter_example(
23272322 else
23282323 return { };
23292324}
2330-
2331- // / \related string_constraintt
2332- typedef std::map<exprt, std::vector<exprt>> array_index_mapt;
2333-
2334- // / \related string_constraintt
2335- static array_index_mapt gather_indices (const exprt &expr)
2336- {
2337- array_index_mapt indices;
2338- // clang-format off
2339- std::for_each (
2340- expr.depth_begin (),
2341- expr.depth_end (),
2342- [&](const exprt &expr)
2343- {
2344- const auto index_expr = expr_try_dynamic_cast<const index_exprt>(expr);
2345- if (index_expr)
2346- indices[index_expr->array ()].push_back (index_expr->index ());
2347- });
2348- // clang-format on
2349- return indices;
2350- }
2351-
2352- // / \param expr: an expression
2353- // / \param var: a symbol
2354- // / \return Boolean telling whether `expr` is a linear function of `var`.
2355- // / \todo Add unit tests
2356- // / \related string_constraintt
2357- static bool
2358- is_linear_arithmetic_expr (const exprt &expr, const symbol_exprt &var)
2359- {
2360- for (auto it = expr.depth_begin (); it != expr.depth_end ();)
2361- {
2362- if (
2363- it->id () != ID_plus && it->id () != ID_minus &&
2364- it->id () != ID_unary_minus && *it != var)
2365- {
2366- if (find_qvar (*it, var))
2367- return false ;
2368- else
2369- it.next_sibling_or_parent ();
2370- }
2371- else
2372- ++it;
2373- }
2374- return true ;
2375- }
2376-
2377- // / The universally quantified variable is only allowed to occur in index
2378- // / expressions in the body of a string constraint. This function returns true
2379- // / if this is the case and false otherwise.
2380- // / \related string_constraintt
2381- // / \param [in] expr: The string constraint to check
2382- // / \return true if the universal variable only occurs in index expressions,
2383- // / false otherwise.
2384- static bool universal_only_in_index (const string_constraintt &expr)
2385- {
2386- for (auto it = expr.body .depth_begin (); it != expr.body .depth_end ();)
2387- {
2388- if (*it == expr.univ_var )
2389- return false ;
2390- if (it->id () == ID_index)
2391- it.next_sibling_or_parent ();
2392- else
2393- ++it;
2394- }
2395- return true ;
2396- }
2397-
2398- // / Checks the data invariant for \link string_constraintt \endlink
2399- // / \related string_constraintt
2400- // / \param stream: message stream
2401- // / \param ns: namespace
2402- // / \param [in] constraint: the string constraint to check
2403- // / \return whether the constraint satisfies the invariant
2404- static bool is_valid_string_constraint (
2405- messaget::mstreamt &stream,
2406- const namespacet &ns,
2407- const string_constraintt &constraint)
2408- {
2409- const auto eom=messaget::eom;
2410- // Condition 1: The premise cannot contain any string indices
2411- const array_index_mapt premise_indices = gather_indices (constraint.premise );
2412- if (!premise_indices.empty ())
2413- {
2414- stream << " Premise has indices: " << to_string (constraint) << " , map: {" ;
2415- for (const auto &pair : premise_indices)
2416- {
2417- stream << format (pair.first ) << " : {" ;
2418- for (const auto &i : pair.second )
2419- stream << format (i) << " , " ;
2420- }
2421- stream << " }}" << eom;
2422- return false ;
2423- }
2424-
2425- const array_index_mapt body_indices = gather_indices (constraint.body );
2426- // Must validate for each string. Note that we have an invariant that the
2427- // second value in the pair is non-empty.
2428- for (const auto &pair : body_indices)
2429- {
2430- // Condition 2: All indices of the same string must be the of the same form
2431- const exprt rep=pair.second .back ();
2432- for (size_t j=0 ; j<pair.second .size ()-1 ; j++)
2433- {
2434- const exprt i=pair.second [j];
2435- const equal_exprt equals (rep, i);
2436- const exprt result=simplify_expr (equals, ns);
2437- if (result.is_false ())
2438- {
2439- stream << " Indices not equal: " << to_string (constraint)
2440- << " , str: " << format (pair.first ) << eom;
2441- return false ;
2442- }
2443- }
2444-
2445- // Condition 3: f must be linear in the quantified variable
2446- if (!is_linear_arithmetic_expr (rep, constraint.univ_var ))
2447- {
2448- stream << " f is not linear: " << to_string (constraint)
2449- << " , str: " << format (pair.first ) << eom;
2450- return false ;
2451- }
2452-
2453- // Condition 4: the quantified variable can only occur in indices in the
2454- // body
2455- if (!universal_only_in_index (constraint))
2456- {
2457- stream << " Universal variable outside of index:" << to_string (constraint)
2458- << eom;
2459- return false ;
2460- }
2461- }
2462-
2463- return true ;
2464- }
0 commit comments