@@ -116,6 +116,7 @@ static abstract_object_pointert
116116maybe_extract_single_value (const abstract_object_pointert &maybe_singleton);
117117
118118static bool are_any_top (const abstract_object_sett &set);
119+ static bool is_set_extreme (const typet &type, const abstract_object_sett &set);
119120
120121static abstract_object_sett compact_values (const abstract_object_sett &values);
121122static abstract_object_sett widen_value_set (
@@ -296,7 +297,7 @@ void value_set_abstract_objectt::set_values(
296297 const abstract_object_sett &other_values)
297298{
298299 PRECONDITION (!other_values.empty ());
299- if (are_any_top (other_values))
300+ if (are_any_top (other_values) || is_set_extreme ( type (), other_values) )
300301 {
301302 set_top ();
302303 }
@@ -391,6 +392,65 @@ static bool are_any_top(const abstract_object_sett &set)
391392 }) != set.end ();
392393}
393394
395+ using set_predicate_fn = std::function<bool (const abstract_value_objectt &)>;
396+ static bool set_contains (const abstract_object_sett &set, set_predicate_fn pred)
397+ {
398+ return std::find_if (
399+ set.begin (),
400+ set.end (),
401+ [&pred](const abstract_object_pointert &obj) {
402+ const auto &value =
403+ std::dynamic_pointer_cast<const abstract_value_objectt>(obj);
404+ return pred (*value);
405+ }) != set.end ();
406+ }
407+
408+ static bool set_has_extremes (
409+ const abstract_object_sett &set,
410+ set_predicate_fn lower_fn,
411+ set_predicate_fn upper_fn)
412+ {
413+ bool has_lower = set_contains (set, lower_fn);
414+ if (!has_lower)
415+ return false ;
416+
417+ bool has_upper = set_contains (set, upper_fn);
418+ return has_upper;
419+ }
420+
421+ static bool is_set_extreme (const typet &type, const abstract_object_sett &set)
422+ {
423+ if (type.id () == ID_bool)
424+ {
425+ return set_has_extremes (
426+ set,
427+ [](const abstract_value_objectt &value) {
428+ auto c = value.to_constant ();
429+ return c.is_false () || (c.id () == ID_min);
430+ },
431+ [](const abstract_value_objectt &value) {
432+ auto c = value.to_constant ();
433+ return c.is_true () || (c.id () == ID_max);
434+ });
435+ }
436+
437+ if (type.id () == ID_c_bool)
438+ {
439+ return set_has_extremes (
440+ set,
441+ [](const abstract_value_objectt &value) {
442+ auto c = value.to_constant ();
443+ return c.is_zero () || (c.id () == ID_min);
444+ },
445+ [](const abstract_value_objectt &value) {
446+ auto c = value.to_constant ();
447+ return c.is_one () || (c.id () == ID_max);
448+ });
449+ }
450+
451+ return false ;
452+ }
453+
394454// ///////////////
395455static abstract_object_sett
396456non_destructive_compact (const abstract_object_sett &values);
0 commit comments