Пример #1
0
        private static XElement TryToGradeConstructionProblem(XElement xmlPdaCorrect, XElement xmlPdaAttempt, XElement xmlGiveStackAlphabet, XElement xmlMaxGrade, CancellationToken token)
        {
            var pdaCorrect = PDA <char, char> .FromXml(xmlPdaCorrect);

            pdaCorrect.CreateRunner(token);
            var pdaAttempt = PDA <char, char> .FromXml(xmlPdaAttempt);

            pdaAttempt.CreateRunner(token);
            var giveStackAlphabet = bool.Parse(xmlGiveStackAlphabet.Value);
            var maxGrade          = int.Parse(xmlMaxGrade.Value);

            var alphabet = PDAXmlParser.ParseAlphabetFromXmlPDA(xmlPdaCorrect);

            Assertion.Assert(Enumerable.SequenceEqual(alphabet, PDAXmlParser.ParseAlphabetFromXmlPDA(xmlPdaAttempt)), "the alphabets of the given PDAs are not the same");

            var stackAlphabetCorrect = PDAXmlParser.ParseStackAlphabetFromXmlPDA(xmlPdaCorrect);
            var stackAlphabetAttempt = PDAXmlParser.ParseStackAlphabetFromXmlPDA(xmlPdaAttempt);

            Assertion.Assert(!giveStackAlphabet || Enumerable.SequenceEqual(stackAlphabetCorrect, stackAlphabetAttempt), "if the stack-alphabet is given for the solver, the attempt pda has to have the same stack-alphabet");

            int statesDiff = pdaAttempt.States.Count - pdaCorrect.States.Count;
            int stackDiff  = stackAlphabetAttempt.Count - stackAlphabetCorrect.Count;
            PDAEqualityResult <char, char> pdaEqualityResult;

            pdaEqualityResult = new PDAEqualityResult <char, char>(pdaCorrect, pdaAttempt, alphabet, maximumWordLengthTested, maximumNumberOfWords, maximumMilliSeconds);
            if (pdaEqualityResult.PdaCorrectIsinconsistent)
            {
                return(Grader.CreateXmlFeedback(maxGrade, new List <string>()
                {
                    "Oops! Seems like your tutor created an inconsistent pda...therefore, you get the full grade ;)"
                }));
            }

            int    joinSize   = pdaEqualityResult.NumberOfWordsAcceptedByAtLeastOne;
            double proportion = joinSize == 0 ? 1 : (double)pdaEqualityResult.NumberOfWordsAcceptedByBoth / joinSize;
            int    grade      = (int)(maxGrade * proportion);

            var feedback = new List <string>();

            if (!pdaEqualityResult.AreEqual)
            {
                if (pdaEqualityResult.WordsInPdaCorrectButNotInPdaAttempt.Count() == 0 && pdaEqualityResult.WordsInPdaAttemptButNotInPdaCorrect.Count() > 0)
                {
                    feedback.Add(string.Format(HintSuperset));
                }
                else if (pdaEqualityResult.WordsInPdaAttemptButNotInPdaCorrect.Count() == 0 && pdaEqualityResult.WordsInPdaCorrectButNotInPdaAttempt.Count() > 0)
                {
                    feedback.Add(string.Format(HintSubset));
                }

                if (pdaEqualityResult.WordsInPdaCorrectButNotInPdaAttempt.Count() > 0)
                {
                    feedback.Add(string.Format(ErrorWordFalselyExcluded, FindWordWithMinimumLength(pdaEqualityResult.WordsInPdaCorrectButNotInPdaAttempt)));
                }

                if (pdaEqualityResult.WordsInPdaAttemptButNotInPdaCorrect.Count() > 0)
                {
                    feedback.Add(string.Format(ErrorWordFalselyIncluded, FindWordWithMinimumLength(pdaEqualityResult.WordsInPdaAttemptButNotInPdaCorrect)));
                }
            }

            if (pdaEqualityResult.InconsistentWordsInPdaAttempt.Count() > 0)
            {
                grade = Math.Max(grade - 1, 0);
                var tuple = FindElementWithMinimumProperty(pdaEqualityResult.InconsistentWordsInPdaAttempt, t => t.Item1.Length);
                feedback.Add(string.Format(ErrorInconsistentAcceptanceCondition, tuple.Item1, tuple.Item2, !tuple.Item2));
            }

            if (statesDiff > 0 || stackDiff > 0)
            {
                grade = Math.Max(0, grade - 1);

                if (statesDiff > 0)
                {
                    feedback.Add(string.Format(ErrorToManyStates, pdaAttempt.States.Count, pdaCorrect.States.Count));
                }
                if (stackDiff > 0)
                {
                    feedback.Add(string.Format(ErrorToManyStackSymbols, stackAlphabetAttempt.Count, stackAlphabetCorrect.Count));
                }
            }

            if (grade == maxGrade)
            {
                feedback.Add("Perfect!");
            }
            else if (pdaEqualityResult.AreEqual && pdaEqualityResult.InconsistentWordsInPdaAttempt.Count() == 0)
            {
                feedback.Add("Correct (but not perfect)!");
            }

            return(Grader.CreateXmlFeedback(grade, feedback));
        }