Skip to content

Commit 09d2199

Browse files
committed
Build value_set_evaluator - wraps value_set evaluation into a class
1 parent a13d36d commit 09d2199

File tree

1 file changed

+121
-137
lines changed

1 file changed

+121
-137
lines changed

src/analyses/variable-sensitivity/abstract_value_object.cpp

Lines changed: 121 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -496,22 +496,6 @@ abstract_object_pointert intervals_expression_transform(
496496

497497
/////////////////////////////////////////////////////////
498498
// value_set expression transform
499-
static abstract_object_pointert value_set_evaluate_conditional(
500-
const typet &type,
501-
const std::vector<value_ranget> &operands,
502-
const abstract_environmentt &env,
503-
const namespacet &ns);
504-
505-
static std::vector<value_ranget>
506-
unwrap_operands(const std::vector<abstract_object_pointert> &operands);
507-
508-
/// Helper for converting context objects into its abstract-value children
509-
/// \p maybe_wrapped: either an abstract value (or a set of those) or one
510-
/// wrapped in a context
511-
/// \return an abstract value without context (though it might be as set)
512-
static abstract_object_pointert
513-
maybe_unwrap_context(const abstract_object_pointert &maybe_wrapped);
514-
515499
static exprt rewrite_expression(
516500
const exprt &expr,
517501
const std::vector<abstract_object_pointert> &ops);
@@ -564,155 +548,155 @@ abstract_object_sett evaluate_each_combination(
564548
return results;
565549
}
566550

567-
static abstract_object_pointert resolve_new_values(
568-
const abstract_object_sett &new_values,
569-
const abstract_environmentt &environment);
551+
class value_set_evaluator
552+
{
553+
public:
554+
value_set_evaluator(
555+
const exprt &e,
556+
const std::vector<abstract_object_pointert> &ops,
557+
const abstract_environmentt &env,
558+
const namespacet &n)
559+
: expression(e), operands(ops), environment(env), ns(n)
560+
{
561+
PRECONDITION(expression.operands().size() == operands.size());
562+
}
570563

571-
static abstract_object_pointert
572-
resolve_values(const abstract_object_sett &new_values);
573-
static abstract_object_sett
574-
unwrap_and_extract_values(const abstract_object_sett &values);
575-
static abstract_object_pointert
576-
maybe_extract_single_value(const abstract_object_pointert &maybe_singleton);
564+
abstract_object_pointert operator()() const
565+
{
566+
return transform();
567+
}
577568

578-
static abstract_object_pointert value_set_expression_transform(
579-
const exprt &expr,
580-
const std::vector<abstract_object_pointert> &operands,
581-
const abstract_environmentt &environment,
582-
const namespacet &ns)
583-
{
584-
PRECONDITION(operands.size() == expr.operands().size());
569+
private:
570+
abstract_object_pointert transform() const
571+
{
572+
auto collective_operands = unwrap_operands();
585573

586-
auto collective_operands = unwrap_operands(operands);
574+
if(expression.id() == ID_if)
575+
return value_set_evaluate_conditional(collective_operands);
587576

588-
if(expr.id() == ID_if)
589-
return value_set_evaluate_conditional(
590-
expr.type(), collective_operands, environment, ns);
577+
auto resulting_objects = evaluate_each_combination(
578+
collective_operands, expression, environment, ns);
591579

592-
auto resulting_objects =
593-
evaluate_each_combination(collective_operands, expr, environment, ns);
580+
return resolve_new_values(resulting_objects);
581+
}
594582

595-
return resolve_new_values(resulting_objects, environment);
596-
}
583+
std::vector<value_ranget> unwrap_operands() const
584+
{
585+
auto unwrapped = std::vector<value_ranget>{};
597586

598-
abstract_object_pointert value_set_evaluate_conditional(
599-
const typet &type,
600-
const std::vector<value_ranget> &operands,
601-
const abstract_environmentt &env,
602-
const namespacet &ns)
603-
{
604-
auto const &condition = operands[0];
587+
for(const auto &op : operands)
588+
{
589+
auto av = std::dynamic_pointer_cast<const abstract_value_objectt>(
590+
op->unwrap_context());
591+
INVARIANT(av, "should be an abstract value object");
592+
unwrapped.emplace_back(av->value_range());
593+
}
605594

606-
auto const &true_result = operands[1];
607-
auto const &false_result = operands[2];
595+
return unwrapped;
596+
}
608597

609-
auto all_true = true;
610-
auto all_false = true;
611-
for(auto v : condition)
598+
static abstract_object_sett
599+
unwrap_and_extract_values(const abstract_object_sett &values)
612600
{
613-
auto expr = v->to_constant();
614-
all_true = all_true && expr.is_true();
615-
all_false = all_false && expr.is_false();
601+
abstract_object_sett unwrapped_values;
602+
for(auto const &value : values)
603+
{
604+
unwrapped_values.insert(
605+
maybe_extract_single_value(value->unwrap_context()));
606+
}
607+
608+
return unwrapped_values;
616609
}
617-
auto indeterminate = !all_true && !all_false;
618610

619-
abstract_object_sett resulting_objects;
620-
if(all_true || indeterminate)
621-
resulting_objects.insert(true_result);
622-
if(all_false || indeterminate)
623-
resulting_objects.insert(false_result);
624-
return resolve_new_values(resulting_objects, env);
625-
}
611+
static abstract_object_pointert
612+
maybe_extract_single_value(const abstract_object_pointert &maybe_singleton)
613+
{
614+
auto const &value_as_set =
615+
std::dynamic_pointer_cast<const value_set_tag>(maybe_singleton);
616+
if(value_as_set)
617+
{
618+
PRECONDITION(value_as_set->get_values().size() == 1);
619+
PRECONDITION(!std::dynamic_pointer_cast<const context_abstract_objectt>(
620+
value_as_set->get_values().first()));
626621

627-
static std::vector<value_ranget>
628-
unwrap_operands(const std::vector<abstract_object_pointert> &operands)
629-
{
630-
auto unwrapped = std::vector<value_ranget>{};
622+
return value_as_set->get_values().first();
623+
}
624+
else
625+
return maybe_singleton;
626+
}
631627

632-
for(const auto &op : operands)
628+
abstract_object_pointert
629+
resolve_new_values(const abstract_object_sett &new_values) const
633630
{
634-
auto av = std::dynamic_pointer_cast<const abstract_value_objectt>(
635-
maybe_unwrap_context(op));
636-
// INVARIANT(av, "should be an abstract value object");
637-
if(av)
638-
unwrapped.emplace_back(av->value_range());
639-
else // Forthcoming work will eliminate this line
640-
unwrapped.emplace_back(value_ranget{make_single_value_range(op)});
631+
auto result = resolve_values(new_values);
632+
return environment.add_object_context(result);
641633
}
642634

643-
return unwrapped;
644-
}
635+
static abstract_object_pointert
636+
resolve_values(const abstract_object_sett &new_values)
637+
{
638+
PRECONDITION(!new_values.empty());
645639

646-
static exprt rewrite_expression(
647-
const exprt &expr,
648-
const std::vector<abstract_object_pointert> &ops)
649-
{
650-
auto operands_expr = exprt::operandst{};
651-
for(auto v : ops)
652-
operands_expr.push_back(v->to_constant());
653-
auto rewritten_expr = exprt(expr.id(), expr.type(), std::move(operands_expr));
654-
return rewritten_expr;
655-
}
640+
auto unwrapped_values = unwrap_and_extract_values(new_values);
656641

657-
static abstract_object_pointert
658-
maybe_unwrap_context(const abstract_object_pointert &maybe_wrapped)
659-
{
660-
auto const &context_value =
661-
std::dynamic_pointer_cast<const context_abstract_objectt>(maybe_wrapped);
642+
if(unwrapped_values.size() > value_set_abstract_objectt::max_value_set_size)
643+
return unwrapped_values.to_interval();
662644

663-
return context_value ? context_value->unwrap_context() : maybe_wrapped;
664-
}
665-
666-
static abstract_object_sett
667-
unwrap_and_extract_values(const abstract_object_sett &values)
668-
{
669-
abstract_object_sett unwrapped_values;
670-
for(auto const &value : values)
671-
{
672-
unwrapped_values.insert(
673-
maybe_extract_single_value(maybe_unwrap_context(value)));
645+
const auto &type = new_values.first()->type();
646+
auto result = std::make_shared<value_set_abstract_objectt>(type);
647+
result->set_values(unwrapped_values);
648+
return result;
674649
}
675650

676-
return unwrapped_values;
677-
}
678-
679-
static abstract_object_pointert
680-
maybe_extract_single_value(const abstract_object_pointert &maybe_singleton)
681-
{
682-
auto const &value_as_set =
683-
std::dynamic_pointer_cast<const value_set_tag>(maybe_singleton);
684-
if(value_as_set)
651+
abstract_object_pointert
652+
value_set_evaluate_conditional(const std::vector<value_ranget> &ops) const
685653
{
686-
PRECONDITION(value_as_set->get_values().size() == 1);
687-
PRECONDITION(!std::dynamic_pointer_cast<const context_abstract_objectt>(
688-
value_as_set->get_values().first()));
654+
auto const &condition = ops[0];
655+
656+
auto const &true_result = ops[1];
657+
auto const &false_result = ops[2];
689658

690-
return value_as_set->get_values().first();
659+
auto all_true = true;
660+
auto all_false = true;
661+
for(const auto &v : condition)
662+
{
663+
auto expr = v->to_constant();
664+
all_true = all_true && expr.is_true();
665+
all_false = all_false && expr.is_false();
666+
}
667+
auto indeterminate = !all_true && !all_false;
668+
669+
abstract_object_sett resulting_objects;
670+
if(all_true || indeterminate)
671+
resulting_objects.insert(true_result);
672+
if(all_false || indeterminate)
673+
resulting_objects.insert(false_result);
674+
return resolve_new_values(resulting_objects);
691675
}
692-
else
693-
return maybe_singleton;
694-
}
695676

696-
static abstract_object_pointert resolve_new_values(
697-
const abstract_object_sett &new_values,
698-
const abstract_environmentt &environment)
677+
const exprt &expression;
678+
const std::vector<abstract_object_pointert> &operands;
679+
const abstract_environmentt &environment;
680+
const namespacet &ns;
681+
};
682+
683+
static abstract_object_pointert value_set_expression_transform(
684+
const exprt &expr,
685+
const std::vector<abstract_object_pointert> &operands,
686+
const abstract_environmentt &environment,
687+
const namespacet &ns)
699688
{
700-
auto result = resolve_values(new_values);
701-
return environment.add_object_context(result);
689+
auto evaluator = value_set_evaluator(expr, operands, environment, ns);
690+
return evaluator();
702691
}
703692

704-
static abstract_object_pointert
705-
resolve_values(const abstract_object_sett &new_values)
693+
static exprt rewrite_expression(
694+
const exprt &expr,
695+
const std::vector<abstract_object_pointert> &ops)
706696
{
707-
PRECONDITION(!new_values.empty());
708-
709-
auto unwrapped_values = unwrap_and_extract_values(new_values);
710-
711-
if(unwrapped_values.size() > value_set_abstract_objectt::max_value_set_size)
712-
return unwrapped_values.to_interval();
713-
714-
const auto &type = new_values.first()->type();
715-
auto result = std::make_shared<value_set_abstract_objectt>(type);
716-
result->set_values(unwrapped_values);
717-
return result;
697+
auto operands_expr = exprt::operandst{};
698+
for(auto v : ops)
699+
operands_expr.push_back(v->to_constant());
700+
auto rewritten_expr = exprt(expr.id(), expr.type(), std::move(operands_expr));
701+
return rewritten_expr;
718702
}

0 commit comments

Comments
 (0)