Esempio n. 1
1
        public List<Edge<int>> mfas(BidirectionalGraph<int, Edge<int>> G)
        {
            List<Edge<int>> F = new List<Edge<int>>();
            IDictionary<int, int> P = new Dictionary<int, int>();

            int sccCount = G.StronglyConnectedComponents(out P);

            if (sccCount == 0)
            {
                return F;
            }

            if (sccCount == 1)
            {
                Tuple<List<int>, List<int>> T = bisect(G);
                F = mfas(subGraph(T.Item1, G));
                F.AddRange(mfas(subGraph(T.Item2, G)));
                F.AddRange(fromV2toV1(T, G));
            }
            else
            {
                var scc = new HashSet<int>(P.Values);
                foreach (int k in scc)
                {
                    List<int> S = P.Select(x => x).Where(x => x.Value == k).Select(x => x.Key).ToList<int>();
                    F.AddRange(mfas(subGraph(S, G)));
                }
            }

            return F;
        }
Esempio n. 2
0
        public static StronglyConntectedComponents <T> Sccs <T>(this BidirectionalGraph <T, Edge <T> > graph)
        {
            IDictionary <T, int> sccNumbering;

            graph.StronglyConnectedComponents(out sccNumbering);
            return(new StronglyConntectedComponents <T>(sccNumbering, sccNumbering.TurnAround()));
        }
Esempio n. 3
0
        /// <summary>
        /// Adds a new coercion rule. Trys to avoid cyclic implicit casts chains.
        /// </summary>
        /// <typeparam name="TOriginalType"></typeparam>
        /// <typeparam name="TCastingType"></typeparam>
        /// <param name="kind"></param>
        /// <param name="cast"></param>
        public void AddCoercionRule <TOriginalType, TCastingType>(CoercionKind kind, Func <TOriginalType, TCastingType> cast)
        {
            var original = typeof(TOriginalType);
            var casting  = typeof(TCastingType);

            if (GetTypeByNative(original) == null)
            {
                throw new UnknownTypeException(original);
            }
            if (GetTypeByNative(casting) == null)
            {
                throw new UnknownTypeException(casting);
            }
            var rule = new CoercionRule(kind, original, casting, a => cast((TOriginalType)a));

            if (allCoercionRules.TryGetEdge(original, casting, out TaggedEdge <Type, CoercionRule> existingEdge))
            {
                throw new InvalidOperationException("Such a rule does already exist!");
            }
            var edge = new TaggedEdge <System.Type, CoercionRule>(original, casting, rule);

            if (kind == CoercionKind.Implicit)
            {
                implicitCoercionRules.AddVertex(original);
                implicitCoercionRules.AddVertex(casting);
                implicitCoercionRules.AddEdge(edge);
                if (implicitCoercionRules.StronglyConnectedComponents(out IDictionary <Type, int> components) != implicitCoercionRules.Vertices.Count())
                {
                    implicitCoercionRules.RemoveEdge(edge);
                    throw new InvalidOperationException("This action would create an implicit conversion cycle!");
                }
            }
            allCoercionRules.AddVertex(original);
            allCoercionRules.AddVertex(casting);
            allCoercionRules.AddEdge(edge);
            Debug.WriteLine($"- added coercion rule from '{original.Name}' to '{casting.Name}'");
        }