private Optional <Example> TryMakeExample(string folder) { var fs = Directory.GetFiles(folder, "[P]*", SearchOption.TopDirectoryOnly); if (fs.Length != 1) { Log.Warning("Ignore example {0}: Multiple or no error message files found", folder); return(Optional <Example> .Nothing); } var info = _parser.ParseError(fs[0]); fs = Directory.GetFiles(folder, "[E]*", SearchOption.TopDirectoryOnly); if (fs.Length != 1) { Log.Warning("Ignore example {0}: Multiple or no input source found", folder); return(Optional <Example> .Nothing); } var inputJSON = _parser.ParseProgramAsJSON(fs[0]); var file = fs[0]; fs = Directory.GetFiles(folder, "[C]*", SearchOption.TopDirectoryOnly); if (fs.Length != 1) { Log.Warning("Ignore example {0}: Multiple or no output source found", folder); return(Optional <Example> .Nothing); } var outputJSON = _parser.ParseProgramAsJSON(fs[0]); return(new Example( new Input(SyntaxNodeContext.FromJSON(inputJSON), info.pos, info.message, file), SyntaxNodeContext.FromJSON(outputJSON), folder ).Some()); }
private Input MakeInputFromFile(string file) { var inputJSON = _parser.ParseProgramAsJSON(file); var error = _parser.Compile(file).Value; return(new Input(SyntaxNodeContext.FromJSON(inputJSON), error.pos, error.message, file)); }
private JObject CheckPassed(Input testcase, bool interactive) { var outputDir = Path.Combine(_output_dir, Path.GetFileName(Path.GetDirectoryName(testcase.file))); if (!Directory.Exists(outputDir)) { Directory.CreateDirectory(outputDir); } var testcases = new List <Input>(); testcases.Add(testcase); var outputs = new List <string>(); outputs.Add(Path.Combine(outputDir, testcases.Count + _parser.GetSourceFileExtension())); var rulesApplied = new JArray(); bool passed = false; // attempt to solve this testcase using existing rules (maybe multiple times) while (true) { var result = TestOne(testcases.Last(), outputs.Last()); if (result is RuleLib.ApplySuccess <Parser.CompileError> ) { var r = result as RuleLib.ApplySuccess <Parser.CompileError>; rulesApplied.Add(r.ruleUsed); passed = true; break; } else if (result is RuleLib.ApplyFailure <Parser.CompileError> ) { var r = result as RuleLib.ApplyFailure <Parser.CompileError>; rulesApplied.Add(r.ruleUsed); if (testcases.Count < 5) // set up a new input for next step { testcases.Add(MakeInputFromFile(outputs.Last())); outputs.Add(Path.Combine(outputDir, testcases.Count + _parser.GetSourceFileExtension())); } else { break; } } else // not appliable { break; } } JObject stat = new JObject(); stat.Add("path", testcase.file); stat.Add("solved?", passed); if (passed) { stat.Add("rules applied", rulesApplied); } if (!passed && _topK > 0 && interactive) // ask an expert to provide a fix to this example // and enlarge the rule lib with the newly synthesized rule set { Console.WriteLine("Interactive mode enabled for failed testcase: {0}", testcase.file); bool cont = false; char key = GetUserInput("[C]ontinue, [S]kip, or Skip [A]ll? ", ch => (ch == "C" || ch == "S" || ch == "A") ? ch.First().Some() : Optional <char> .Nothing); switch (key) { case 'C': cont = true; break; case 'S': cont = false; break; case 'A': cont = false; _topK = 0; break; } var records = new JArray(); while (cont) { // 1. decide which testcase is the input of the example int id; if (testcases.Count == 1) { Console.WriteLine("Input: {0}", testcases.First().file); id = 0; } else { for (int i = 0; i < testcases.Count; i++) { Console.WriteLine("[{0}] {1}", i, testcases[i].file); } id = GetUserInput("Select input: ", s => { int choice; return((int.TryParse(s, out choice) && choice >= 0 && choice < testcases.Count) ? choice.Some() : Optional <int> .Nothing); }); } Input inp = testcases[id]; // 2. user provide fix for the selected input string fixFile = GetUserInput("Fix: ", f => { if (!File.Exists(f)) { Console.WriteLine("Error: this file does not exist."); return(Optional <string> .Nothing); } return(f.Some()); }); // 3. learn with the new example var fix = SyntaxNodeContext.FromJSON(_parser.ParseProgramAsJSON(fixFile)); var name = "new example " + _new_count; _new_count++; var example = new Example(inp, fix, fixFile); var record = LearnRuleSet(new ExampleGroup(example, name)); records.Add(record); // 4. needs fix multiple times? var r = _parser.Compile(fixFile); if (r.HasValue) { var err = r.Value; var newCase = new Input(fix, err.pos, err.message, fixFile); var r1 = TestOne(newCase, fixFile + ".out"); if (r1 is RuleLib.ApplySuccess <Parser.CompileError> ) // we are done { cont = false; } else { Console.WriteLine("Note: the provided fix is still buggy: {0}: {1}", err.pos, err.message); testcases.Add(newCase); } } else // we are done { cont = false; } } stat.Add("incremental synthesis tasks", records); } return(stat); }