Example #1
0
        public static SmartSet <State> GetClosure(IEnumerable <State> states, Automaton automaton)
        {
            var list = new List <State>();

            foreach (var state in states)
            {
                list.Add(state);
            }
            for (var i = 0; i < list.Count; i++)
            {
                var state       = list[i];
                var transitions = automaton.SuccessorEdges(state);
                foreach (var transition in transitions)
                {
                    if (Automaton.IsEpsilonTransition(transition))
                    {
                        var toState = transition.To;
                        if (list.Contains(toState))
                        {
                            continue;
                        }
                        list.Add(toState);
                    }
                }
            }

            var result = new SmartSet <State>();

            result.UnionWith(list);
            return(result);
        }
Example #2
0
        public State AddHashSetState(Automaton dfa, SmartSet <State> states)
        {
            var result = FindHashSetState(dfa, states);

            if (result != null)
            {
                return(result);
            }
            result = new State(dfa);
            _hash_sets.Add(states, result);
            return(result);
        }
Example #3
0
        /* Apply powerset construction to the NFA to convert to a DFA.
         * Note, the result of this method isn't strictly a DFA because
         * edges in the automaton can be text or code, which function just like
         * epsilon transitions--no input is consumed for the edge.
         */
        public Automaton Optimize(Automaton nfa)
        {
            var dfa = new Automaton();

            // For every state s, compute collection of states along epsilon edges
            // to get an initial computation of dfa states.
            foreach (var s in nfa.Vertices)
            {
                var c = ClosureTaker.GetClosure(new List <State> {
                    s
                }, nfa);
                _closure[s] = c;
            }

            // For every state set, compute sums and fix up state sets.
            foreach (var p in _closure)
            {
                var key = p.Key;
                var set = p.Value;
                foreach (var s in set)
                {
                    _closure[s].UnionWith(set);
                }
            }

            // For every state in nfa using Tarjan walk,
            // sum sets with common transitions.
            var ordered_list = new TarjanNoBackEdges <State, Edge>(nfa).ToList();

            ordered_list.Reverse();
            var changed = true;

            while (changed)
            {
                changed = false;
                foreach (var s in ordered_list)
                {
                    var closure     = _closure[s];
                    var transitions = ClosureTaker.GatherTransitions(closure);
                    foreach (var transition_set in transitions)
                    {
                        var key       = transition_set.Key;
                        var value     = transition_set.Value;
                        var state_set = new SmartSet <State>();
                        // All states in value must have common set in dfa.
                        foreach (var e in value)
                        {
                            var c  = e.To;
                            var cl = _closure[c];
                            state_set.UnionWith(cl);
                        }

                        foreach (var c in state_set)
                        {
                            if (!_closure[c].Equals(state_set))
                            {
                                _closure[c] = state_set;
                                changed     = true;
                            }
                        }
                    }
                }
            }

            var initialState = CreateInitialState(nfa, dfa);

            foreach (var p in _closure)
            {
                var state_set     = p.Value;
                var new_dfa_state = FindHashSetState(dfa, state_set);
                if (new_dfa_state == null)
                {
                    var state = AddHashSetState(dfa, state_set);
                    {
                        var mark = false;
                        foreach (var s in state_set)
                        {
                            if (nfa.FinalStates.Contains(s))
                            {
                                mark = true;
                            }
                        }
                        if (mark && !dfa.FinalStates.Contains(state))
                        {
                            dfa.AddFinalState(state);
                        }
                    }
                }
            }

            //System.Console.Error.WriteLine(dfa.ToString());

            foreach (var p in _closure)
            {
                var k         = p.Key;
                var state_set = p.Value;
                var dfa_state = FindHashSetState(dfa, state_set);
                //     System.Console.Error.WriteLine("State " + dfa_state.Id + ":"
                //                                    + state_set.Aggregate(
                //                                        "", // start with empty string to handle empty list case.
                //                                       (current, next) => current + ", " + next));
            }

            //System.Console.Error.WriteLine(dfa.ToString());
            foreach (var from_dfa_state in dfa.Vertices)
            {
                var nfa_state_set = FindHashSet(from_dfa_state);
                var transitions   = ClosureTaker.GatherTransitions(nfa_state_set);
                foreach (var transition_set in transitions)
                {
                    // Note, transitions is a collection of edges for a given string.
                    // For the NFA, an edge has one Ast for the edge because it came from one pattern.
                    // But, for the DFA, there could be multiple edges for the same string,
                    // each from a different pattern! Compute the set of Asts for
                    // all edges.
                    var key       = transition_set.Key;
                    var value     = transition_set.Value;
                    var state_set = new HashSet <State>();
                    foreach (var e in value)
                    {
                        state_set.Add(e.To);
                    }
                    // Find in all previous states.
                    var new_state_set = _hash_sets.Where(hs => state_set.IsSubsetOf(hs.Key)).FirstOrDefault().Key;
                    if (new_state_set == null)
                    {
                        new_state_set = _closure[state_set.First()];
                    }
                    var to_dfa_state = FindHashSetState(dfa, new_state_set);
                    var mods         = value.First().EdgeModifiers;
                    var asts         = new List <IParseTree>();
                    foreach (var v in value)
                    {
                        foreach (var v2 in v.AstList)
                        {
                            asts.Add(v2);
                        }
                    }
                    var he = new Edge(dfa, from_dfa_state, to_dfa_state, asts, mods);
                }
            }

            // Add in "any" fragment in order to match tree nodes that aren't in pattern.
            //{
            //    State s3 = new State(dfa); s3.Commit();
            //    var e1 = new Edge(dfa, s3, s3, null, Edge.EmptyAst, (int)Edge.EdgeModifiers.Any); e1.Commit();
            //    var f = new Fragment(s3);
            //}

            return(dfa);
        }
Example #4
0
 public State FindHashSetState(Automaton dfa, SmartSet <State> states)
 {
     _hash_sets.TryGetValue(states, out State result);
     return(result);
 }