Skip to content

Commit ac1b620

Browse files
committed
TG-672 Fixed expr_cast to be unambiguous and added const and const references throughout
1 parent b5fe7e3 commit ac1b620

File tree

1 file changed

+68
-56
lines changed

1 file changed

+68
-56
lines changed

src/solvers/refinement/string_refinement.cpp

+68-56
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
5353
const std::vector<string_constraintt> &universal_axioms,
5454
const std::vector<string_not_contains_constraintt> &not_contains_axioms,
5555
string_constraint_generatort &generator,
56-
std::function<exprt(const exprt &)> get,
56+
const std::function<exprt(const exprt &)> &get,
5757
messaget::mstreamt &stream,
5858
const namespacet &ns,
5959
std::size_t max_string_length,
@@ -96,45 +96,57 @@ static std::vector<exprt> instantiate_not_contains(
9696
const string_constraint_generatort &generator);
9797

9898
static exprt get_array(
99-
std::function<exprt(const exprt &)> super_get,
99+
const std::function<exprt(const exprt &)> &super_get,
100100
const exprt &arr);
101101

102102
/// Convert exprt to a specific type. Throw bad_cast if conversion
103103
/// cannot be performed
104104
/// Generic case doesn't exist, specialize for different types accordingly
105105
/// TODO: this should go to util
106+
107+
// Tag dispatching struct
108+
106109
template<typename T>
107-
optionalt<T> expr_cast(const exprt &);
110+
struct expr_cast_implt final { };
108111

109112
template<>
110-
optionalt<mp_integer> expr_cast<mp_integer>(const exprt &expr)
113+
struct expr_cast_implt<mp_integer> final
111114
{
112-
mp_integer out;
113-
if(to_integer(expr, out))
114-
return { };
115-
return out;
116-
}
115+
optionalt<mp_integer> operator()(const exprt &expr) const
116+
{
117+
mp_integer out;
118+
if(to_integer(expr, out))
119+
return {};
120+
return out;
121+
}
122+
};
117123

118124
template<>
119-
optionalt<std::size_t> expr_cast<std::size_t>(const exprt &expr)
125+
struct expr_cast_implt<std::size_t> final
120126
{
121-
if(const auto tmp=expr_cast<mp_integer>(expr))
127+
optionalt<std::size_t> operator()(const exprt &expr) const
122128
{
123-
if(tmp->is_long() && *tmp >= 0)
124-
return tmp->to_long();
129+
if(const auto tmp=expr_cast_implt<mp_integer>()(expr))
130+
if(tmp->is_long() && *tmp>=0)
131+
return tmp->to_long();
132+
return {};
125133
}
126-
return { };
127-
}
134+
};
128135

129136
template<>
130-
optionalt<string_exprt> expr_cast<string_exprt>(const exprt &expr)
137+
struct expr_cast_implt<string_exprt> final
131138
{
132-
if(is_refined_string_type(expr.type()))
139+
optionalt<string_exprt> operator()(const exprt &expr) const
133140
{
134-
return to_string_expr(expr);
141+
if(is_refined_string_type(expr.type()))
142+
return to_string_expr(expr);
143+
return {};
135144
}
136-
return { };
137-
}
145+
};
146+
147+
template<typename T>
148+
optionalt<T> expr_cast(const exprt& expr)
149+
{ return expr_cast_implt<T>()(expr); }
138150

