예제 #1
0
파일: DfaUtils.cs 프로젝트: nobikik9/kju
        public static IReadOnlyCollection <IState> GetAllStates <TLabel, Symbol>(this IDfa <TLabel, Symbol> dfa)
        {
            var visited = new HashSet <IState>();
            var queue   = new Queue <IState>();

            queue.Enqueue(dfa.StartingState());
            visited.Add(dfa.StartingState());

            while (queue.Count > 0)
            {
                var s           = queue.Dequeue();
                var transitions = dfa.Transitions(s);

                foreach (var nextState in transitions.Values)
                {
                    if (!visited.Contains(nextState))
                    {
                        queue.Enqueue(nextState);
                        visited.Add(nextState);
                    }
                }
            }

            return(visited);
        }
예제 #2
0
        private static HashSet <IState> ReachableStates(IDfa <TLabel, Symbol> dfa)
        {
            var reachedStates = new HashSet <IState>();

            var queue = new Queue <IState>();

            queue.Enqueue(dfa.StartingState());
            reachedStates.Add(dfa.StartingState());

            while (queue.Count > 0)
            {
                IState state = queue.Dequeue();
                foreach (KeyValuePair <Symbol, IState> transition in dfa.Transitions(state))
                {
                    if (!reachedStates.Contains(transition.Value))
                    {
                        reachedStates.Add(transition.Value);
                        queue.Enqueue(transition.Value);
                    }
                }
            }

            return(reachedStates);
        }
예제 #3
0
        private static TLabel GetTargetLabel <TLabel>(IDfa <TLabel, char> dfa, string s, TLabel defaultLabel)
        {
            var state = dfa.StartingState();

            foreach (var ch in s)
            {
                var transitions = dfa.Transitions(state);
                if (!transitions.ContainsKey(ch))
                {
                    return(defaultLabel);
                }

                state = transitions[ch];
            }

            return(dfa.Label(state));
        }
예제 #4
0
        public static bool AreEquivalent(IDfa <TLabel, Symbol> firstDfa, IDfa <TLabel, Symbol> secondDfa)
        {
            var reached = new HashSet <Tuple <IState, IState> >();
            var queue   = new Queue <Tuple <IState, IState> >();

            queue.Enqueue(Tuple.Create(firstDfa.StartingState(), secondDfa.StartingState()));
            reached.Add(queue.Peek());

            while (queue.Count > 0)
            {
                var(firstState, secondState) = queue.Dequeue();
                if (!firstDfa.Label(firstState).Equals(secondDfa.Label(secondState)))
                {
                    return(false);
                }

                var firstStateTransitions  = firstDfa.Transitions(firstState);
                var secondStateTransitions = secondDfa.Transitions(secondState);

                if (!firstStateTransitions.Count.Equals(secondStateTransitions.Count))
                {
                    return(false);
                }

                foreach (var(c, firstNextState) in firstStateTransitions)
                {
                    if (!secondStateTransitions.ContainsKey(c))
                    {
                        return(false);
                    }

                    var secondNextState = secondStateTransitions[c];

                    var pair = Tuple.Create(firstNextState, secondNextState);
                    if (!reached.Contains(pair))
                    {
                        reached.Add(pair);
                        queue.Enqueue(pair);
                    }
                }
            }

            return(true);
        }
예제 #5
0
        private static HashSet <IState> ReachableStates <TLabel>(IDfa <TLabel, char> dfa)
        {
            var reachedStates = new HashSet <IState>();

            var queue = new Queue <IState>(new[] { dfa.StartingState() });

            while (queue.Count > 0)
            {
                var state = queue.Dequeue();
                foreach (var(_, value) in dfa.Transitions(state))
                {
                    if (!reachedStates.Contains(value))
                    {
                        reachedStates.Add(value);
                        queue.Enqueue(value);
                    }
                }
            }

            return(reachedStates);
        }
예제 #6
0
        private static void CheckAutomatonEquivalence <TLabel>(IDfa <TLabel, char> firstDfa, IDfa <TLabel, char> secondDfa)
        {
            var reached = new HashSet <Tuple <IState, IState> >();
            var queue   = new Queue <Tuple <IState, IState> >();

            queue.Enqueue(Tuple.Create(firstDfa.StartingState(), secondDfa.StartingState()));
            reached.Add(queue.Peek());

            while (queue.Count > 0)
            {
                var(firstState, secondState) = queue.Dequeue();
                Assert.AreEqual(firstDfa.Label(firstState), secondDfa.Label(secondState), "Labels should be equal");
                var firstStateTransitions  = firstDfa.Transitions(firstState);
                var secondStateTransitions = secondDfa.Transitions(secondState);

                var firstTransitionCount  = firstStateTransitions.Count;
                var secondTransitionCount = secondStateTransitions.Count;
                Assert.AreEqual(
                    firstTransitionCount,
                    secondTransitionCount,
                    $"States {firstState} and {secondState} have different number of transitions: {firstTransitionCount} != {secondTransitionCount}");

                foreach (var(c, firstNextState) in firstStateTransitions)
                {
                    Assert.IsTrue(
                        secondStateTransitions.ContainsKey(c),
                        $"States have different sets of transitions, {secondTransitionCount} : {string.Join(",", firstStateTransitions.Select((x, y) => ((int)x.Key).ToString()).ToList())}");

                    var secondNextState = secondStateTransitions[c];

                    var pair = Tuple.Create(firstNextState, secondNextState);
                    if (!reached.Contains(pair))
                    {
                        reached.Add(pair);
                        queue.Enqueue(pair);
                    }
                }
            }
        }