Skip to content

Commit c5ab866

Browse files
author
Daniel Kroening
authored
Merge pull request diffblue#1430 from romainbrenguier/refactor/gather_indices
Refactor functions in string solver
2 parents 55b6ac5 + d378980 commit c5ab866

File tree

2 files changed

+26
-49
lines changed

2 files changed

+26
-49
lines changed

src/solvers/refinement/string_constraint_generator_transformation.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,10 @@ exprt string_constraint_generatort::add_axioms_for_char_set(
354354
axioms.push_back(equal_exprt(res.length(), str.length()));
355355
axioms.push_back(equal_exprt(res[position], character));
356356
const symbol_exprt q = fresh_univ_index("QA_char_set", position.type());
357-
or_exprt a3_body(equal_exprt(q, position), equal_exprt(res[q], str[q]));
358-
axioms.push_back(string_constraintt(q, res.length(), a3_body));
357+
equal_exprt a3_body(res[q], str[q]);
358+
notequal_exprt a3_guard(q, position);
359+
axioms.push_back(string_constraintt(
360+
q, from_integer(0, q.type()), res.length(), a3_guard, a3_body));
359361
return if_exprt(
360362
out_of_bounds, from_integer(1, f.type()), from_integer(0, f.type()));
361363
}

src/solvers/refinement/string_refinement.cpp

+22-47
Original file line numberDiff line numberDiff line change
@@ -1924,9 +1924,13 @@ exprt substitute_array_lists(exprt expr, size_t string_max_length)
19241924
/// \return an expression
19251925
exprt string_refinementt::get(const exprt &expr) const
19261926
{
1927-
const auto super_get = [this](const exprt &expr) { // NOLINT
1927+
// clang-format off
1928+
const auto super_get = [this](const exprt &expr)
1929+
{
19281930
return supert::get(expr);
19291931
};
1932+
// clang-format on
1933+
19301934
exprt ecopy(expr);
19311935
(void)symbol_resolve.replace_expr(ecopy);
19321936

@@ -2003,31 +2007,21 @@ static optionalt<exprt> find_counter_example(
20032007
typedef std::map<exprt, std::vector<exprt>> array_index_mapt;
20042008

20052009
/// \related string_constraintt
2006-
class gather_indices_visitort: public const_expr_visitort
2010+
static array_index_mapt gather_indices(const exprt &expr)
20072011
{
2008-
public:
20092012
array_index_mapt indices;
2010-
2011-
gather_indices_visitort(): indices() {}
2012-
2013-
void operator()(const exprt &expr) override
2014-
{
2015-
if(expr.id()==ID_index)
2013+
// clang-format off
2014+
std::for_each(
2015+
expr.depth_begin(),
2016+
expr.depth_end(),
2017+
[&](const exprt &expr)
20162018
{
2017-
const index_exprt &index=to_index_expr(expr);
2018-
const exprt &s(index.array());
2019-
const exprt &i(index.index());
2020-
indices[s].push_back(i);
2021-
}
2022-
}
2023-
};
2024-
2025-
/// \related string_constraintt
2026-
static array_index_mapt gather_indices(const exprt &expr)
2027-
{
2028-
gather_indices_visitort v;
2029-
expr.visit(v);
2030-
return v.indices;
2019+
const auto index_expr = expr_try_dynamic_cast<const index_exprt>(expr);
2020+
if(index_expr)
2021+
indices[index_expr->array()].push_back(index_expr->index());
2022+
});
2023+
// clang-format on
2024+
return indices;
20312025
}
20322026

20332027
/// \param expr: an expression
@@ -2064,33 +2058,14 @@ is_linear_arithmetic_expr(const exprt &expr, const symbol_exprt &var)
20642058
/// false otherwise.
20652059
static bool universal_only_in_index(const string_constraintt &expr)
20662060
{
2067-
// For efficiency, we do a depth-first search of the
2068-
// body. The exprt visitors do a BFS and hide the stack/queue, so we would
2069-
// need to store a map from child to parent.
2070-
2071-
// The unsigned int represents index depth we are. For example, if we are
2072-
// considering the fragment `a[b[x]]` (not inside an index expression), then
2073-
// the stack would look something like `[..., (a, 0), (b, 1), (x, 2)]`.
2074-
typedef std::pair<exprt, unsigned> valuet;
2075-
std::stack<valuet> stack;
2076-
// We start at 0 since expr is not an index expression, so expr.body() is not
2077-
// in an index expression.
2078-
stack.push(valuet(expr.body(), 0));
2079-
while(!stack.empty())
2061+
for(auto it = expr.body().depth_begin(); it != expr.body().depth_end();)
20802062
{
2081-
// Inspect current value
2082-
const valuet cur=stack.top();
2083-
stack.pop();
2084-
const exprt e=cur.first;
2085-
const unsigned index_depth=cur.second;
2086-
const unsigned child_index_depth=index_depth+(e.id()==ID_index?0:1);
2087-
2088-
// If we found the universal variable not in an index_exprt, fail
2089-
if(e==expr.univ_var() && index_depth==0)
2063+
if(*it == expr.univ_var())
20902064
return false;
2065+
if(it->id() == ID_index)
2066+
it.next_sibling_or_parent();
20912067
else
2092-
forall_operands(it, e)
2093-
stack.push(valuet(*it, child_index_depth));
2068+
++it;
20942069
}
20952070
return true;
20962071
}

0 commit comments

Comments
 (0)