private bool VisitNodeInCycle(TicNode node) { node.VisitMark = NotVisited; _cycle.Push(node); if (_cycleInitiator != node) { //continue to collect cycle route return(false); } // Ref and/or ancestor cycle found // That means all elements in cycle have to be merged // (a<= b <= c = a) => (a = b = c) var merged = SolvingFunctions.MergeGroup(_cycle.Reverse()); // Cycle is merged _cycle = null; _cycleInitiator = null; // continue toposort algorithm return(Visit(merged)); // Whole cycle is not found yet // step back }
public SolvingNode[] Toposort() { int iteration = 0; while (true) { var allNodes = _syntaxNodes.Concat(_variables.Values).Concat(_typeVariables).ToArray(); if (iteration > allNodes.Length * allNodes.Length) { throw new InvalidOperationException("Infinite cycle detected. Types cannot be solved"); } iteration++; var result = NodeToposortFunctions.Toposort(allNodes); switch (result.Status) { case SortStatus.MemebershipCycle: throw new InvalidOperationException("Reqursive type defenition"); case SortStatus.AncestorCycle: { var cycle = result.Order; Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine($"Found cycle: "); Console.ResetColor(); Console.WriteLine(string.Join("->", cycle.Select(r => r.Name))); //main node. every other node has to reference on it SolvingFunctions.MergeGroup(cycle); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine($"Cycle normalization results: "); Console.ResetColor(); foreach (var solvingNode in cycle) { solvingNode.PrintToConsole(); } break; } case SortStatus.Sorted: Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine($"Toposort results: "); Console.ResetColor(); Console.WriteLine(string.Join("->", result.Order.Select(r => r.Name))); Console.WriteLine("Refs:" + string.Join(",", result.Refs.Select(r => r.Name))); return(result.Order.Union(result.Refs).ToArray()); } } }