Esempio n. 1
0
        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());
        }
Esempio n. 2
0
        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));
        }
Esempio n. 3
0
        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);
        }