|
1 | 1 | #!/usr/bin/env python
|
2 | 2 |
|
| 3 | +usage = \ |
| 4 | +"""Prints the proof tree and either the active goal, or the specified goal. |
| 5 | +
|
| 6 | +Usage: |
| 7 | +
|
| 8 | + lib/render-proof-tree <filename> [goal_id] |
| 9 | +""" |
| 10 | + |
| 11 | +import sys |
| 12 | +import os |
| 13 | +sys.path.append(os.path.join(os.path.dirname(__file__), '../ext/k/k-distribution/target/release/k/lib/')) |
| 14 | +import pyk |
| 15 | + |
3 | 16 | from anytree import NodeMixin, Node, RenderTree
|
4 | 17 | from collections import namedtuple
|
5 | 18 | import textwrap
|
6 | 19 | import fileinput
|
7 | 20 | import re
|
8 | 21 |
|
9 | 22 |
|
| 23 | +# Parse args |
| 24 | +# ---------- |
| 25 | + |
| 26 | +if len(sys.argv) < 2 or len(sys.argv) > 3: print(usage); exit(1) |
| 27 | +input_file = sys.argv[1] |
| 28 | +selected_id = None |
| 29 | +if len(sys.argv) == 3: selected_id = sys.argv[2] |
| 30 | + |
10 | 31 | class Goal(NodeMixin):
|
11 |
| - def __init__(self, id, parent_id): |
| 32 | + def __init__(self, id, parent_id, active): |
12 | 33 | self.id = id
|
13 | 34 | self.name = id
|
14 | 35 | self.parent_id = parent_id
|
| 36 | + self.active = active |
15 | 37 | self.claim = None
|
| 38 | + self.trace = None |
| 39 | + |
| 40 | +# Parse K output |
| 41 | +# -------------- |
16 | 42 |
|
17 | 43 | nodes = {}
|
18 | 44 | roots = []
|
| 45 | +next_line_is_claim = False |
| 46 | +next_line_is_trace = False |
19 | 47 |
|
20 |
| -for line in fileinput.input(): |
21 |
| - match = re.search(' *active: \w*, id: (\w*\d*), parent: (\.|\w*\d*)', line) |
22 |
| - if not match is None: |
23 |
| - id = match.group(1) |
24 |
| - parent = match.group(2) |
25 |
| - node = Goal(id, parent) |
| 48 | +with open(input_file) as f: |
| 49 | + for line in f: |
| 50 | + match = re.search(' *active: (\w*), id: (\w*\d*), parent: (\.|\w*\d*)', line) |
| 51 | + if match is not None: |
| 52 | + active = match.group(1) == 'true' |
| 53 | + id = match.group(2) |
| 54 | + parent = match.group(3) |
| 55 | + node = Goal(id, parent, active) |
26 | 56 | nodes[id] = node
|
27 | 57 | if parent == '.': roots += [node]
|
28 |
| - match = re.search('implies', line) |
29 |
| - if not match is None: |
30 |
| - node.claim = line |
| 58 | + if next_line_is_claim: node.claim = line.strip(); next_line_is_claim = False |
| 59 | + if next_line_is_trace: node.trace = line.strip(); next_line_is_trace = False |
| 60 | + next_line_is_claim = re.search('<claim>', line) is not None |
| 61 | + next_line_is_trace = re.search('<trace>', line) is not None |
| 62 | + |
| 63 | +# Build proof tree |
| 64 | +# ---------------- |
31 | 65 |
|
32 | 66 | for id, node in nodes.items():
|
33 | 67 | if node in roots: continue
|
34 | 68 | node.parent = nodes[node.parent_id]
|
35 | 69 |
|
| 70 | +# Print proof tree |
| 71 | +# ---------------- |
| 72 | + |
| 73 | +def is_node_selected(node): |
| 74 | + if selected_id is None: return node.active |
| 75 | + return node.id == selected_id |
| 76 | + |
| 77 | +term_normal ='\033[0m' |
| 78 | +term_bold ='\033[1m' |
| 79 | +term_reverse ='\033[7m' |
| 80 | +for pre, fill, node in RenderTree(roots[0]): |
| 81 | + if is_node_selected(node): |
| 82 | + pre += term_reverse |
| 83 | + print( pre, 'id: ', node.id, ',' |
| 84 | + , 'trace:', node.trace |
| 85 | + , term_normal |
| 86 | + ) |
| 87 | + |
36 | 88 | for pre, fill, node in RenderTree(roots[0]):
|
37 |
| - print(pre, 'id: ', node.id, 'x') |
38 |
| - # if not node.claim is None: |
39 |
| - # print(('\n' + fill).join(textwrap.wrap('claim: ' + node.claim))) |
| 89 | + if is_node_selected(node): |
| 90 | + print('id:', node.id) |
| 91 | + print('claim:', node.claim) |
40 | 92 |
|
0 commit comments