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)
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)