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-
2324static index_range_implementation_ptrt
2425make_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// ///////////////
377378static abstract_object_sett
378379non_destructive_compact (const abstract_object_sett &values);
380+ static abstract_object_sett destructive_compact (abstract_object_sett values);
379381static 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
391399static 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+
421455static bool value_is_not_contained_in (
422456 const abstract_object_pointert &object,
423457 const std::vector<constant_interval_exprt> &intervals)
0 commit comments