Skip to content

Commit dee9072

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 2af6ea1 commit dee9072

File tree

2 files changed

+68
-4
lines changed

2 files changed

+68
-4
lines changed

src/analyses/variable-sensitivity/value_set_abstract_object.cpp

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@
99
/// \file
1010
/// Value Set Abstract Object
1111

12-
#include "interval_abstract_value.h"
12+
#include <analyses/variable-sensitivity/abstract_environment.h>
1313
#include <analyses/variable-sensitivity/constant_abstract_value.h>
1414
#include <analyses/variable-sensitivity/context_abstract_object.h>
15+
#include <analyses/variable-sensitivity/interval_abstract_value.h>
1516
#include <analyses/variable-sensitivity/value_set_abstract_object.h>
1617

18+
#include <util/arith_tools.h>
1719
#include <util/make_unique.h>
20+
#include <util/simplify_expr.h>
1821

1922
#include <algorithm>
2023

21-
#include "abstract_environment.h"
22-
2324
static index_range_implementation_ptrt
2425
make_value_set_index_range(const std::set<exprt> &vals);
2526

@@ -376,6 +377,7 @@ static bool are_any_top(const abstract_object_sett &set)
376377
/////////////////
377378
static abstract_object_sett
378379
non_destructive_compact(const abstract_object_sett &values);
380+
static abstract_object_sett destructive_compact(abstract_object_sett values);
379381
static bool value_is_not_contained_in(
380382
const abstract_object_pointert &object,
381383
const std::vector<constant_interval_exprt> &intervals);
@@ -385,7 +387,13 @@ static abstract_object_sett compact_values(const abstract_object_sett &values)
385387
if(values.size() <= value_set_abstract_objectt::max_value_set_size)
386388
return values;
387389

388-
return non_destructive_compact(values);
390+
auto compacted = non_destructive_compact(values);
391+
if(compacted.size() <= value_set_abstract_objectt::max_value_set_size)
392+
return compacted;
393+
394+
compacted = destructive_compact(values);
395+
396+
return compacted;
389397
}
390398

391399
static abstract_object_sett
@@ -418,6 +426,32 @@ non_destructive_compact(const abstract_object_sett &values)
418426
return compacted;
419427
}
420428

429+
exprt eval_expr(exprt e)
430+
{
431+
auto dummy_symbol_table = symbol_tablet{};
432+
auto dummy_namespace = namespacet{dummy_symbol_table};
433+
434+
return simplify_expr(e, dummy_namespace);
435+
}
436+
437+
static abstract_object_sett destructive_compact(abstract_object_sett values)
438+
{
439+
auto width = values.to_interval();
440+
auto slice_width = eval_expr(div_exprt(
441+
minus_exprt(width.get_upper(), width.get_lower()),
442+
from_integer(3, width.type())));
443+
444+
auto lower_slice = constant_interval_exprt(
445+
width.get_lower(), eval_expr(plus_exprt(width.get_lower(), slice_width)));
446+
auto upper_slice = constant_interval_exprt(
447+
eval_expr(minus_exprt(width.get_upper(), slice_width)), width.get_upper());
448+
449+
values.insert(interval_abstract_valuet::make_interval(lower_slice));
450+
values.insert(interval_abstract_valuet::make_interval(upper_slice));
451+
452+
return non_destructive_compact(values);
453+
} // destructive_compact
454+
421455
static bool value_is_not_contained_in(
422456
const abstract_object_pointert &object,
423457
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)