Esempio n. 1
0
        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
        }
Esempio n. 2
0
        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());
                }
            }
        }