public static XElement getTwoWordsInstructorFeedback(XElement regex, XElement xAlphabet, XElement first, XElement second)
        {
            string         firstString  = (XElement.Parse(DFAUtilities.RemoveAllNamespaces(first.ToString()))).Value.Trim();
            string         secondString = (XElement.Parse(DFAUtilities.RemoveAllNamespaces(second.ToString()))).Value.Trim();
            HashSet <char> alphabet     = parseAlphabet(xAlphabet);

            CharSetSolver solver  = new CharSetSolver(BitWidth.BV64);
            var           dfaPair = DFAUtilities.parseRegexFromXML(regex, xAlphabet, solver);
            var           dfa     = dfaPair.Second.Determinize(solver).Minimize(solver);

            firstString  = firstString.decodeEpsilon();
            secondString = secondString.decodeEpsilon();
            int  firstState    = DFAUtilities.GetStateAfterString(dfa.InitialState, firstString, dfa, solver);
            int  secondState   = DFAUtilities.GetStateAfterString(dfa.InitialState, secondString, dfa, solver);
            bool areEquivalent = (firstState == secondState);

            if (areEquivalent)
            {
                var suffixDfa = Automaton <BDD> .Create(firstState, dfa.GetFinalStates(), dfa.GetMoves());

                var suffixRegex = solver.ConvertToRegex(suffixDfa);
                suffixRegex = regexToTraditional(suffixRegex);
                return(XElement.Parse(String.Format("<div><feedback> The words '{0}' and '{1}' are equivalent. The language of suffixes is '{2}'</feedback></div>", firstString, secondString, suffixRegex)));
            }
            else
            {
                var shortestDiff = DFAUtilities.GetDifferentiatingWord(firstState, secondState, dfa, alphabet, solver).Second;
                return(XElement.Parse(String.Format("<div><feedback> The words '{0}' and '{1}' are NOT equivalent. The shortest differentiating word is '{2}'</feedback></div>", firstString, secondString, shortestDiff)));
            }
        }
        public static XElement getSameFeedback(XElement regex, XElement xAlphabet, XElement first, XElement second, XElement notEquivalent, XElement reason, XElement maxGrade)
        {
            string         firstString          = (XElement.Parse(DFAUtilities.RemoveAllNamespaces(first.ToString()))).Value.Trim().decodeEpsilon();
            string         secondString         = (XElement.Parse(DFAUtilities.RemoveAllNamespaces(second.ToString()))).Value.Trim().decodeEpsilon();
            string         reasonString         = (XElement.Parse(DFAUtilities.RemoveAllNamespaces(reason.ToString()))).Value.Trim();
            bool           areEquivalentAttempt = int.Parse(notEquivalent.Value) == 1 ? false : true;
            int            maxG     = int.Parse(maxGrade.Value);
            HashSet <char> alphabet = parseAlphabet(xAlphabet);

            CharSetSolver solver  = new CharSetSolver(BitWidth.BV64);
            var           dfaPair = DFAUtilities.parseRegexFromXML(regex, xAlphabet, solver);
            var           dfa     = dfaPair.Second.Minimize(solver);

            int  firstState    = DFAUtilities.GetStateAfterString(dfa.InitialState, firstString, dfa, solver);
            int  secondState   = DFAUtilities.GetStateAfterString(dfa.InitialState, secondString, dfa, solver);
            bool areEquivalent = (firstState == secondState);

            if (areEquivalent != areEquivalentAttempt)
            {
                return(XElement.Parse(string.Format("<div><grade>0</grade><feedback>Wrong equivalency assesment!</feedback></div>")));
            }
            else if (areEquivalent)
            {
                try
                {
                    var suffixDfa = Automaton <BDD> .Create(firstState, dfa.GetFinalStates(), dfa.GetMoves());

                    var reasonDfaPair      = DFAUtilities.parseRegexFromXML(reason, xAlphabet, solver);
                    var dfaGradingFeedback = DFAGrading.GetGrade(suffixDfa, reasonDfaPair.Second, alphabet, solver, 1500, maxG, FeedbackLevel.Minimal, false, false, true);
                    var feedString         = "<div>";
                    foreach (var feed in dfaGradingFeedback.Second)
                    {
                        feedString += string.Format("{0}<br />", feed);
                    }
                    feedString += "</div>";
                    if (maxG == dfaGradingFeedback.First)
                    {
                        return(XElement.Parse(string.Format("<div><grade>{0}</grade><feedback>Correct!</feedback></div>", maxG)));
                    }
                    else
                    {
                        return(XElement.Parse(string.Format("<div><grade>{0}</grade><feedback>{1}</feedback></div>", Math.Max((int)(maxG / 3), dfaGradingFeedback.First), feedString)));
                    }
                }
                catch (PDLException pdlex)
                {
                    return(XElement.Parse(string.Format("<div><grade>{0}</grade><feedback>Parsing Error: {1}</feedback></div>", (int)(maxG / 3), pdlex.Message)));
                }
            }
            else
            {
                // Finding a shortest differentiating word
                var shortestDiff = DFAUtilities.GetDifferentiatingWord(firstState, secondState, dfa, alphabet, solver).Second;
                reasonString = reasonString.decodeEpsilon();
                int  endFirst  = DFAUtilities.GetStateAfterString(firstState, reasonString, dfa, solver);
                int  endSecond = DFAUtilities.GetStateAfterString(secondState, reasonString, dfa, solver);
                bool c1        = dfa.GetFinalStates().Contains(endFirst);
                bool c2        = dfa.GetFinalStates().Contains(endSecond);
                if (c1 ^ c2)
                {
                    return(XElement.Parse(string.Format("<div><grade>{0}</grade><feedback>Correct!</feedback></div>", maxG)));
                }
                else
                {
                    string feedString = string.Format("The words '{0}' and '{2}' are both {1} by the language", (firstString + reasonString).emptyToEpsilon(), c1 ? "accepted" : "not accepted", (secondString + reasonString).emptyToEpsilon());
                    return(XElement.Parse(string.Format("<div><grade>{0}</grade><feedback>{1}</feedback></div>", (int)(maxG / 3), feedString)));
                }
            }
        }