# Path: soap/common/base.py
# def base_dispatcher(dispatch_name='execute'):
#     class Dispatcher(BaseDispatcher):
#         pass
#     Dispatcher.dispatch_name = dispatch_name
#     return Dispatcher
# 
# Path: soap/semantics/functions/arithmetic.py
# class ArithmeticEvaluator(base_dispatcher()):
#     def generic_execute(self, expr, state):
#     def execute_numeral(self, expr, state):
#     def execute_PartitionLabel(self, expr, state):
#     def _execute_args(self, expr, state):
#     def execute_Variable(self, expr, state):
#     def execute_UnaryArithExpr(self, expr, state):
#     def execute_BinaryArithExpr(self, expr, state):
#     def execute_Subscript(self, expr, state):
#     def execute_AccessExpr(self, expr, state):
#     def execute_UpdateExpr(self, expr, state):
#     def execute_SelectExpr(self, expr, state):
#     def execute_FixExpr(self, expr, state):
#     def execute_PreUnrollExpr(self, expr, state):
#     def execute_MetaState(self, meta_state, state):
#     def __call__(self, expr, state):
#     def __eq__(self, other):
#     def __hash__(self):
# def _to_norm(value):
# def error_eval(expr, state, to_norm=True):
# 
# Path: soap/semantics/functions/boolean.py
# @cached
# def bool_eval(expr, state):
#     if state.is_bottom():
#         return state, state
#     constraints = construct(expr)
#     true_list, false_list = [], []
#     for cstr in constraints:
#         cstr_list = []
#         for cmp_expr in cstr:
#             cmp_eval_list = [
#                 _comparison_eval(cmp_expr, state)
#                 for cmp_expr in _bool_transform(cmp_expr)]
#             cstr_list += cmp_eval_list
#         if not cstr_list:
#             # empty, don't know how to constraint values
#             return state, state
#         true, false = zip(*cstr_list)
#         true_list.append(meet(true))
#         false_list.append(join(false))
#     return join(true_list), meet(false_list)
# 
# Path: soap/program/flow.py
# class CompositionalFlow(Flow):
#     """Flow for program composition.
# 
#     Combines multiple flow objects into a unified flow.
#     """
#     def __init__(self, flows=None):
#         super().__init__()
#         new_flows = []
#         for flow in (flows or []):
#             if isinstance(flow, CompositionalFlow):
#                 new_flows += flow.flows
#             else:
#                 new_flows.append(flow)
#         self.flows = tuple(new_flows)
# 
#     def transition(self, state):
#         for flow in self.flows:
#             state = flow.transition(state)
#         return state
# 
#     def __bool__(self):
#         return any(self.flows)
# 
#     def format(self):
#         return '\n'.join(flow.format() for flow in self.flows)
# 
#     def __eq__(self, other):
#         if type(self) is not type(other):
#             return False
#         return self.flows == other.flows
# 
#     def __repr__(self):
#         return '{cls}(flows={flows!r})'.format(
#             cls=self.__class__.__name__, flows=self.flows)
# 
#     def __hash__(self):
#         return hash(self.flows)
# 
# class WhileFlow(Flow):
#     """Program flow for conditional while loops.  """
# 
#     def __init__(self, conditional_expr, loop_flow):
#         super().__init__()
#         self.conditional_expr = conditional_expr
#         self.loop_flow = loop_flow
# 
#     def format(self):
#         loop_format = indent(self.loop_flow.format())
#         template = 'while ({conditional_expr}) {{\n{loop_format}}} '
#         return template.format(
#             conditional_expr=self.conditional_expr, loop_format=loop_format)
# 
#     def __repr__(self):
#         return '{cls}(conditional_expr={expr!r}, loop_flow={flow!r})'.format(
#             cls=self.__class__.__name__, expr=self.conditional_expr,
#             flow=self.loop_flow)
# 
#     def __eq__(self, other):
#         if type(self) is not type(other):
#             return False
#         return (self.conditional_expr == other.conditional_expr and
#                 self.loop_flow == other.loop_flow)
# 
#     def __hash__(self):
#         return hash((self.conditional_expr, self.loop_flow))


from soap.common import base_dispatcher
from soap.semantics.functions import arith_eval, bool_eval
from soap.program.flow import CompositionalFlow, WhileFlow
        return cls(bottom=True)

    def generic_visit(self, flow):
        raise TypeError('No method to visit {!r}'.format(flow))

    def visit_SkipFlow(self, flow):
        return self

    visit_InputFlow = visit_OutputFlow = visit_SkipFlow

    def visit_AssignFlow(self, flow):
        return self.immu_update(flow.var, arith_eval(flow.expr, self))

    def visit_IfFlow(self, flow):
        bool_expr = flow.conditional_expr
        true_split, false_split = bool_eval(bool_expr, self)
        true_split = true_split.transition(flow.true_flow)
        false_split = false_split.transition(flow.false_flow)
        return true_split | false_split

    def visit_WhileFlow(self, flow):
        raise NotImplementedError('Override this method.')

    def visit_ForFlow(self, flow):
        state = self.transition(flow.init_flow)
        loop_flows = flow.loop_flow
        if isinstance(loop_flows, CompositionalFlow):
            loop_flows = loop_flows.flows
        else:
            loop_flows = [loop_flows]

