Skip to content

Commit c365441

Browse files
committed
value_set_abstract_object destructive merge
Generate two intervals covering the upper and lower part of the value sets range of values, then merge values into those.
1 parent 9e2904c commit c365441

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

src/analyses/variable-sensitivity/value_set_abstract_object.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ static bool are_any_top(const abstract_object_sett &set)
350350
/////////////////
351351
static abstract_object_sett
352352
non_destructive_compact(const abstract_object_sett &values);
353+
static abstract_object_sett destructive_compact(abstract_object_sett values);
353354
static bool value_is_not_contained_in(
354355
const abstract_object_pointert &object,
355356
const std::vector<constant_interval_exprt> &intervals);
@@ -359,7 +360,13 @@ static abstract_object_sett compact_values(const abstract_object_sett &values)
359360
if(values.size() <= value_set_abstract_objectt::max_value_set_size)
360361
return values;
361362

362-
return non_destructive_compact(values);
363+
auto compacted = non_destructive_compact(values);
364+
if(compacted.size() <= value_set_abstract_objectt::max_value_set_size)
365+
return compacted;
366+
367+
compacted = destructive_compact(values);
368+
369+
return compacted;
363370
}
364371

365372
static abstract_object_sett
@@ -392,6 +399,32 @@ non_destructive_compact(const abstract_object_sett &values)
392399
return compacted;
393400
}
394401

402+
exprt eval_expr(exprt e)
403+
{
404+
auto dummy_symbol_table = symbol_tablet{};
405+
auto dummy_namespace = namespacet{dummy_symbol_table};
406+
407+
return simplify_expr(e, dummy_namespace);
408+
}
409+
410+
static abstract_object_sett destructive_compact(abstract_object_sett values)
411+
{
412+
auto width = values.to_interval();
413+
auto slice_width = eval_expr(div_exprt(
414+
minus_exprt(width.get_upper(), width.get_lower()),
415+
from_integer(3, width.type())));
416+
417+
auto lower_slice = constant_interval_exprt(
418+
width.get_lower(), eval_expr(plus_exprt(width.get_lower(), slice_width)));
419+
auto upper_slice = constant_interval_exprt(
420+
eval_expr(minus_exprt(width.get_upper(), slice_width)), width.get_upper());
421+
422+
values.insert(interval_abstract_valuet::make_interval(lower_slice));
423+
values.insert(interval_abstract_valuet::make_interval(upper_slice));
424+
425+
return non_destructive_compact(values);
426+
} // destructive_compact
427+
395428
static bool value_is_not_contained_in(
396429
const abstract_object_pointert &object,
397430
const std::vector<constant_interval_exprt> &intervals)

unit/analyses/variable-sensitivity/value_set_abstract_object/compacting.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,4 +166,34 @@ SCENARIO(
166166
}
167167
}
168168
}
169+
170+
GIVEN("compact values to create new intervals")
171+
{
172+
const exprt interval_1_4 = constant_interval_exprt(val1, val4);
173+
const exprt interval_9_12 = constant_interval_exprt(val9, val12);
174+
175+
WHEN("compacting { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }")
176+
{
177+
auto value_set = make_value_set(
178+
{val1,
179+
val2,
180+
val3,
181+
val4,
182+
val5,
183+
val6,
184+
val7,
185+
val8,
186+
val9,
187+
val10,
188+
val11,
189+
val12},
190+
environment,
191+
ns);
192+
THEN("{ [1, 4], 5, 6, 7, 8, [9, 12] }")
193+
{
194+
EXPECT(
195+
value_set, {val5, val6, val7, val8, interval_1_4, interval_9_12});
196+
}
197+
}
198+
}
169199
}

0 commit comments

Comments
 (0)