public List <Symbol> First(Symbol symbol, Symbol lookAHead)
        {
            if (!CacheFirst.ContainsKey(symbol))
            {
                CacheFirst.Add(symbol, new Hashtable());
            }

            if (((Hashtable)CacheFirst[symbol]).ContainsKey(lookAHead))
            {
                return((List <Symbol>)((Hashtable)CacheFirst[symbol])[lookAHead]);
            }
            else
            {
                ((Hashtable)CacheFirst[symbol]).Add(lookAHead, null);
            }

            List <Symbol> returns = new List <Symbol>();

            if (symbol.Terminal)
            {
                returns.Add(symbol);
            }
            else
            {
                Queue <Symbol> queue = new Queue <Symbol>();
                queue.Enqueue(symbol);

                Dictionary <Symbol, bool> visitados = new Dictionary <Symbol, bool>();
                while (queue.Count > 0)
                {
                    Symbol actual = queue.Dequeue();

                    var rules = GrammarLine.GetRules(actual);

                    foreach (var rule in rules)
                    {
                        List <Symbol> firsts = new List <Symbol>();

                        foreach (var destiny in rule.Destiny)
                        {
                            firsts.Add(destiny);
                            if (!destiny.GoToEmpty)
                            {
                                break;
                            }
                        }


                        foreach (var first in firsts)
                        {
                            if (first.Terminal)
                            {
                                var temp = first;
                                if (temp == Symbol.EmptySymbol)
                                {
                                    temp = Symbol.TapeFinal;
                                }

                                if (!returns.Contains(temp))
                                {
                                    returns.Add(temp);
                                }
                            }
                            else
                            {
                                if (!visitados.ContainsKey(first))
                                {
                                    visitados.Add(first, true);
                                    queue.Enqueue(first);
                                }
                            }
                        }
                    }
                }
            }

            if (returns.Count == 0)// [0] != Symbol.TapeFinal)
            {
                returns.Add(lookAHead);
            }

            ((Hashtable)CacheFirst[symbol])[lookAHead] = returns;

            return(returns);
        }
        private void CreateAutoma()
        {
            ValueState          value = new ValueState();
            RuleProductionState rule  = new RuleProductionState();

            rule.Source   = GrammarLine.VariableStart;
            rule.Destiny  = GrammarLine.GetRules(rule.Source)[0].Destiny;
            rule.Id       = GrammarLine.GetRules(rule.Source)[0].Id;
            rule.TypeName = GrammarLine.GetRules(rule.Source)[0].TypeName;

            rule.Pointer    = 0;
            rule.Pertinence = 1;
            rule.Lookahead  = Symbol.TapeFinal;
            rule.Parent     = GrammarLine.GetRules(rule.Source)[0].Parent;
            value.Rules.Add(rule);
            State <Symbol> state = new State <Symbol>(0, "I000", 1, 0, Closure(value));

            FirstState = state;
            // Rules.AddRange(state.GetValue<ValueState>().Rules);

            Automa.States.Add(state);
            bool change = true;
            //  while (change)
            {
                change = false;

                for (int i = 0; i < Automa.States.Count; i++)
                {
                    var stateActualI = Automa.States[i];

                    SymbolList symbols = Grammar.Symbols;
                    for (int j = 0; j < symbols.Count; j++)
                    {
                        var symbolX = symbols[j];

                        var valStateI = stateActualI.GetValue <ValueState>();

                        var valueGoto = Goto(valStateI, symbolX);

                        if (valueGoto.Rules.Count > 0)
                        {
                            //var item = value.Rules
                            // foreach (var item in value.Rules)
                            {
                                state = Automa.States.FirstOrDefault(s => s.GetValue <ValueState>().Equals(valueGoto));
                                if (state == null)
                                {
                                    state      = new State <Symbol>(-1, "Temp", 1, 0, valueGoto);
                                    state.Name = string.Format("I{0:000}", state.Id);
                                    Automa.States.Add(state);
                                }

                                //    Rules.AddRange(value.Rules);

                                Transition <Symbol> transition = new Transition <Symbol>();
                                transition.From = stateActualI;
                                stateActualI.Transitions.Add(transition);


                                transition.To = state;
                                var sir = new SimpleIncludeRule <Symbol>(symbolX, 1);
                                //  sir.Pertinence = item.Pertinence * Automa.States[i].GetValue<ValueState>().Rules[0].Pertinence;

                                transition.Rule = sir;

                                Automa.Transitions.Add(transition);

                                change = true;
                            }
                        }
                    }
                }
            }
        }
        public ValueState Closure(ValueState state)
        {
            // ValueState returns = new ValueState();

            bool change = true;

            //while (change)
            {
                change = false;
                //
                for (int i = 0; i < state.Rules.Count; i++)
                {
                    //A->alphaBbeta, a
                    Symbol        A     = state.Rules[i].Source;
                    List <Symbol> alpha = state.Rules[i].Destiny.Take(state.Rules[i].Pointer).ToList();
                    if (alpha.Count == 0)
                    {
                        alpha.Add(Symbol.EmptySymbol);
                    }
                    Symbol B = Symbol.EmptySymbol;
                    if (state.Rules[i].Destiny.Count > state.Rules[i].Pointer)
                    {
                        B = state.Rules[i].Destiny[state.Rules[i].Pointer];
                    }
                    Symbol beta = Symbol.TapeFinal;
                    if (state.Rules[i].Pointer + 1 < state.Rules[i].Destiny.Count)
                    {
                        beta = state.Rules[i].Destiny[state.Rules[i].Pointer + 1];
                    }

                    Symbol a = state.Rules[i].Lookahead;

                    var rolesB = GrammarLine.GetRules(B);
                    for (int j = 0; j < rolesB.Count; j++)
                    {
                        var first = First(beta, a);

                        for (int k = 0; k < first.Count; k++)
                        {
                            if (first[k].Terminal || first[k] == Symbol.TapeFinal)
                            {
                                RuleProductionState rule = new RuleProductionState();
                                rule.Id       = rolesB[j].Id;
                                rule.TypeName = rolesB[j].TypeName;
                                rule.Source   = B;
                                rule.Destiny.AddRange(rolesB[j].Destiny);
                                rule.Pointer   = 0;
                                rule.Lookahead = first[k];
                                rule.Parent    = rolesB[j].Parent;
                                rule.CalculateHash();
                                // state.Rules[i].Pertinence;

                                if (!state.HashCodeRules.ContainsKey(rule.HashCode))
                                //if (!state.Rules.Any(r => r.Equals(rule)))
                                {
                                    rule.Pertinence = rolesB[j].Pertinence;// *state.Rules[i].Pertinence;// 0.8;
                                    state.AddRule(rule);
                                    change = true;
                                }
                            }
                        }
                    }
                }
            }

            return(state);
        }