def is_fast(protocol, valuation, disabled): graph, vertices, edges = transformation_graph(protocol, valuation, disabled) components, _, is_bottom = label_components(graph, attractors=True) U = {q for q in vertices if not is_bottom[components[vertices[q]]]} R = {q: set() for q in vertices} expV = set() for (p, q) in edges: if components[vertices[p]] != components[vertices[q]]: for t in edges[p, q]: expV.add(t.pre) if t.pre not in disabled: for r in (set(t.pre) & U): R[r].add(t.pre) for q in U: formula = Formula(valuation, disabled) formula.assert_some_pair_present(expV) formula.assert_some_states_present({q}) if not formula.implies_some_present_tautology_check(R[q]): return False return True
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)
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 def add_edge(i, j): self._graph.add_edge(i, j) phi = Formula() phi.assert_some_states_present(self.protocol.initial_states) root_stage = Stage(set(), set(), set(), set(), phi) root_index = add_vertex(root_stage) unprocessed = [(root_index, root_stage)] mem = {"K": {}, "K_": {}} # For memoization while len(unprocessed) > 0: index, stage = unprocessed.pop(0) children, refined = new_stages(self.protocol, stage, mem, self._use_t_invariants) if not refined: # TODO find criterion to continue if refinement fails self._failed_stages.add(index) continue #self._strong_witness = False #self._all_good = False # If node failed to be expanded, # then flag as failure and skip to next iteration if children is None: self._failed_stages.add(index) continue # Check termination witness if self._check_termination_witness: witness = check_termination_witness(self.protocol, stage, refined) if witness is None: self._failed_witness_stages.add(index) elif witness is False: self._strong_witness = False self._all_good = False elif self._all_good: self._all_good = is_good(self.protocol, stage, mem, self._use_t_invariants) # If stage in stable consensus, then flag its consensus if self.protocol.false_states <= stage.absent: self._true_stages.add(index) elif self.protocol.true_states <= stage.absent: self._false_stages.add(index) # Construct stage successors is_terminal = True for child_stage in children: is_terminal = False # Add child if depth does not exceed max depth if ((self._max_depth is None) or (child_stage.depth() <= self._max_depth)): child_index = add_vertex(child_stage) add_edge(index, child_index) unprocessed.append((child_index, child_stage)) # If stage is terminal, then flag as terminal if is_terminal: self._terminal_stages.add(index)