-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.py
More file actions
155 lines (128 loc) · 5.02 KB
/
Copy pathutils.py
File metadata and controls
155 lines (128 loc) · 5.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
from __future__ import annotations
from typing import Dict, List, Tuple
import re
from amr_toolbox.AMRgraph import AMRNode
from nltk.corpus import wordnet as wn
from collections import deque, defaultdict
SENSE_RE = re.compile(r"-(\d\d)$")
ATTR_RE = re.compile(r"^attr-\d+$")
ATTR_OF_RE = re.compile(r"^:arg(\d+)-of$", re.IGNORECASE)
_OP_RE = re.compile(r":(?:op|snt)(\d+)")
# --------------------------------------------------------------------------- #
# Helper utilities
# --------------------------------------------------------------------------- #
def has_child(node:AMRNode, rel:str, val:str|None=None) -> bool:
"""True if node --rel--> child (and child's .text == val if given)"""
for ch, r in node.children.items():
if r == rel and (val is None or ch.text == val):
return True
return False
def has_any_child(node:AMRNode, rel:str, vals:List[str]) -> bool:
for ch, r in node.children.items():
if r == rel and ch.text in vals:
return True
return False
# return any(lemma.lower() == s.name().split('.')[0] and s.pos() != 'n' for s in synsets)
def _ordered_children(node: AMRNode) -> List[AMRNode]:
items = []
for ch, rel in node.children.items():
m = _OP_RE.match(rel)
if m: items.append((int(m.group(1)), ch))
return [ch for _, ch in sorted(items)]
def reorder_choice_blocks(lean_code: str) -> str:
# 1) split into blocks on two-or-more newlines
blocks = re.split(r'\n{2,}', lean_code)
# 2) pull out all the Choice Prop blocks
choice_blocks = {}
kept_blocks = []
for blk in blocks:
m = re.match(r'def\s+(\w+)\s*:\s*Choice\s+Prop\b', blk)
if m:
var = m.group(1)
choice_blocks[var] = blk
else:
kept_blocks.append(blk)
# 3) re‐insert each choice block just before the first block that mentions its var
final_blocks = []
for blk in kept_blocks:
# for each pending choice var, if this block mentions it, prepend its choice block
for var in list(choice_blocks):
if re.search(r'\b{}\b'.format(re.escape(var)), blk):
final_blocks.append(choice_blocks.pop(var))
final_blocks.append(blk)
# 4) any leftover choice blocks go at the end
for blk in choice_blocks.values():
final_blocks.append(blk)
# re‐join with double‐newlines
return "\n\n".join(final_blocks)
def topo_sort(deps):
order = []
indegree = {k: len(v) for k, v in deps.items()}
dq = deque([k for k, deg in indegree.items() if deg == 0])
while dq:
node = dq.popleft()
order.append(node)
for dependent in deps:
if node in deps[dependent]:
deps[dependent].remove(node)
indegree[dependent] -= 1
if indegree[dependent] == 0:
dq.append(dependent)
if any(deps[n] for n in deps):
print("Warning: Cycle detected, partial order returned.")
for n in deps:
if deps[n]:
order.append(n)
return order
def topo_sort_amr(deps, depth):
from collections import deque
order = []
indegree = {node: len(deps[node]) for node in deps}
dq = deque([n for n, deg in indegree.items() if deg == 0])
while dq:
node = dq.popleft()
order.append(node)
for other in deps:
if node in deps[other]:
deps[other].remove(node)
indegree[other] -= 1
if indegree[other] == 0:
dq.append(other)
# If cycles remain, resolve re-entrancies
unresolved = {n for n in deps if deps[n]}
if unresolved:
print("Re-entrancy detected, resolving by depth.")
for node in unresolved:
for dep in list(deps[node]):
if depth.get(dep, 0) < depth.get(node, 0):
# Keep the dependency if dep is deeper (e.g., break-01 > close-10)
continue
else:
# Remove the dependency if dep is shallower
print(f"Removed reentrant edge: {node} depends on {dep}")
deps[node].remove(dep)
indegree[node] -= 1
if indegree[node] == 0:
dq.append(node)
# Resume sorting
while dq:
node = dq.popleft()
if node not in order:
order.append(node)
for other in deps:
if node in deps[other]:
deps[other].remove(node)
indegree[other] -= 1
if indegree[other] == 0:
dq.append(other)
# Add any stragglers
for node in deps:
if node not in order:
order.append(node)
return order
def print_tree(d, indent=0):
for key, value in d.items():
# Print the var_name of the key object
print(' ' * indent + str(getattr(key, 'var_name', str(key))))
if isinstance(value, dict):
print_tree(value, indent + 1)