Beispiel #1
0
        public DfaStateSet IntersectWith(DfaStateSet other)
        {
            var intersect = new HashSet <DfaState>(this.set);

            intersect.IntersectWith(other.set);

            return(new DfaStateSet(intersect));
        }
Beispiel #2
0
        public DfaStateSet ExceptWith(DfaStateSet other)
        {
            var except = new HashSet <DfaState>(this.set);

            except.ExceptWith(other.set);

            return(new DfaStateSet(except));
        }
Beispiel #3
0
        private void MergeStates()
        {
            //
            // https://en.wikipedia.org/wiki/DFA_minimization
            // Hopcroft's algorithm
            //

            var finals = new DfaStateSet(FinalStates);
            var nons   = new DfaStateSet(NonFinalStates);

            var partitions = new List <DfaStateSet> {
                finals, nons
            };
            var working = new List <DfaStateSet> {
                finals
            };

            var terminals = new HashSet <Atom>(AllStates.SelectMany(state => state.Transitions).Select(transition => transition.Terminal));

            while (working.Count > 0)
            {
                var a = working[0];
                working.RemoveAt(0);

                foreach (var terminal in terminals)
                {
                    var x = new DfaStateSet();
                    foreach (var state in AllStates)
                    {
                        foreach (var transition in state.Transitions)
                        {
                            if (transition.Terminal.Set.Overlaps(terminal.Set))
                            {
                                if (a.Contains(transition.Target))
                                {
                                    x.Add(state);
                                    break;
                                }
                            }
                        }
                    }

                    var i = 0;

                    while (i < partitions.Count)
                    {
                        var y             = partitions[i];
                        var x_intersect_y = x.IntersectWith(y);

                        var y_without_x = y.ExceptWith(x);

                        if (x_intersect_y.IsEmpty || y_without_x.IsEmpty)
                        {
                            i += 1;
                            continue;
                        }
                        partitions[i] = x_intersect_y;
                        i            += 1;
                        partitions.Insert(i, y_without_x);
                        i += 1;

                        var j = 0;
                        while (j < working.Count)
                        {
                            if (working[j] == y)
                            {
                                working.RemoveAt(j);
                                working.Add(x_intersect_y);
                                working.Add(y_without_x);
                                break;
                            }

                            j += 1;
                        }

                        if (j == working.Count)
                        {
                            // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
                            if (x_intersect_y.Count <= y_without_x.Count)
                            {
                                working.Add(x_intersect_y);
                            }
                            else
                            {
                                working.Add(y_without_x);
                            }
                        }
                    }
                }
            }

            foreach (var partition in partitions)
            {
                if (partition.Count > 1)
                {
                    var dfaStates = partition.ToList();
                    var premium   = dfaStates.First();
                    var remove    = dfaStates.Skip(1).ToList();

                    foreach (var state in AllStates)
                    {
                        foreach (var transition in state.Transitions)
                        {
                            if (remove.Contains(transition.Target))
                            {
                                transition.Retarget(premium);
                            }
                        }
                    }
                }
            }

            SetDfa(Dfa);
        }