10 | module Data.Graph.Indexed.Ring.Relevant.ShortestPath
12 | import Data.Array.Mutable
13 | import Data.Graph.Indexed.Ring.Relevant.Types
14 | import Data.Linear.Ref1
17 | import public Data.Graph.Indexed
18 | import public Data.Graph.Indexed.Subgraph
25 | smaller : Fin o -> (rdeg : Nat) -> ISubgraph o k e Nat -> Fin o -> Bool
26 | smaller root rdeg g n =
27 | case compare (snd $
lab g n) rdeg of
32 | parameters {o : Nat}
33 | (g : ISubgraph o k e Nat)
36 | (q : Ref s (Queue $
Fin o))
37 | (r : MArray s o (Path o))
41 | deq : F1 s (Maybe $
Fin o)
43 | let qu # t := read1 q t
44 | in case dequeue qu of
45 | Nothing => Nothing # t
46 | Just (v,q2) => let _ # t := write1 q q2 t in Just v # t
50 | enq : Fin o -> F1' s
51 | enq v t = let qu # t := read1 q t in write1 q (enqueue qu v) t
54 | append : Path o -> Fin o -> Path o
55 | append (P l p k fs ls c) n =
61 | then P (S l) (p :< n) (smaller root rdeg g n) n n c
62 | else P (S l) (p :< n) (k && smaller root rdeg g n) fs n c
68 | merge : Path o -> Fin o -> Path o -> Path o
70 | let True := S p.length == q.length | False => q
71 | True := p.keep | False => q
72 | True := q.keep | False => append p n
73 | in {combos $= (+ p.combos)} q
76 | adjNeighbours : Path o -> List (Fin o) -> F1' s
77 | adjNeighbours p [] t = () # t
78 | adjNeighbours p (x::xs) t =
79 | let p2 # t := Core.get r x t
80 | in case p2.length of
83 | let _ # t := set r x (append p x) t
85 | in adjNeighbours p xs t
88 | let _ # t := set r x (merge p x p2) t
89 | in adjNeighbours p xs t
92 | impl : SnocList (Path o) -> F1 s (List $
Path o)
96 | Nothing # t => (sp <>> []) # t
98 | let p # t := Core.get r n t
99 | False := p.length * 2 > o | True => (sp <>> []) # t
100 | _ # t := adjNeighbours p (neighbours g n) t
101 | in impl (if p.keep then sp :< p else sp) t
105 | toDegs : Subgraph k e n -> Subgraph k e Nat
106 | toDegs (G o g) = G o $
mapAdj (\(A (x,_) ns) => A (x, length ns) ns) g
115 | shortestPaths : {o : _} -> ISubgraph o k e Nat -> Fin o -> List (Path o)
116 | shortestPaths g root =
117 | assert_total $
run1 $
\t =>
118 | let r # t := marray1 o (P 0 [<] False root root 0) t
119 | q # t := ref1 (Queue.fromList [root]) t
120 | _ # t := set r root (P 1 [<root] False root root 1) t
121 | in impl g root (snd $
lab g root) q r [<] t