139151
template<typename T>
140152
T expr_cast_v(const exprt &expr)
@@ -206,7 +218,7 @@ static void display_index_set(
206218
const exprt &s=i.first;
207219
stream << "IS(" << from_expr(ns, "", s) << ")=={" << eom;
208220

209-
for(auto j : i.second)
221+
for(const auto &j : i.second)
210222
{
211223
const auto it=current_index_set.find(i.first);
212224
if(it!=current_index_set.end() && it->second.find(j)!=it->second.end())
@@ -696,7 +708,8 @@ decision_proceduret::resultt string_refinementt::dec_solve()
696708
{
697709
string_not_contains_constraintt nc_axiom=
698710
to_string_not_contains_constraint(axiom);
699-
refined_string_typet rtype=to_refined_string_type(nc_axiom.s0().type());
711+
const refined_string_typet &rtype=
712+
to_refined_string_type(nc_axiom.s0().type());
700713
const typet &index_type=rtype.get_index_type();
701714
array_typet witness_type(index_type, infinity_exprt(index_type));
702715
generator.witness[nc_axiom]=
@@ -715,7 +728,7 @@ decision_proceduret::resultt string_refinementt::dec_solve()
715728
const auto get=[this](const exprt &expr) { return this->get(expr); };
716729

717730
// Initial try without index set
718-
decision_proceduret::resultt res=supert::dec_solve();
731+
const decision_proceduret::resultt res=supert::dec_solve();
719732
if(res==resultt::D_SATISFIABLE)
720733
{
721734
bool satisfied;
@@ -759,7 +772,7 @@ decision_proceduret::resultt string_refinementt::dec_solve()
759772

760773
while((loop_bound_--)>0)
761774
{
762-
decision_proceduret::resultt res=supert::dec_solve();
775+
const decision_proceduret::resultt res=supert::dec_solve();
763776

764777
if(res==resultt::D_SATISFIABLE)
765778
{
@@ -899,7 +912,7 @@ void string_refinementt::add_lemma(
899912
/// representing an integer
900913
/// \return an array expression or an array_of_exprt
901914
static exprt get_array(
902-
const std::function<exprt(const exprt &)> super_get,
915+
const std::function<exprt(const exprt &)> &super_get,
903916
const namespacet &ns,
904917
const std::size_t max_string_length,
905918
const exprt &arr,
@@ -909,7 +922,7 @@ static exprt get_array(
909922
exprt size_val=super_get(size);
910923
size_val=simplify_expr(size_val, ns);
911924
typet char_type=arr.type().subtype();
912-
typet index_type=size.type();
925+
const typet &index_type=size.type();
913926
array_typet empty_ret_type(char_type, from_integer(0, index_type));
914927
array_of_exprt empty_ret(from_integer(0, char_type), empty_ret_type);
915928

@@ -986,7 +999,7 @@ static exprt get_array(
986999
/// \par parameters: an expression representing an array
9871000
/// \return an expression
9881001
static exprt get_array(
989-
const std::function<exprt(const exprt &)> super_get,
1002+
const std::function<exprt(const exprt &)> &super_get,
9901003
const exprt &arr)
9911004
{
9921005
exprt arr_model=super_get(arr);
@@ -1022,7 +1035,7 @@ void debug_model(
10221035
messaget::mstreamt &stream,
10231036
const namespacet &ns,
10241037
const std::size_t max_string_length,
1025-
const std::function<exprt(const exprt &)> super_get,
1038+
const std::function<exprt(const exprt &)> &super_get,
10261039
const std::vector<symbol_exprt> &boolean_symbols,
10271040
const std::vector<symbol_exprt> &index_symbols)
10281041
{
@@ -1073,13 +1086,13 @@ void debug_model(
10731086
}
10741087
}
10751088

1076-
for(const auto it : boolean_symbols)
1089+
for(const auto &it : boolean_symbols)
10771090
{
10781091
stream << " - " << it.get_identifier() << ": "
10791092
<< from_expr(ns, "", super_get(it)) << '\n';
10801093
}
10811094

1082-
for(const auto it : index_symbols)
1095+
for(const auto &it : index_symbols)
10831096
{
10841097
stream << " - " << it.get_identifier() << ": "
10851098
<< from_expr(ns, "", super_get(it)) << '\n';
@@ -1268,8 +1281,8 @@ static exprt negation_of_not_contains_constraint(
12681281
const symbol_exprt &univ_var)
12691282
{
12701283
// If the for all is vacuously true, the negation is false.
1271-
const exprt lbu=axiom.univ_lower_bound();
1272-
const exprt ubu=axiom.univ_upper_bound();
1284+
const exprt &lbu=axiom.univ_lower_bound();
1285+
const exprt &ubu=axiom.univ_upper_bound();
12731286
if(lbu.id()==ID_constant && ubu.id()==ID_constant)
12741287
{
12751288
const auto lb_int=expr_cast<mp_integer>(lbu);
@@ -1318,8 +1331,8 @@ static exprt negation_of_not_contains_constraint(
13181331
static exprt negation_of_constraint(const string_constraintt &axiom)
13191332
{
13201333
// If the for all is vacuously true, the negation is false.
1321-
exprt lb=axiom.lower_bound();
1322-
exprt ub=axiom.upper_bound();
1334+
const exprt &lb=axiom.lower_bound();
1335+
const exprt &ub=axiom.upper_bound();
13231336
if(lb.id()==ID_constant && ub.id()==ID_constant)
13241337
{
13251338
const auto lb_int=expr_cast<mp_integer>(lb);
@@ -1371,7 +1384,7 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
13711384
const std::vector<string_constraintt> &universal_axioms,
13721385
const std::vector<string_not_contains_constraintt> &not_contains_axioms,
13731386
string_constraint_generatort &generator,
1374-
std::function<exprt(const exprt &)> get,
1387+
const std::function<exprt(const exprt &)> &get,
13751388
messaget::mstreamt &stream,
13761389
const namespacet &ns,
13771390
std::size_t max_string_length,
@@ -1400,11 +1413,11 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
14001413
for(size_t i=0; i<universal_axioms.size(); i++)
14011414
{
14021415
const string_constraintt &axiom=universal_axioms[i];
1403-
const symbol_exprt univ_var=axiom.univ_var();
1404-
const exprt bound_inf=axiom.lower_bound();
1405-
const exprt bound_sup=axiom.upper_bound();
1406-
const exprt prem=axiom.premise();
1407-
const exprt body=axiom.body();
1416+
const symbol_exprt &univ_var=axiom.univ_var();
1417+
const exprt &bound_inf=axiom.lower_bound();
1418+
const exprt &bound_sup=axiom.upper_bound();
1419+
const exprt &prem=axiom.premise();
1420+
const exprt &body=axiom.body();
14081421

14091422
const string_constraintt axiom_in_model(
14101423
univ_var, get(bound_inf), get(bound_sup), get(prem), get(body));
@@ -1427,9 +1440,8 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
14271440
substitute_array_access(with_concretized_arrays);
14281441
stream << " - negated_axiom_without_array_access:\n"
14291442
<< " " << from_expr(ns, "", with_concretized_arrays) << '\n';
1430-
exprt witness;
14311443

1432-
if(const auto witness=
1444+
if(const auto &witness=
14331445
find_counter_example(ns, ui, with_concretized_arrays, univ_var))
14341446
{
14351447
stream << " - violated_for: "
@@ -1449,13 +1461,13 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
14491461
for(size_t i=0; i<not_contains_axioms.size(); i++)
14501462
{
14511463
const string_not_contains_constraintt &nc_axiom=not_contains_axioms[i];
1452-
const exprt univ_bound_inf=nc_axiom.univ_lower_bound();
1453-
const exprt univ_bound_sup=nc_axiom.univ_upper_bound();
1454-
const exprt prem=nc_axiom.premise();
1455-
const exprt exists_bound_inf=nc_axiom.exists_lower_bound();
1456-
const exprt exists_bound_sup=nc_axiom.exists_upper_bound();
1457-
const string_exprt s0=nc_axiom.s0();
1458-
const string_exprt s1=nc_axiom.s1();
1464+
const exprt &univ_bound_inf=nc_axiom.univ_lower_bound();
1465+
const exprt &univ_bound_sup=nc_axiom.univ_upper_bound();
1466+
const exprt &prem=nc_axiom.premise();
1467+
const exprt &exists_bound_inf=nc_axiom.exists_lower_bound();
1468+
const exprt &exists_bound_sup=nc_axiom.exists_upper_bound();
1469+
const string_exprt &s0=nc_axiom.s0();
1470+
const string_exprt &s1=nc_axiom.s1();
14591471

14601472
symbol_exprt univ_var=generator.fresh_univ_index(
14611473
"not_contains_univ_var", nc_axiom.s0().length().type());
@@ -1474,7 +1486,7 @@ static std::pair<bool, std::vector<exprt>> check_axioms(
14741486
<< from_expr(ns, "", negaxiom) << eom;
14751487
substitute_array_access(negaxiom);
14761488

1477-
if(const auto witness=find_counter_example(ns, ui, negaxiom, univ_var))
1489+
if(const auto &witness=find_counter_example(ns, ui, negaxiom, univ_var))
14781490
{
14791491
stream << "string constraint can be violated for "
14801492
<< univ_var.get_identifier()
@@ -1717,7 +1729,7 @@ class find_qvar_visitort: public const_expr_visitort
17171729
/// look for the symbol and return true if it is found
17181730
/// \par parameters: an index expression and a symbol qvar
17191731
/// \return a Boolean
1720-
static bool find_qvar(const exprt index, const symbol_exprt &qvar)
1732+
static bool find_qvar(const exprt &index, const symbol_exprt &qvar)
17211733
{
17221734
find_qvar_visitort v2(qvar);
17231735
index.visit(v2);
@@ -1784,7 +1796,7 @@ static void add_to_index_set(
17841796
exprt i)
17851797
{
17861798
simplify(i, ns);
1787-
const bool is_size_t=expr_cast<size_t>(i).has_value();
1799+
const bool is_size_t=expr_cast<std::size_t>(i).has_value();
17881800
if(i.id()!=ID_constant || is_size_t)
17891801
{
17901802
for(const auto &sub : sub_arrays(s))
@@ -1799,7 +1811,7 @@ static void initial_index_set(
17991811
const namespacet &ns,
18001812
const string_constraintt &axiom)
18011813
{
1802-
symbol_exprt qvar=axiom.univ_var();
1814+
const symbol_exprt &qvar=axiom.univ_var();
18031815
std::list<exprt> to_process;
18041816
to_process.push_back(axiom.body());
18051817

@@ -2116,9 +2128,9 @@ class gather_indices_visitort: public const_expr_visitort
21162128
{
21172129
if(expr.id()==ID_index)
21182130
{
2119-
const index_exprt index=to_index_expr(expr);
2120-
const exprt s(index.array());
2121-
const exprt i(index.index());
2131+
const index_exprt &index=to_index_expr(expr);
2132+
const exprt &s(index.array());
2133+
const exprt &i(index.index());
21222134
indices[s].push_back(i);
21232135
}
21242136
}

0 commit comments

Comments
 (0)