@@ -77,6 +77,10 @@ def edge(i: int, j: int) -> KCFG.Edge:
77
77
return KCFG .Edge (node (i ), node (j ), 1 , ())
78
78
79
79
80
+ def merged_edge (i : int , j : int , edges : Iterable [KCFG .Edge ]) -> KCFG .MergedEdge :
81
+ return KCFG .MergedEdge (node (i ), node (j ), tuple (edges ))
82
+
83
+
80
84
def cover (i : int , j : int ) -> KCFG .Cover :
81
85
csubst = term (j ).match_with_constraint (term (i ))
82
86
assert csubst is not None
@@ -107,6 +111,14 @@ def _make_edge_dict(i: int, j: int, depth: int = 1, rules: tuple[str, ...] = ())
107
111
return [_make_edge_dict (* edge ) for edge in edges ]
108
112
109
113
114
+ def merged_edge_dicts (* merged_edges : Iterable ) -> list [dict [str , Any ]]:
115
+
116
+ def _make_merged_edge_dict (s : int , t : int , * edges : Iterable ) -> dict [str , Any ]:
117
+ return {'source' : s , 'target' : t , 'edges' : edge_dicts (* edges )}
118
+
119
+ return [_make_merged_edge_dict (* merged_edge ) for merged_edge in merged_edges ]
120
+
121
+
110
122
def cover_dicts (* edges : tuple [int , int ]) -> list [dict [str , Any ]]:
111
123
covers = []
112
124
for i , j in edges :
@@ -310,6 +322,7 @@ def test_get_successors() -> None:
310
322
'next' : 19 ,
311
323
'nodes' : node_dicts (18 ),
312
324
'edges' : edge_dicts ((11 , 12 )),
325
+ 'merged_edges' : merged_edge_dicts ((17 , 18 , (14 , 15 ))),
313
326
'splits' : split_dicts ((12 , [(13 , mlTop ()), (14 , mlTop ())])),
314
327
'covers' : cover_dicts ((14 , 11 )),
315
328
'ndbranches' : ndbranch_dicts ((13 , [(16 , False ), (17 , False )])),
@@ -318,12 +331,14 @@ def test_get_successors() -> None:
318
331
319
332
# When
320
333
edges = set (cfg .edges (source_id = 11 ))
334
+ merged_edges = set (cfg .merged_edges (source_id = 17 ))
321
335
covers = set (cfg .covers (source_id = 14 ))
322
336
splits = sorted (cfg .splits (source_id = 12 ))
323
337
ndbranches = set (cfg .ndbranches (source_id = 13 ))
324
338
325
339
# Then
326
340
assert edges == {edge (11 , 12 )}
341
+ assert merged_edges == {merged_edge (17 , 18 , [edge (14 , 15 )])}
327
342
assert covers == {cover (14 , 11 )}
328
343
assert splits == [split (12 , [13 , 14 ])]
329
344
assert ndbranches == {ndbranch (13 , [16 , 17 ])}
@@ -344,8 +359,9 @@ def test_get_predecessors() -> None:
344
359
def test_reachable_nodes () -> None :
345
360
# Given
346
361
d = {
347
- 'nodes' : node_dicts (20 ),
362
+ 'nodes' : node_dicts (21 ),
348
363
'edges' : edge_dicts ((13 , 15 ), (14 , 15 ), (15 , 12 )),
364
+ 'merged_edges' : merged_edge_dicts ((20 , 21 , (12 , 13 ))),
349
365
'covers' : cover_dicts ((12 , 13 )),
350
366
'splits' : split_dicts (
351
367
(16 , [(12 , mlTop ()), (13 , mlTop ()), (17 , mlTop ())]), (17 , [(12 , mlTop ()), (18 , mlTop ())])
@@ -362,16 +378,17 @@ def test_reachable_nodes() -> None:
362
378
363
379
# Then
364
380
assert nodes_2 == {node (12 ), node (13 ), node (15 )}
365
- assert nodes_3 == {node (16 ), node (12 ), node (13 ), node (17 ), node (18 ), node (15 ), node (19 ), node (20 )}
381
+ assert nodes_3 == {node (16 ), node (12 ), node (13 ), node (17 ), node (18 ), node (15 ), node (19 ), node (20 ), node ( 21 ) }
366
382
assert nodes_4 == {node (13 ), node (16 ), node (12 ), node (15 ), node (17 ), node (14 )}
367
383
assert nodes_5 == {node (19 ), node (18 ), node (17 ), node (16 )}
368
384
369
385
370
386
def test_paths_between () -> None :
371
387
# Given
372
388
d = {
373
- 'nodes' : node_dicts (20 ),
389
+ 'nodes' : node_dicts (21 ),
374
390
'edges' : edge_dicts ((13 , 15 ), (14 , 15 ), (15 , 12 )),
391
+ 'merged_edges' : merged_edge_dicts ((20 , 21 , (12 , 13 ))),
375
392
'covers' : cover_dicts ((12 , 13 )),
376
393
'splits' : split_dicts (
377
394
(16 , [(12 , mlTop ()), (13 , mlTop ()), (17 , mlTop ())]), (17 , [(12 , mlTop ()), (18 , mlTop ())])
@@ -391,11 +408,11 @@ def test_paths_between() -> None:
391
408
]
392
409
393
410
# When
394
- paths = sorted (cfg .paths_between (17 , 20 ))
411
+ paths = sorted (cfg .paths_between (17 , 21 ))
395
412
396
413
# Then
397
414
assert paths == [
398
- (split (17 , [18 ]), ndbranch (18 , [20 ])),
415
+ (split (17 , [18 ]), ndbranch (18 , [20 ]), merged_edge ( 20 , 21 , [ edge ( 12 , 13 )]) ),
399
416
]
400
417
401
418
@@ -914,7 +931,8 @@ def test_pretty_print() -> None:
914
931
d = {
915
932
'nodes' : nodes ,
916
933
'aliases' : {'foo' : 14 , 'bar' : 14 },
917
- 'edges' : edge_dicts ((21 , 12 ), (12 , 13 , 5 ), (13 , 14 ), (15 , 16 ), (16 , 13 ), (18 , 17 ), (22 , 19 )),
934
+ 'edges' : edge_dicts ((12 , 13 , 5 ), (13 , 14 ), (15 , 16 ), (16 , 13 ), (18 , 17 ), (22 , 19 )),
935
+ 'merged_edges' : merged_edge_dicts ((21 , 12 , (21 , 12 ), (21 , 13 ))),
918
936
'covers' : cover_dicts ((19 , 22 )),
919
937
'splits' : split_dicts (
920
938
(
@@ -940,7 +958,7 @@ def test_pretty_print() -> None:
940
958
'\n '
941
959
'┌─ 21 (root)\n '
942
960
'│\n '
943
- '│ (1 step )\n '
961
+ '│ (1|1 steps )\n '
944
962
'├─ 12\n '
945
963
'│\n '
946
964
'│ (5 steps)\n '
@@ -1026,7 +1044,7 @@ def test_pretty_print() -> None:
1026
1044
'│ V21\n '
1027
1045
'│ </top>\n '
1028
1046
'│\n '
1029
- '│ (1 step )\n '
1047
+ '│ (1|1 steps )\n '
1030
1048
'├─ 12\n '
1031
1049
'│ <top>\n '
1032
1050
'│ V12\n '
0 commit comments