public ValueState Goto(ValueState i, Symbol x)
        {
            ValueState j = new ValueState();

            foreach (var ruleI in i.Rules)
            {
                if (ruleI.Destiny.Contains(x))
                {
                    if (ruleI.Pointer < ruleI.Destiny.Count)
                    {
                        var destiny = ruleI.Destiny[ruleI.Pointer];

                        if (destiny == x)
                        {
                            RuleProductionState rule = new RuleProductionState();
                            rule.Id        = ruleI.Id;
                            rule.Source    = ruleI.Source;
                            rule.Lookahead = ruleI.Lookahead;
                            rule.Destiny.AddRange(ruleI.Destiny);
                            rule.Parent     = ruleI.Parent;
                            rule.Pertinence = ruleI.Pertinence;
                            rule.TypeName   = ruleI.TypeName;
                            rule.Pointer    = ruleI.Pointer + 1;
                            rule.CalculateHash();

                            if (!j.HashCodeRules.ContainsKey(rule.HashCode))
                            {
                                j.AddRule(rule);
                            }
                        }
                    }
                }
            }
            return(Closure(j));
        }
        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);
        }