private static XElement TryToRunSimulation(XElement xmlPda, XElement xmlWord, CancellationToken token) { var pda = PDA <char, char> .FromXml(xmlPda); var word = xmlWord.Value; try { SimulationPath <char, char> path; if (pda.Deterministic) { path = DPDASimulationRunner <char, char> .RunSimulation(pda, word.ToArray(), pda.AcceptanceCondition, token); } else { path = CFGSimulationRunner <char> .RunSimulation(pda, word.ToArray(), token); } XNamespace xNamespace = @ns; return(new XElement(xNamespace + "div", path.ToXml())); } catch (InconsistentPDAException ex) { return(Error(ex.Message)); } catch (NoAcceptanceException ex) { return(Error(ex.Message)); } }
private static XElement TryToGradeWordProblem(XElement xmlPda, XElement xmlWordsInLanguage, XElement xmlWordsNotInLanguage, XElement xmlMaxGrade, CancellationToken token) { var pda = PDA <char, char> .FromXml(xmlPda); pda.CreateRunner(token); var alphabet = PDAXmlParser.ParseAlphabetFromXmlPDA(xmlPda); var maxGrade = int.Parse(xmlMaxGrade.Value); var wordsIn = xmlWordsInLanguage.Elements().Select(xmlWord => string.Concat(xmlWord.Value)).ToList(); //.Take(maximumWordLength) var wordsNotIn = xmlWordsNotInLanguage.Elements().Select(xmlWord => string.Concat(xmlWord.Value)).ToList(); //.Take(maximumWordLength) var feedback = new List <string>(); int numberOfCorrectWords; try { numberOfCorrectWords = CheckWordsInLanguage(wordsIn, alphabet, pda, feedback) + CheckWordsNotInLanguage(wordsNotIn, alphabet, pda, feedback); } catch (InconsistentPDAException) { return(Grader.CreateXmlFeedback(maxGrade, new List <string>() { "Oops! Seems like your tutor created an inconsistent pda...therefore, you get the full grade ;)" })); } int totalNumberOfWords = wordsIn.Count() + wordsNotIn.Count(); int grade = (int)((double)numberOfCorrectWords * maxGrade / totalNumberOfWords); if (grade == maxGrade) { feedback.Add("Correct!"); } return(Grader.CreateXmlFeedback(grade, feedback)); }
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)); }