diff options
-rwxr-xr-x | monkey/monkey.py | 41 | ||||
-rwxr-xr-x | monkey/test.py | 11 |
2 files changed, 48 insertions, 4 deletions
diff --git a/monkey/monkey.py b/monkey/monkey.py index 7c8141c..b6032f7 100755 --- a/monkey/monkey.py +++ b/monkey/monkey.py @@ -260,3 +260,44 @@ def fix(name, code, edits, aux_code='', timeout=30, debug=False): total_time = time.monotonic() - start_time return '', [], total_time, n_tested + +# Return a list of pairs (range, message) describing edits in [path]. +def fix_hints(code, path): + program = list(annotate(code)) + + messages = [] + for step_type, idx, a, b in path: + if step_type == 'add_rule': + msg = 'Add another rule.' + start = program[idx].pos + end = start + elif step_type == 'add_part': + msg = 'Add another goal.' + start = program[idx].pos + end = start + elif step_type == 'remove_part': + msg = 'Check this goal.' + start = program[idx].pos + end = idx + len(a) - 1 + if program[end].type in ('COMMA', 'PERIOD', 'SEMI'): + end -= 1 + end = program[end].pos + len(program[end].val) + elif step_type == 'change_part': + msg = 'Check this goal.' + first = 0 + while idx+first < len(program)-1 and first < len(a) and first < len(b) and a[first] == b[first]: + first += 1 + last = len(a)-1 + while last < len(b) and last >= first and a[last] == b[last]: + last -= 1 + start = program[idx+first].pos + end = program[idx+last].pos + len(program[idx+last].val) + elif step_type == 'remove_rule': + msg = 'Check this rule.' + start = program[idx].pos + end = program[idx + len(a) - 1].pos + messages.append(((start, end), msg)) + + program[idx:idx+len(a)] = [t.clone(pos=program[idx].pos) for t in b] + + return messages diff --git a/monkey/test.py b/monkey/test.py index 17c27fe..cf67723 100755 --- a/monkey/test.py +++ b/monkey/test.py @@ -9,7 +9,7 @@ from termcolor import colored from .edits import classify_edits, trace_graph from .graph import graphviz -from .monkey import fix +from .monkey import fix, fix_hints from prolog.engine import test from prolog.util import annotate, compose, stringify from .util import indent @@ -53,12 +53,15 @@ try: except: done = [] -def print_hint(solution, steps, fix_time, n_tested): +def print_hint(code, solution, steps, fix_time, n_tested): if solution: print(colored('Hint found! Tested {} programs in {:.1f} s.'.format(n_tested, fix_time), 'green')) print(colored(' Edits', 'blue')) for step_type, pos, a, b in steps: print(' {}: {} {} → {}'.format(pos, step_type, stringify(a), stringify(b))) + print(colored(' Hints', 'blue')) + for (start, end), msg in fix_hints(code, steps): + print(' {}-{}: {}'.format(start, end, msg)) print(colored(' Final version', 'blue')) print(indent(compose(annotate(solution)), 2)) else: @@ -80,7 +83,7 @@ if len(sys.argv) >= 3 and sys.argv[2] == 'test': solution, steps, fix_time, n_tested = fix(problem.name, program, edits, aux_code=aux_code, timeout=timeout) if solution: done.append(program) - print_hint(solution, steps, fix_time, n_tested) + print_hint(program, solution, steps, fix_time, n_tested) print() pickle.dump(done, open('status-'+str(problem.pk)+'.pickle', 'wb')) @@ -172,4 +175,4 @@ else: # Try finding a fix. print(colored('Analyzing program…', 'yellow')) solution, steps, fix_time, n_tested = fix(problem.name, code, edits, aux_code=aux_code, debug=True) - print_hint(solution, steps, fix_time, n_tested) + print_hint(code, solution, steps, fix_time, n_tested) |