protected void Reset()
        {
            CNF_RULES      = new List <CNF_Rule>();
            WORDS          = new List <string>();
            SENTENCE_WORDS = new List <string>();
            CKY_i          = 0;
            CKY_j          = 0;
            CKY_k          = 0;
            CKY_TABLECELLS = new CKY_TableCell[1, 1];
            PROCESSCHAIN   = new List <ProcessChain>();
            //this.Sentence_Text.Value = "";

            N_Word = 0;
            CKY_Grid.Columns.Clear();
            CNF_Grid.Columns.Clear();

            CKY_DATATABLE = new DataTable();
            CNF_DATATABLE = new DataTable();
            btnMain_State = "Start";             // btnMain_State;
            FinalCell     = false;               // Touch the final cell
        }
        protected void Next(bool fskip = false)
        {
            string s;
            int    id_rule;
            string word;

            CKY_TableCell[,] cky_tablecells = CKY_TABLECELLS;
            List <ProcessChain> PC = PROCESSCHAIN;

            // First cell
            if ((int)CKY_i == 0 && (int)CKY_j == 0 && (int)CKY_k == 0)
            {
                CKY_k = 1;
                CKY_i = 0;
                CKY_j = 1;
                word  = SENTENCE_WORDS[(int)CKY_k - 1];
                cky_tablecells[0, 1].Tag       = CKY_TableCell.GetTagofWord(word, out id_rule, CNF_RULES);
                cky_tablecells[0, 1].fTerminal = true;

                s = String.Format("<strong>{0}</strong>", cky_tablecells[0, 1].Tag);
                CKY_TABLECELLS = cky_tablecells;
                SetDataTable(0, 1, s);

                ChangeColor(0, -1, 1, id_rule - 1);

                // ProcessChain for Prev
                //ProcessChain prChain = new ProcessChain(CKY_k - 1, -1, CKY_k, id_rule - 1, true);
                PC.Add(new ProcessChain(CKY_i, CKY_j, CKY_k, id_rule - 1, true));
                PROCESSCHAIN = PC;
                return;
            }

            int i = (int)CKY_i;
            int j = (int)CKY_j + 1;        // Get next j
            int k = (int)CKY_k;
            // TableCell (i, k) = (i, j) + (j, k)
            CKY_TableCell CurTC;
            CKY_TableCell OppositeTC;

            // End of k col => Next k
            if (i <= 0 && j >= k)
            {
                CKY_k = (int)CKY_k + 1;
                CKY_i = (int)CKY_k - 2;
                CKY_j = (int)CKY_k - 2;

                word = SENTENCE_WORDS[(int)CKY_k - 1];
                cky_tablecells[(int)CKY_k - 1, (int)CKY_k].Tag       = CKY_TableCell.GetTagofWord(word, out id_rule, CNF_RULES);
                cky_tablecells[(int)CKY_k - 1, (int)CKY_k].fTerminal = true;
                s = String.Format("<strong>{0}</strong>", cky_tablecells[(int)CKY_k - 1, (int)CKY_k].Tag);
                SetDataTable((int)CKY_k - 1, (int)CKY_k, s);

                ChangeColor((int)CKY_k - 1, -1, (int)CKY_k, id_rule - 1);

                CKY_TABLECELLS = cky_tablecells;

                // Processchain for Prev()
                PC.Add(new ProcessChain(CKY_i, CKY_j, CKY_k, id_rule - 1, true));
                PROCESSCHAIN = PC;

                if (fskip)
                {
                    Next(fskip);
                }
                else
                {
                    return;
                }
            }
            if (FinalCell == true)
            {
                return;
            }
            if (j == k)
            {
                j = i;
                i = i - 1;
            }
            int x, y;

            for (x = i; x >= 0; x--)
            {
                for (y = j; y < k; y++)
                {
                    CurTC      = cky_tablecells[x, y];
                    OppositeTC = cky_tablecells[y, k];
                    id_rule    = CKY_TableCell.CheckMerge(CurTC, OppositeTC, CNF_RULES);
                    if (id_rule == -1)
                    {
                        continue;
                    }
                    else
                    {
                        cky_tablecells[x, k].Set(CNF_RULES[id_rule - 1].Left, false, x, y, y, k);
                        cky_tablecells[x, k].fTerminal = false;
                        s = String.Format("<strong>{0}</strong><br />({1}, {2}) + ({3}, {4})", cky_tablecells[x, k].Tag, x, y, y, k);
                        SetDataTable(x, k, s);

                        ChangeColor(x, y, k, id_rule - 1);

                        PC.Add(new ProcessChain(x, y, k, id_rule - 1, false));
                        PROCESSCHAIN = PC;

                        CKY_TABLECELLS = cky_tablecells;
                        if (x == 0 && k == N_Word)
                        {
                            FinalCell       = true;
                            btnMain_State   = "Reset";
                            btnMain.Text    = "Reset";
                            btnNext.Enabled = false;
                            DisplayParseText();
                            CKY_i = x;
                            CKY_j = y;
                            CKY_k = k;
                            return;
                        }
                        if (fskip == false)
                        {
                            CKY_i = x;
                            CKY_j = y;
                            CKY_k = k;
                            return;
                        }
                        else
                        {
                            //RestoreColor(x, y, k, check - 1);
                            CKY_i = x;
                            CKY_j = y;
                            CKY_k = k;
                            Next(fskip);
                            if (FinalCell == true)
                            {
                                return;
                            }
                        }
                    }
                }
                if (y == k)
                {
                    j = i;
                }
            }

            CKY_k = (int)CKY_k + 1;
            CKY_i = (int)CKY_k - 2;
            CKY_j = (int)CKY_k - 2;
            if ((int)CKY_k > N_Word)
            {
                FinalCell       = true;
                btnMain_State   = "Reset";
                btnMain.Text    = "Reset";
                btnNext.Enabled = false;
                DisplayParseText();
                this.BindGrid();
                return;
            }
            word = SENTENCE_WORDS[(int)CKY_k - 1];
            cky_tablecells[(int)CKY_k - 1, (int)CKY_k].Tag       = CKY_TableCell.GetTagofWord(word, out id_rule, CNF_RULES);
            cky_tablecells[(int)CKY_k - 1, (int)CKY_k].fTerminal = true;
            s = String.Format("<strong>{0}</strong>", cky_tablecells[(int)CKY_k - 1, (int)CKY_k].Tag);
            SetDataTable((int)CKY_k - 1, (int)CKY_k, s);

            ChangeColor((int)CKY_k - 1, -1, (int)CKY_k, id_rule - 1);

            CKY_TABLECELLS = cky_tablecells;

            // Processchain for Prev()
            PC.Add(new ProcessChain(CKY_i, CKY_j, CKY_k, id_rule - 1, true));
            PROCESSCHAIN = PC;

            if (fskip == true)
            {
                Next(fskip);
            }
        }
        protected void Display_CKY_Table(string[] words)
        {
            DataTable CKY_GRID_DATATABLE = new DataTable();

            N_Word = words.Length;

            string s;
            int    i, j;

            for (i = 0; i < N_Word + 1; i++)
            {
                CKY_GRID_DATATABLE.Rows.Add();
                CKY_GRID_DATATABLE.Columns.Add();
            }

            // Create N+1 x N+1 table
            for (i = 0; i < N_Word + 1; i++)
            {
                //DataRow TempRow2 = new DataRow();
                TableRow TempRow = new TableRow();
                for (j = 0; j < N_Word + 1; j++)
                {
                    TableCell TempCell = new TableCell();
                    // Header row
                    if (i == 0 && j > 0)
                    {
                        s = String.Format("<strong>{0}</strong><br />{1}", j, words[j - 1]);
                        CKY_GRID_DATATABLE.Rows[i].SetField(j, s);
                    }
                    // (0, 0) cell
                    if (i == 0 && j == 0)
                    {
                        s = "<strong>0</strong>";
                        CKY_GRID_DATATABLE.Rows[i].SetField(j, s);
                    }
                    // First Vertical row
                    if (i > 0 && j == 0)
                    {
                        s = String.Format("<strong>{0}</strong>", i - 1);
                        CKY_GRID_DATATABLE.Rows[i].SetField(j, s);
                    }

                    // Other Cells
                    if (i > 0 && j > 0)
                    {
                        s = "";
                        CKY_GRID_DATATABLE.Rows[i].SetField(j, s);
                    }
                }
            }

            for (int k = 0; k < N_Word + 1; k++)
            {
                BoundField bfield = new BoundField();
                bfield.HeaderText = CKY_GRID_DATATABLE.Columns[k].ColumnName;
                bfield.DataField  = CKY_GRID_DATATABLE.Columns[k].ColumnName;
                bfield.HtmlEncode = false;
                CKY_Grid.Columns.Add(bfield);
            }

            CKY_DATATABLE = CKY_GRID_DATATABLE;

            this.BindGrid();


            // Create CKY_Global.CKY_TABLECELLS for processing Algorithm and Tracing
            CKY_TableCell[,] cky_Tablecells = new CKY_TableCell[N_Word + 1, N_Word + 1];
            for (i = 0; i < N_Word + 1; i++)
            {
                for (j = 0; j < N_Word + 1; j++)
                {
                    cky_Tablecells[i, j] = new CKY_TableCell();
                }
            }
            this.CKY_TABLECELLS = cky_Tablecells;
        }