@@ -145,11 +145,16 @@ literalt prop_conv_solvert::convert(const exprt &expr)
145
145
if (!result.second )
146
146
return result.first ->second ;
147
147
148
+ // new entry
149
+ if (record_cache_iterators)
150
+ cache_iterators.push_back (result.first );
151
+
148
152
literalt literal = convert_bool (expr);
149
153
150
154
// insert into cache
151
155
152
156
result.first ->second = literal;
157
+
153
158
if (freeze_all && !literal.is_constant ())
154
159
prop.set_frozen (literal);
155
160
@@ -276,23 +281,47 @@ literalt prop_conv_solvert::convert_bool(const exprt &expr)
276
281
const let_exprt &let_expr = to_let_expr (expr);
277
282
278
283
// first check whether this is all boolean
279
- if (
280
- let_expr.value ().type ().id () == ID_bool &&
281
- let_expr.where ().type ().id () == ID_bool)
284
+ DATA_INVARIANT (
285
+ let_expr.value ().type ().id () == ID_bool,
286
+ " Boolean let must have Boolean value" );
287
+ DATA_INVARIANT (
288
+ let_expr.where ().type ().id () == ID_bool,
289
+ " Boolean let must have Boolean subexpression" );
290
+
291
+ literalt value = convert (let_expr.value ());
292
+
293
+ const irep_idt &id = let_expr.symbol ().get_identifier ();
294
+ auto emplace_result = symbols.emplace (id, literalt ());
295
+ literalt old_variable;
296
+
297
+ // We do not expect the identifier to be unique; in particular, nesting
298
+ // is supported. Thus, do we need to save a value from an outer scope?
299
+ if (!emplace_result.second )
282
300
{
283
- literalt value = convert (let_expr.value ());
284
-
285
- // We expect the identifier of the bound symbols to be unique,
286
- // and thus, these can go straight into the symbol map.
287
- // This property also allows us to cache any subexpressions.
288
- const irep_idt &id = let_expr.symbol ().get_identifier ();
289
- symbols[id] = value;
290
- literalt result = convert (let_expr.where ());
291
-
292
- // remove again
293
- symbols.erase (id);
294
- return result;
301
+ // insertion did not take place
302
+ old_variable = emplace_result.first ->second ;
303
+ emplace_result.first ->second = value;
295
304
}
305
+
306
+ // record all newly added cache entries
307
+ bool previous_record_cache_iterators = record_cache_iterators;
308
+ std::size_t previous_cache_iterators_size = cache_iterators.size ();
309
+ record_cache_iterators = true ;
310
+
311
+ // recursive call
312
+ literalt result = convert (let_expr.where ());
313
+
314
+ // clear cache_iterators that use the bound symbol from the cache
315
+ cache_iterators.resize (previous_cache_iterators_size);
316
+ record_cache_iterators = previous_record_cache_iterators;
317
+
318
+ // remove/restore symbol
319
+ if (emplace_result.second )
320
+ emplace_result.first ->second = old_variable;
321
+ else
322
+ symbols.erase (emplace_result.first );
323
+
324
+ return result;
296
325
}
297
326
298
327
return convert_rest (expr);
0 commit comments