Skip to content

Commit a4a4073

Browse files
author
Daniel Kroening
committed
replace recursion in letify_rec by loop
This avoids stack overflow in the case of expressions with many unique subexpressions. PR #4395 is an exemplar.
1 parent 960d6e7 commit a4a4073

File tree

2 files changed

+22
-20
lines changed

2 files changed

+22
-20
lines changed

src/solvers/smt2/letify.cpp

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,26 +46,29 @@ void letifyt::collect_bindings(
4646
let_order.push_back(expr);
4747
}
4848

49-
exprt letifyt::letify_rec(
49+
exprt letifyt::letify(
5050
const exprt &expr,
51-
std::vector<exprt> &let_order,
52-
const seen_expressionst &map,
53-
std::size_t i)
51+
const std::vector<exprt> &let_order,
52+
const seen_expressionst &map)
5453
{
55-
if(i >= let_order.size())
56-
return substitute_let(expr, map);
54+
exprt result = substitute_let(expr, map);
5755

58-
exprt current = let_order[i];
59-
INVARIANT(
60-
map.find(current) != map.end(), "expression should have been seen already");
56+
// go backwards in let order
57+
for(auto r_it = let_order.rbegin(); r_it != let_order.rend(); r_it++)
58+
{
59+
const exprt &current = *r_it;
6160

62-
if(map.find(current)->second.count < LET_COUNT)
63-
return letify_rec(expr, let_order, map, i + 1);
61+
auto m_it = map.find(current);
62+
INVARIANT(m_it != map.end(), "expression should have been seen already");
63+
64+
if(m_it->second.count >= LET_COUNT)
65+
{
66+
result = let_exprt(
67+
m_it->second.let_symbol, substitute_let(current, map), result);
68+
}
69+
}
6470

65-
return let_exprt(
66-
map.find(current)->second.let_symbol,
67-
substitute_let(current, map),
68-
letify_rec(expr, let_order, map, i + 1));
71+
return result;
6972
}
7073

7174
exprt letifyt::operator()(const exprt &expr)
@@ -75,7 +78,7 @@ exprt letifyt::operator()(const exprt &expr)
7578

7679
collect_bindings(expr, map, let_order);
7780

78-
return letify_rec(expr, let_order, map, 0);
81+
return letify(expr, let_order, map);
7982
}
8083

8184
exprt letifyt::substitute_let(const exprt &expr, const seen_expressionst &map)

src/solvers/smt2/letify.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,10 @@ class letifyt
4646
seen_expressionst &map,
4747
std::vector<exprt> &let_order);
4848

49-
static exprt letify_rec(
49+
static exprt letify(
5050
const exprt &expr,
51-
std::vector<exprt> &let_order,
52-
const seen_expressionst &map,
53-
std::size_t i);
51+
const std::vector<exprt> &let_order,
52+
const seen_expressionst &map);
5453

5554
static exprt substitute_let(const exprt &expr, const seen_expressionst &map);
5655
};

0 commit comments

Comments
 (0)