# Path: soap/common/base.py
# def base_dispatcher(dispatch_name='execute'):
#     class Dispatcher(BaseDispatcher):
#         pass
#     Dispatcher.dispatch_name = dispatch_name
#     return Dispatcher
# 
# Path: soap/semantics/functions/arithmetic.py
# class ArithmeticEvaluator(base_dispatcher()):
#     def generic_execute(self, expr, state):
#     def execute_numeral(self, expr, state):
#     def execute_PartitionLabel(self, expr, state):
#     def _execute_args(self, expr, state):
#     def execute_Variable(self, expr, state):
#     def execute_UnaryArithExpr(self, expr, state):
#     def execute_BinaryArithExpr(self, expr, state):
#     def execute_Subscript(self, expr, state):
#     def execute_AccessExpr(self, expr, state):
#     def execute_UpdateExpr(self, expr, state):
#     def execute_SelectExpr(self, expr, state):
#     def execute_FixExpr(self, expr, state):
#     def execute_PreUnrollExpr(self, expr, state):
#     def execute_MetaState(self, meta_state, state):
#     def __call__(self, expr, state):
#     def __eq__(self, other):
#     def __hash__(self):
# def _to_norm(value):
# def error_eval(expr, state, to_norm=True):
# 
# Path: soap/semantics/functions/boolean.py
# @cached
# def bool_eval(expr, state):
#     if state.is_bottom():
#         return state, state
#     constraints = construct(expr)
#     true_list, false_list = [], []
#     for cstr in constraints:
#         cstr_list = []
#         for cmp_expr in cstr:
#             cmp_eval_list = [
#                 _comparison_eval(cmp_expr, state)
#                 for cmp_expr in _bool_transform(cmp_expr)]
#             cstr_list += cmp_eval_list
#         if not cstr_list:
#             # empty, don't know how to constraint values
#             return state, state
#         true, false = zip(*cstr_list)
#         true_list.append(meet(true))
#         false_list.append(join(false))
#     return join(true_list), meet(false_list)
# 
# Path: soap/program/flow.py
# class CompositionalFlow(Flow):
#     """Flow for program composition.
# 
#     Combines multiple flow objects into a unified flow.
#     """
#     def __init__(self, flows=None):
#         super().__init__()
#         new_flows = []
#         for flow in (flows or []):
#             if isinstance(flow, CompositionalFlow):
#                 new_flows += flow.flows
#             else:
#                 new_flows.append(flow)
#         self.flows = tuple(new_flows)
# 
#     def transition(self, state):
#         for flow in self.flows:
#             state = flow.transition(state)
#         return state
# 
#     def __bool__(self):
#         return any(self.flows)
# 
#     def format(self):
#         return '\n'.join(flow.format() for flow in self.flows)
# 
#     def __eq__(self, other):
#         if type(self) is not type(other):
#             return False
#         return self.flows == other.flows
# 
#     def __repr__(self):
#         return '{cls}(flows={flows!r})'.format(
#             cls=self.__class__.__name__, flows=self.flows)
# 
#     def __hash__(self):
#         return hash(self.flows)
# 
# class WhileFlow(Flow):
#     """Program flow for conditional while loops.  """
# 
#     def __init__(self, conditional_expr, loop_flow):
#         super().__init__()
#         self.conditional_expr = conditional_expr
#         self.loop_flow = loop_flow
# 
#     def format(self):
#         loop_format = indent(self.loop_flow.format())
#         template = 'while ({conditional_expr}) {{\n{loop_format}}} '
#         return template.format(
#             conditional_expr=self.conditional_expr, loop_format=loop_format)
# 
#     def __repr__(self):
#         return '{cls}(conditional_expr={expr!r}, loop_flow={flow!r})'.format(
#             cls=self.__class__.__name__, expr=self.conditional_expr,
#             flow=self.loop_flow)
# 
#     def __eq__(self, other):
#         if type(self) is not type(other):
#             return False
#         return (self.conditional_expr == other.conditional_expr and
#                 self.loop_flow == other.loop_flow)
# 
#     def __hash__(self):
#         return hash((self.conditional_expr, self.loop_flow))


# Path: soap/semantics/state/base.py
from soap.common import base_dispatcher
from soap.semantics.functions import arith_eval, bool_eval
from soap.program.flow import CompositionalFlow, WhileFlow

        return cls(bottom=True)

    def generic_visit(self, flow):
        raise TypeError('No method to visit {!r}'.format(flow))

    def visit_SkipFlow(self, flow):
        return self

    visit_InputFlow = visit_OutputFlow = visit_SkipFlow

    def visit_AssignFlow(self, flow):
        return self.immu_update(flow.var, arith_eval(flow.expr, self))

    def visit_IfFlow(self, flow):
        bool_expr = flow.conditional_expr
        true_split, false_split = bool_eval(bool_expr, self)
        true_split = true_split.transition(flow.true_flow)
        false_split = false_split.transition(flow.false_flow)
        return true_split | false_split

    def visit_WhileFlow(self, flow):
        raise NotImplementedError('Override this method.')

    def visit_ForFlow(self, flow):
        state = self.transition(flow.init_flow)
        loop_flows = flow.loop_flow
        if isinstance(loop_flows, CompositionalFlow):
            loop_flows = loop_flows.flows
        else:
            loop_flows = [loop_flows]

        loop_flow = CompositionalFlow(loop_flows + [flow.incr_flow])