35
35
#include < java_bytecode/java_types.h>
36
36
#include < util/optional.h>
37
37
38
+ static exprt instantiate (
39
+ const string_constraintt &axiom, const exprt &str, const exprt &val);
40
+ exprt simplify_sum (const exprt &f);
41
+
38
42
// / Convert exprt to a specific type. Throw bad_cast if conversion
39
43
// / cannot be performed
40
44
// / Generic case doesn't exist, specialize for different types accordingly
@@ -97,59 +101,72 @@ string_refinementt::string_refinementt(const infot &info):
97
101
98
102
// / display the current index set, for debugging
99
103
static void display_index_set (
100
- const messaget& message ,
104
+ messaget::mstreamt stream ,
101
105
const namespacet& ns,
102
106
const std::map<exprt, std::set<exprt>>& current_index_set,
103
107
const std::map<exprt, std::set<exprt>>& index_set)
104
108
{
109
+ const auto eom = messaget::eom;
105
110
std::size_t count=0 ;
106
111
std::size_t count_current=0 ;
107
112
for (const auto &i : index_set)
108
113
{
109
114
const exprt &s=i.first ;
110
- message. debug () << " IS(" << from_expr (ns, " " , s) << " )=={" << message. eom ;
115
+ stream << " IS(" << from_expr (ns, " " , s) << " )=={" << eom;
111
116
112
117
for (auto j : i.second )
113
118
{
114
119
const auto it=current_index_set.find (i.first );
115
120
if (it!=current_index_set.end () && it->second .find (j)!=it->second .end ())
116
121
{
117
122
count_current++;
118
- message. debug () << " **" ;
123
+ stream << " **" ;
119
124
}
120
- message. debug () << " " << from_expr (ns, " " , j) << " ;" << message. eom ;
125
+ stream << " " << from_expr (ns, " " , j) << " ;" << eom;
121
126
count++;
122
127
}
123
- message. debug () << " }" << message. eom ;
128
+ stream << " }" << eom;
124
129
}
125
- message. debug () << count << " elements in index set (" << count_current
126
- << " newly added)" << message. eom ;
130
+ stream << count << " elements in index set (" << count_current
131
+ << " newly added)" << eom;
127
132
}
128
133
129
134
// / compute the index set for all formulas, instantiate the formulas with the
130
135
// / found indexes, and add them as lemmas.
131
- void string_refinementt::add_instantiations ()
136
+
137
+ static void display_current_index_set (
138
+ messaget::mstreamt &stream,
139
+ const namespacet &ns,
140
+ const std::map<exprt, std::set<exprt>> ¤t_index_set)
132
141
{
133
- debug () << " string_constraint_generatort::add_instantiations: "
134
- << " going through the current index set:" << eom;
142
+ const auto eom=messaget::eom;
143
+ stream << " string_constraint_generatort::add_instantiations: "
144
+ << " going through the current index set:" << eom;
135
145
for (const auto &i : current_index_set)
136
146
{
137
147
const exprt &s=i.first ;
138
- debug () << " IS(" << from_expr (ns, " " , s) << " )=={" ;
148
+ stream << " IS(" << from_expr (ns, " " , s) << " )=={" ;
139
149
140
150
for (const auto &j : i.second )
141
- debug () << from_expr (ns, " " , j) << " ; " ;
142
- debug () << " }" << eom;
151
+ stream << from_expr (ns, " " , j) << " ; " ;
152
+ stream << " }" << eom;
153
+ }
154
+ }
143
155
156
+ static std::vector<exprt> generate_instantiations (
157
+ const std::map<exprt, std::set<exprt>> ¤t_index_set,
158
+ const std::vector<string_constraintt>& universal_axioms)
159
+ {
160
+ std::vector<exprt> lemmas;
161
+ for (const auto &i : current_index_set)
162
+ {
144
163
for (const auto &ua : universal_axioms)
145
164
{
146
165
for (const auto &j : i.second )
147
- {
148
- exprt lemma=instantiate (ua, s, j);
149
- add_lemma (lemma);
150
- }
166
+ lemmas.push_back (instantiate (ua, i.first , j));
151
167
}
152
168
}
169
+ return lemmas;
153
170
}
154
171
155
172
// / List the simple expressions on which the expression depends in the
@@ -381,7 +398,10 @@ void string_refinementt::concretize_results()
381
398
concretize_string (it.second );
382
399
for (const auto &it : generator.get_created_strings ())
383
400
concretize_string (it);
384
- add_instantiations ();
401
+ for (const auto & lemma :
402
+ generate_instantiations (current_index_set, universal_axioms))
403
+ add_lemma (lemma);
404
+ display_current_index_set (debug (), ns, current_index_set);
385
405
}
386
406
387
407
// / For each string whose length has been solved, add constants to the map
@@ -551,7 +571,10 @@ decision_proceduret::resultt string_refinementt::dec_solve()
551
571
initial_index_set (universal_axioms);
552
572
update_index_set (cur);
553
573
cur.clear ();
554
- add_instantiations ();
574
+ for (const auto & lemma :
575
+ generate_instantiations (current_index_set, universal_axioms))
576
+ add_lemma (lemma);
577
+ display_current_index_set (debug (), ns, current_index_set);
555
578
556
579
while ((loop_bound_--)>0 )
557
580
{
@@ -579,7 +602,10 @@ decision_proceduret::resultt string_refinementt::dec_solve()
579
602
current_index_set.clear ();
580
603
update_index_set (cur);
581
604
cur.clear ();
582
- add_instantiations ();
605
+ for (const auto & lemma :
606
+ generate_instantiations (current_index_set, universal_axioms))
607
+ add_lemma (lemma);
608
+ display_current_index_set (debug (), ns, current_index_set);
583
609
584
610
if (current_index_set.empty ())
585
611
{
@@ -597,7 +623,7 @@ decision_proceduret::resultt string_refinementt::dec_solve()
597
623
}
598
624
}
599
625
600
- display_index_set (* this , ns, current_index_set, index_set);
626
+ display_index_set (debug () , ns, current_index_set, index_set);
601
627
debug ()<< " instantiating NOT_CONTAINS constraints" << eom;
602
628
for (unsigned i=0 ; i<not_contains_axioms.size (); i++)
603
629
{
@@ -1254,8 +1280,7 @@ bool string_refinementt::check_axioms()
1254
1280
// / \return a map where each leaf of the input is mapped to the number of times
1255
1281
// / it is added. For instance, expression $x + x - y$ would give the map x ->
1256
1282
// / 2, y -> -1.
1257
- std::map<exprt, int > string_refinementt::map_representation_of_sum (
1258
- const exprt &f) const
1283
+ static std::map<exprt, int > map_representation_of_sum (const exprt &f)
1259
1284
{
1260
1285
// number of time the leaf should be added (can be negative)
1261
1286
std::map<exprt, int > elems;
@@ -1297,8 +1322,10 @@ std::map<exprt, int> string_refinementt::map_representation_of_sum(
1297
1322
// / \return a expression for the sum of each element in the map a number of
1298
1323
// / times given by the corresponding integer in the map. For a map x -> 2, y
1299
1324
// / -> -1 would give an expression $x + x - y$.
1300
- exprt string_refinementt::sum_over_map (
1301
- std::map<exprt, int > &m, const typet &type, bool negated) const
1325
+ static exprt sum_over_map (
1326
+ std::map<exprt, int > &m,
1327
+ const typet &type,
1328
+ bool negated = false )
1302
1329
{
1303
1330
exprt sum=nil_exprt ();
1304
1331
mp_integer constants=0 ;
@@ -1368,7 +1395,7 @@ exprt string_refinementt::sum_over_map(
1368
1395
1369
1396
// / \par parameters: an expression with only plus and minus expr
1370
1397
// / \return an equivalent expression in a canonical form
1371
- exprt string_refinementt:: simplify_sum (const exprt &f) const
1398
+ exprt simplify_sum (const exprt &f)
1372
1399
{
1373
1400
std::map<exprt, int > map=map_representation_of_sum (f);
1374
1401
return sum_over_map (map, f.type ());
@@ -1381,7 +1408,7 @@ exprt string_refinementt::simplify_sum(const exprt &f) const
1381
1408
// / a function of $qvar$, i.e. the value that is necessary for qvar for f to
1382
1409
// / be equal to val. For instance, if `f` corresponds to the expression $q +
1383
1410
// / x$, `compute_inverse_function(q,v,f)` returns an expression for $v - x$.
1384
- exprt string_refinementt:: compute_inverse_function (
1411
+ static exprt compute_inverse_function (
1385
1412
const exprt &qvar, const exprt &val, const exprt &f)
1386
1413
{
1387
1414
exprt positive, negative;
@@ -1409,8 +1436,8 @@ exprt string_refinementt::compute_inverse_function(
1409
1436
string_refinement_invariantt (" a proper function must have exactly one "
1410
1437
" occurrences after reduction, or it canceled out, and it does not have "
1411
1438
" one" ));
1412
- debug () << " in string_refinementt::compute_inverse_function:"
1413
- << " warning: occurrences of qvar canceled out " << eom;
1439
+ // debug() << "in string_refinementt::compute_inverse_function:"
1440
+ // << " warning: occurrences of qvar canceled out " << eom;
1414
1441
}
1415
1442
1416
1443
elems.erase (it);
@@ -1605,7 +1632,7 @@ class find_index_visitort: public const_expr_visitort
1605
1632
// / \param [in] str: the string which must be indexed
1606
1633
// / \param [in] qvar: the universal variable that must be in the index
1607
1634
// / \return an index expression in `expr` on `str` containing `qvar`
1608
- exprt find_index (const exprt &expr, const exprt &str, const symbol_exprt &qvar)
1635
+ static exprt find_index (const exprt &expr, const exprt &str, const symbol_exprt &qvar)
1609
1636
{
1610
1637
find_index_visitort v (str, qvar);
1611
1638
expr.visit (v);
@@ -1619,7 +1646,7 @@ exprt find_index(const exprt &expr, const exprt &str, const symbol_exprt &qvar)
1619
1646
// / For instance, if `axiom` corresponds to $\forall q. s[q+x]='a' &&
1620
1647
// / t[q]='b'$, `instantiate(axiom,s,v)` would return an expression for
1621
1648
// / $s[v]='a' && t[v-x]='b'$.
1622
- exprt string_refinementt:: instantiate (
1649
+ static exprt instantiate (
1623
1650
const string_constraintt &axiom, const exprt &str, const exprt &val)
1624
1651
{
1625
1652
exprt idx=find_index (axiom.body (), str, axiom.univ_var ());
0 commit comments