24 | module ControlFlow.CFG
26 | import public ControlFlow.Edge
39 | Neighbors : Type -> Type
40 | Neighbors a = Maybe (List a)
48 | Vertex : Type -> Type
49 | Vertex a = (v : a) -> (ins : Neighbors a) -> (outs : Neighbors a) -> Type
53 | interface Connectable (0 vertex : Vertex a) where
56 | -> {0 ins, outs : Neighbors a}
57 | -> vertex v ins Nothing
58 | -> vertex v Nothing outs
59 | -> vertex v ins outs
73 | Defined (List (Edge a))
78 | Closed : Neighbors a
82 | Single : a -> Neighbors a
92 | Single : a -> a -> Edges a
93 | Single from to = Defined [from ~> to]
100 | fromVOut : (v : a) -> (outs : Neighbors a) -> Edges a
101 | fromVOut v Nothing = Undefined v
102 | fromVOut v (Just outs) = Defined (v ~>> outs)
109 | fromVIn : (ins : Neighbors a) -> (v : a) -> Edges a
110 | fromVIn Nothing v = Undefined v
111 | fromVIn (Just ins) v = Defined (ins ~~> v)
118 | (~>>?) : (v : a) -> (outs : Neighbors a) -> Edges a
119 | v ~>>? vs = fromVOut v vs
123 | (?~~>) : (ins : Neighbors a) -> (v : a) -> Edges a
124 | vs ?~~> v = fromVIn vs v
141 | data CFG : (vertex : Vertex a) -> (ins : Edges a) -> (outs : Edges a) -> Type where
144 | Empty : CFG vertex (Defined edges) (Defined edges)
148 | : {0 vertex : Vertex a}
149 | -> {vins, vouts : Neighbors a}
150 | -> vertex v vins vouts
151 | -> CFG vertex (vins ?~~> v) (v ~>>? vouts)
158 | : {ins, outs, loopIns, loopOuts : List (Edge a)}
159 | -> (node : CFG vertex (Defined $
ins ++ loopOuts) (Defined $
loopIns ++ outs))
160 | -> (loop : CFG vertex (Defined loopIns) (Defined loopOuts))
161 | -> CFG vertex (Defined ins) (Defined outs)
169 | : (pre : CFG vertex ins (Defined edges))
170 | -> (post : CFG vertex (Defined edges) outs)
171 | -> CFG vertex ins outs
179 | : (left : CFG vertex (Defined ins) (Defined outs))
180 | -> (right : CFG vertex (Defined ins') (Defined outs'))
181 | -> CFG vertex (Defined $
ins ++ ins') (Defined $
outs ++ outs')
186 | : {ins, ins' : List (Edge a)}
187 | -> CFG vertex (Defined $
ins ++ ins') outs
188 | -> CFG vertex (Defined $
ins' ++ ins) outs
192 | : {outs, outs' : List (Edge a)}
193 | -> CFG vertex ins (Defined $
outs ++ outs')
194 | -> CFG vertex ins (Defined $
outs' ++ outs)
196 | export infixr 4 |-|
200 | : CFG vertex (Defined ins) (Defined outs)
201 | -> CFG vertex (Defined ins') (Defined outs')
202 | -> CFG vertex (Defined $
ins ++ ins') (Defined $
outs ++ outs')
205 | export infixr 5 *->
209 | : CFG vertex ins (Defined edges)
210 | -> CFG vertex (Defined edges) outs
211 | -> CFG vertex ins outs
216 | : {0 vertex : Vertex a}
217 | -> {vins : Neighbors a}
218 | -> {vouts : List a}
219 | -> vertex v vins (Just vouts)
220 | -> CFG vertex (Defined $
v ~>> vouts) gouts
221 | -> CFG vertex (vins ?~~> v) gouts
222 | prepend v g = (SingleVertex v) *-> g
227 | -> {vouts : Neighbors a}
229 | -> CFG vertex gins (Defined $
vins ~~> v)
230 | -> vertex v (Just vins) vouts
231 | -> CFG vertex gins (v ~>>? vouts)
232 | append g v = g *-> (SingleVertex v)
235 | : {0 vertex : Vertex a}
236 | -> {vins : Neighbors a}
239 | -> (pre : vertex v vins (Just [w, w']))
240 | -> (left : CFG vertex (Single v w) (Defined louts))
241 | -> (right : CFG vertex (Single v w') (Defined routs))
242 | -> CFG vertex (vins ?~~> v) (Defined $
louts ++ routs)
243 | branch pre left right = pre `prepend` (left |-| right)
246 | : {0 vertex : Vertex a}
247 | -> {vins, vouts : Neighbors a}
248 | -> {w, w', u, u' : a}
250 | -> (pre : vertex v vins (Just [w, w']))
251 | -> (left : CFG vertex (Single v w) (Single u t))
252 | -> (right : CFG vertex (Single v w') (Single u' t))
253 | -> (post : vertex t (Just [u, u']) vouts)
254 | -> CFG vertex (vins ?~~> v) (t ~>>? vouts)
255 | fullBranch pre left right post = (branch pre left right) `append` post
266 | : {ls, rs : List (Edge a)}
267 | -> (node : CFG vertex ins (Defined $
ls ++ rs))
268 | -> (branch : CFG vertex (Defined ls) (Defined ls'))
269 | -> CFG vertex ins (Defined $
ls' ++ rs)
270 | lbranch node branch = node *-> (branch |-| Empty)
281 | : {ls, rs : List (Edge a)}
282 | -> (node : CFG vertex ins (Defined $
ls ++ rs))
283 | -> (branch : CFG vertex (Defined rs) (Defined rs'))
284 | -> CFG vertex ins (Defined $
ls ++ rs')
285 | rbranch node branch = node *-> (Empty |-| branch)
296 | : {ls, rs : List (Edge a)}
297 | -> (branch : CFG vertex (Defined ls) (Defined ls'))
298 | -> (node : CFG vertex (Defined $
ls' ++ rs) outs)
299 | -> CFG vertex (Defined $
ls ++ rs) outs
300 | lmerge branch node = (branch |-| Empty) *-> node
311 | : {ls, rs : List (Edge a)}
312 | -> (branch : CFG vertex (Defined rs) (Defined rs'))
313 | -> (node : CFG vertex (Defined $
ls ++ rs') outs)
314 | -> CFG vertex (Defined $
ls ++ rs) outs
315 | rmerge branch node = (Empty |-| branch) *-> node
320 | : {0 vertex : Vertex a}
321 | -> {ins : Neighbors a}
323 | -> ({outs : Neighbors a} -> vertex v Nothing outs -> vertex v ins outs)
324 | -> CFG vertex (Undefined v) gouts
325 | -> CFG vertex (ins ?~~> v) gouts
327 | imap f (SingleVertex {vins = Nothing} v) = SingleVertex (f v)
328 | imap f (Series g g') = Series (imap f g) g'
329 | imap f (OFlip g) = OFlip (imap f g)
331 | imap f Empty
impossible
332 | imap f (SingleVertex {vins = Just ins} v) impossible
333 | imap f (Cycle node loop
) impossible
334 | imap f (Parallel g g'
) impossible
335 | imap f (IFlip g
) impossible
340 | : {0 vertex : Vertex a}
341 | -> {outs : Neighbors a}
343 | -> ({ins : Neighbors a} -> vertex v ins Nothing -> vertex v ins outs)
344 | -> CFG vertex gins (Undefined v)
345 | -> CFG vertex gins (v ~>>? outs)
347 | omap f (SingleVertex {vouts = Nothing} v) = SingleVertex (f v)
348 | omap f (Series g g') = Series g (omap f g')
349 | omap f (IFlip g) = IFlip (omap f g)
351 | omap f Empty
impossible
352 | omap f (SingleVertex {vouts = Just outs} v) impossible
353 | omap f (Cycle node loop
) impossible
354 | omap f (Parallel g g'
) impossible
355 | omap f (OFlip g
) impossible
363 | : (impl : Connectable vertex)
364 | => CFG vertex ins (Undefined v)
365 | -> CFG vertex (Undefined v) outs
366 | -> CFG vertex ins outs
368 | connect (SingleVertex {vouts = Nothing} v) g = imap (cnct @{impl} v) g
369 | connect (Series g g') g'' = Series g (connect g' g'')
370 | connect (IFlip g) g' = IFlip (connect g g')
372 | connect Empty g'
impossible
373 | connect (SingleVertex {vouts = Just outs} v) g' impossible
374 | connect (Cycle node loop
) g'
impossible
375 | connect (Parallel g g'
) g'
impossible
376 | connect (OFlip g
) g'
impossible
378 | export infixr 5 *~>
382 | : (impl : Connectable vertex)
383 | => CFG vertex ins (Undefined v)
384 | -> CFG vertex (Undefined v) outs
385 | -> CFG vertex ins outs
390 | : {0 vertex : Vertex a}
391 | -> vertex v Nothing Nothing
392 | -> CFG vertex (Undefined v) (Undefined v)
393 | initGraph v = SingleVertex v
398 | : {0 vertex : Vertex a}
399 | -> ({outs : Neighbors a} -> vertex v Nothing outs -> b)
400 | -> CFG vertex (Undefined v) gouts
402 | iget f (SingleVertex {vins = Nothing} v) = f v
403 | iget f (Series g g') = iget f g
404 | iget f (OFlip g) = iget f g
406 | iget f Empty
impossible
407 | iget f (SingleVertex {vins = Just ins} v) impossible
408 | iget f (Cycle node loop
) impossible
409 | iget f (Parallel g g'
) impossible
410 | iget f (IFlip g
) impossible
415 | : {0 vertex : Vertex a}
416 | -> ({ins : Neighbors a} -> vertex v ins Nothing -> b)
417 | -> CFG vertex gins (Undefined v)
420 | oget f (SingleVertex {vouts = Nothing} v) = f v
421 | oget f (Series g g') = oget f g'
422 | oget f (IFlip g) = oget f g
424 | oget f Empty
impossible
425 | oget f (SingleVertex {vouts = Just outs} v) impossible
426 | oget f (Cycle node loop
) impossible
427 | oget f (Parallel g g'
) impossible
428 | oget f (OFlip g
) impossible
434 | -> {0 vertex, vertex' : Vertex a}
435 | -> {0 ins, outs : Edges a}
437 | -> {vins, vouts : Neighbors a}
438 | -> vertex v vins vouts
439 | -> vertex' v vins vouts
441 | -> CFG vertex ins outs
442 | -> CFG vertex' ins outs
444 | vmap f Empty = Empty
445 | vmap f (SingleVertex v) = SingleVertex (f v)
446 | vmap f (Cycle node loop) = Cycle (vmap f node) (vmap f loop)
447 | vmap f (Series g g') = Series (vmap f g) (vmap f g')
448 | vmap f (Parallel g g') = Parallel (vmap f g) (vmap f g')
449 | vmap f (IFlip g) = IFlip (vmap f g)
450 | vmap f (OFlip g) = OFlip (vmap f g)
459 | -> {0 vertex, vertex' : Vertex a}
460 | -> {0 ins, outs : List (Edge a)}
462 | -> {vins, vouts : List a}
463 | -> vertex v (Just vins) (Just vouts)
464 | -> vertex' v (Just vins) (Just vouts)
466 | -> CFG vertex (Defined ins) (Defined outs)
467 | -> CFG vertex' (Defined ins) (Defined outs)
469 | vmap' f (SingleVertex {vins = Just ins, vouts = Just outs} v) = SingleVertex (f v)
470 | vmap' f Empty = Empty
471 | vmap' f (Cycle node loop) = Cycle (vmap' f node) (vmap' f loop)
472 | vmap' f (Series g g') = Series (vmap' f g) (vmap' f g')
473 | vmap' f (Parallel g g') = Parallel (vmap' f g) (vmap' f g')
474 | vmap' f (IFlip g) = IFlip (vmap' f g)
475 | vmap' f (OFlip g) = OFlip (vmap' f g)
477 | vmap' f (SingleVertex {vins = Nothing} v) impossible
478 | vmap' f (SingleVertex {vouts = Nothing} v) impossible