def new_stage(protocol, stage, valuation, mem):
    new_valuation = new_stage_valuation(protocol, valuation, stage.disabled)

    if is_stable_or_dead(protocol, new_valuation, stage.disabled):
        return Stage(Formula(new_valuation),
                     new_valuation,
                     stage.disabled,
                     speed=Speed.ZERO,
                     parent=stage)

    F, J = eventually_disabled(protocol, new_valuation, stage.disabled, mem)

    # Compute new_formula (Φ) and new_disabled (T)
    if len(F) > 0:
        if len(J) > 0:
            new_disabled = set(stage.disabled) | set(J)
            new_formula = Formula(new_valuation, new_disabled)

            if v_disabled(J, valuation):
                new_formula.assert_valuation(valuation)
            elif v_enabled(J, valuation):
                K = posts_from_pres(protocol, new_valuation, J)
                new_formula.assert_some_pair_present(K)

            # Compute speed
            if is_very_fast(protocol, new_valuation, stage.disabled):
                new_speed = Speed.QUADRATIC
            elif is_fast(protocol, new_valuation, stage.disabled):
                new_speed = Speed.QUADRATIC_LOG
            else:
                new_speed = Speed.CUBIC
        else:
            new_disabled = set(stage.disabled) | set(F)
            new_formula = Formula(new_valuation, new_disabled)
            new_speed = Speed.POLYNOMIAL
    else:
        new_disabled = set(stage.disabled)
        new_formula = Formula(new_valuation, new_disabled)
        new_speed = Speed.EXPONENTIAL

        I = compute_I(protocol, new_valuation, stage.disabled)

        if any(valuation[Var(q)] is True for q in I):
            L = compute_L(protocol, new_valuation, stage.disabled, I)

            new_formula.assert_all_states_absent(I)
            new_formula.assert_some_pair_present(L)
        elif all(valuation[Var(q)] is False for q in I):
            new_formula.assert_valuation(valuation)
        else:
            new_formula.assert_all_states_absent(I)

    return Stage(new_formula,
                 new_valuation,
                 new_disabled,
                 speed=new_speed,
                 parent=stage)
Beispiel #2
0
    def _construct_tree(self):
        def add_vertex(stage):
            vertex = self._graph.add_vertex()
            index = self._graph.vertex_index[vertex]

            self._vertices[index] = stage

            return index

        root_formula = Formula()
        root_formula.assert_some_states_present(self._protocol.initial_states)
        root_formula.assert_all_states_absent(self._protocol.states -
                                              self._protocol.initial_states)

        root_stage = Stage(root_formula, Valuation(), set(), speed=Speed.ZERO)
        root_index = add_vertex(root_stage)
        unexplored = [(root_index, root_stage)]
        mem = {}  # for memoization in computation of J

        while len(unexplored) > 0:
            index, stage = unexplored.pop()
            valuations = stage.formula.solutions()
            has_children = False

            for val in valuations:
                child_stage = new_stage(self._protocol, stage, val, mem)

                if not child_stage.is_redundant():
                    child_index = add_vertex(child_stage)
                    self._graph.add_edge(index, child_index)
                    unexplored.append((child_index, child_stage))
                    has_children = True

            if not has_children:
                self._leaves.add(index)

            self._speed = max(self._speed, stage.speed)