static void XML(params int[] indices) { if (indices.Length == 0) { foreach (WExpr program in programs) { string s1 = program.ToString(); XElement xml = new XElement("WhileProgram", new XAttribute("NumVariables", program.GetNumVariables()), program.ToXML()); WExpr parsedProgram = WhileUtilities.ParseWhileProgramFromXML(xml); string s2 = parsedProgram.ToString(); Console.WriteLine(s1 == s2); } } else { foreach (int index in indices) { WExpr program = programs[index]; string s1 = program.ToString(); XElement xml = new XElement("WhileProgram", new XAttribute("NumVariables", program.GetNumVariables()), program.ToXML()); WExpr parsedProgram = WhileUtilities.ParseWhileProgramFromXML(xml); string s2 = parsedProgram.ToString(); Console.WriteLine(s1 == s2); } } }
public static Tuple <int, List <string>, string> FeedbackForWhileToTM <S>(WExpr correctProgram, TMCB <int, S> attemptTM, int maxGrade) { //returns grade, feedback strings, and a sample input for the tape simulator TMCB <int, int> correctTM = correctProgram.ToTMCB(-1); int numTapes = correctProgram.GetNumVariables(); const int numInputs = 100; const int maxWrongOutpus = 5; //max number of wrong outputs the user is shown. //<correctTM> and <attemptTM> are compared by running both on a set of test inputs and comparing the outputs. int inputsPerTape = (int)Math.Pow(numInputs, (double)1 / numTapes); List <string> wrongOutputList = new List <string>(); string sampleInput = ""; int countCorrectOutputs = 0; int countWrongOutpus = 0; bool dummy; foreach (int[][] input in WhileUtilities.NonNegIntTestInputs(numTapes, inputsPerTape, correctProgram.GetUselessVariables().ToArray())) { int[][] correctOutput = correctTM.Run(input, out dummy); //<correctTM> uses LSBF encoding, <attemptTM> uses MSBF encoding. Reverse <input> for <attemptTM>. for (int i = 0; i < input.Length; ++i) { input[i] = input[i].Reverse().ToArray(); } int[][] attemptOutput = attemptTM.Run(input, out dummy); //for comparing the outputs, reverse <correctOutput> for (int i = 0; i < correctOutput.Length; ++i) { correctOutput[i] = correctOutput[i].Reverse().ToArray(); } //get string representations of the outputs string[] correctStrings = Array.ConvertAll(correctOutput, tape => WhileUtilities.TapeToString(tape, correctTM.blank, new[] { 0 }, "_")); string[] attemptStrings = Array.ConvertAll(attemptOutput, tape => WhileUtilities.TapeToString(tape, attemptTM.blank, new[] { 0 }, "_")); if (WhileUtilities.TapesEqual(correctStrings, attemptStrings)) { ++countCorrectOutputs; } else { if (countWrongOutpus == 0) { //first wrong output: corresponding input is stored in <sampleInput> string[] tapes = Array.ConvertAll(input, tape => WhileUtilities.TapeToString(tape, correctTM.blank, new[] { 0 }, "_")); sampleInput = string.Join(",", tapes); } ++countWrongOutpus; if (countWrongOutpus <= maxWrongOutpus) { wrongOutputList.Add(string.Empty); wrongOutputList.Add($"Input #{countWrongOutpus}:"); for (int i = 0; i < input.Length; ++i) { wrongOutputList.Add($"tape {i}: {WhileUtilities.TapeToString(input[i], correctTM.blank, null)}"); } wrongOutputList.Add("Your output:"); for (int i = 0; i < attemptStrings.Length; ++i) { wrongOutputList.Add($"tape {i}: {attemptStrings[i]}"); } wrongOutputList.Add("Correct output:"); for (int i = 0; i < correctStrings.Length; ++i) { wrongOutputList.Add($"tape {i}: {correctStrings[i]}"); } } } } double actualInputs = Math.Pow(inputsPerTape, numTapes); int grade = (int)((countCorrectOutputs / actualInputs) * maxGrade); List <string> feedbackList = new List <string>(); if (countWrongOutpus == 0) { feedbackList.Add("Correct!"); } else { if (countWrongOutpus <= maxWrongOutpus) { feedbackList.Add($"{countWrongOutpus} of {actualInputs} outpus were wrong:"); } else { feedbackList.Add($"{countWrongOutpus} of {actualInputs} outpus were wrong. Here are {maxWrongOutpus} of them:"); } foreach (string line in wrongOutputList) { feedbackList.Add(line); } } return(new Tuple <int, List <string>, string>(grade, feedbackList, sampleInput)); }