summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xmonkey/monkey.py41
-rwxr-xr-xmonkey/test.py11
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)