1445
1445
return self._keys
1448
def collapse_linear_regions(parent_map):
1449
"""Collapse regions of the graph that are 'linear'.
1455
can be collapsed by removing B and getting::
1459
:param parent_map: A dictionary mapping children to their parents
1460
:return: Another dictionary with 'linear' chains collapsed
1462
# Note: this isn't a strictly minimal collapse. For example:
1470
# Will not have 'D' removed, even though 'E' could fit. Also:
1476
# A and C are both kept because they are edges of the graph. We *could* get
1477
# rid of A if we wanted.
1485
# Will not have any nodes removed, even though you do have an
1486
# 'uninteresting' linear D->B and E->C
1488
for child, parents in parent_map.iteritems():
1489
children.setdefault(child, [])
1491
children.setdefault(p, []).append(child)
1493
orig_children = dict(children)
1495
result = dict(parent_map)
1496
for node in parent_map:
1497
parents = result[node]
1498
if len(parents) == 1:
1499
parent_children = children[parents[0]]
1500
if len(parent_children) != 1:
1501
# This is not the only child
1503
node_children = children[node]
1504
if len(node_children) != 1:
1506
child_parents = result.get(node_children[0], None)
1507
if child_parents is None:
1508
import pdb; pdb.set_trace()
1509
if len(child_parents) != 1:
1510
# This is not its only parent
1512
assert child_parents[0] == node
1513
# The child of this node only points at it, and the parent only has
1514
# this as a child. remove this node, and join the others together
1515
result[node_children[0]] = parents
1516
children[parents[0]] = node_children