// DOES NOT DEAL WITH CIRCUITS WITH CYCLES!!! private List <Gate> AssignTopologicalRanks() { // grab an item from the input set var inEnum = InputAddrs.GetEnumerator(); inEnum.MoveNext(); var gateDeque = new LinkedList <Gate>(); while (inEnum.MoveNext()) { gateDeque.AddFirst(inEnum.Current.Gate); } var sortList = new List <Gate>(); int nextRank = 0; while (gateDeque.Count > 0) { var current = gateDeque.First.Value; if (current.TopologicalRank != Gate.NO_RANK) { // already assigned a rank to this. can move on to next gateDeque.RemoveFirst(); continue; } // check to see if all of the predecessors have a rank assigned. If any don't then add them to the front of the queue bool shouldAssignRank = true; for (int i = 0; i < current.InputCount; i++) { var addr = current.GetLocalInputAddress(i); if (InputAddrs.Contains(addr)) { continue; } var counterparty = InputConnectionCounterparties[addr].Gate; if (counterparty.TopologicalRank == Gate.NO_RANK) { gateDeque.AddFirst(counterparty); shouldAssignRank = false; } } if (shouldAssignRank) { current.TopologicalRank = nextRank; nextRank++; sortList.Add(current); gateDeque.RemoveFirst(); // add all successors for (int i = 0; i < current.OutputCount; i++) { var addr = current.GetLocalOutputAddress(i); if (OutputAddrs.Contains(addr)) { continue; } gateDeque.AddLast(OutputConnectionCounterparties[addr].Gate); } } // otherwise a predecessor still needs a rank } return(sortList); }