# Copyright 2013-present Barefoot Networks, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # # Antonin Bas (antonin@barefootnetworks.com) # # # -*- coding: utf-8 -*- from __future__ import print_function class Node(object): def __init__(self, n): self.n = n self.edges = set() def add_edge_to(self, other): assert(isinstance(other, Node)) self.edges.add(other) def __str__(self): return str(self.n) class Graph(object): def __init__(self): self.nodes = {} self.root = None def add_node(self, node): assert(node not in self.nodes) self.nodes[node] = Node(node) def __contains__(self, node): return node in self.nodes def get_node(self, node): return self.nodes[node] def produce_topo_sorting(self): def visit(node, topo_sorting, sequence=None): if sequence is not None: sequence += [str(node)] if node._behavioral_topo_sorting_mark == 1: if sequence is not None: print("cycle", sequence) return False if node._behavioral_topo_sorting_mark != 2: node._behavioral_topo_sorting_mark = 1 for next_node in node.edges: res = visit(next_node, topo_sorting, sequence) if not res: return False node._behavioral_topo_sorting_mark = 2 topo_sorting.insert(0, node.n) return True has_cycle = False topo_sorting = [] for node in self.nodes.values(): # 0 is unmarked, 1 is temp, 2 is permanent node._behavioral_topo_sorting_mark = 0 for node in self.nodes.values(): if node._behavioral_topo_sorting_mark == 0: if not visit(node, topo_sorting, sequence=[]): has_cycle = True break # removing mark for node in self.nodes.values(): del node._behavioral_topo_sorting_mark if has_cycle: return None return topo_sorting