0 | module Geom.Gen2D.Types
3 | import public Data.Graph.Indexed.Subgraph
4 | import Data.Graph.Indexed.Query.Visited
6 | import Data.SortedMap
7 | import Derive.Prelude
10 | %language ElabReflection
17 | 0 Nodes : Nat -> Type
21 | 0 SnocNodes : Nat -> Type
22 | SnocNodes = SnocList . Fin
25 | data AttachPoint : (k : Nat) -> Type where
26 | None : AttachPoint k
27 | Attach : (parent : Fin k) -> (node : Fin k) -> AttachPoint k
29 | %runElab deriveIndexed "AttachPoint" [Show,Eq]
32 | 0 SubgraphType : Bool -> Nat -> Type -> Type -> Type
33 | SubgraphType True k e n = Subgraph k e n
34 | SubgraphType False _ _ _ = ()
43 | record Component (k : Nat) (e,n : Type) where
45 | attach : AttachPoint k
46 | nodes : List (Fin k)
48 | subgraph : SubgraphType isRing k e n
51 | 0 SnocComps : Nat -> Type -> Type -> Type
52 | SnocComps k e = SnocList . Component k e
55 | 0 Comps : Nat -> Type -> Type -> Type
56 | Comps k e = List . Component k e
58 | setAttach : (a,x : Fin k) -> Component k e n -> Component k e n
59 | setAttach a x = {attach := Attach a x}
66 | 0 RingMap : Nat -> Type -> Type -> Type
67 | RingMap k e n = IArray k (Maybe $
Component k e n)
70 | subnodes : Subgraph k e n -> List (Fin k)
71 | subnodes (G _ g) = fst <$> labels g
73 | children : IGraph k e n -> Visited k -> Component k e n -> List (Fin k, Fin k)
75 | nodes c >>= \a => (a,) <$> filter (flip unvisited v) (neighbours g a)
81 | pairs : Subgraph k e n -> List (Nat, Maybe $
Component k e n)
83 | let ns := subnodes g
84 | c := Just (C None ns True g)
85 | in map (\x => (finToNat x ,c)) ns
90 | rings : {k : _} -> (g : IGraph k e n) -> Maybe (Component k e n, RingMap k e n)
92 | case reverse $
sortBy (comparing order) (biconnectedComponents g) of
94 | r::rs => Just (C None (subnodes r) True r, fromPairs k Nothing (rs >>= pairs))
96 | parameters {k : Nat}
101 | nonVisitedInChain : Visited k -> Fin k -> Bool
102 | nonVisitedInChain v n = isNothing (m `at` n) && unvisited n v
105 | lcf : SnocNodes k -> Queue (SnocNodes k, Fin k) -> Visited k -> SnocNodes k
109 | Just ((sy,y),q2) =>
111 | ns := filter (nonVisitedInChain vis) (neighbours g y)
112 | v2 := assert_smaller vis (visitAll ns vis)
113 | in lcf ss (enqueueAll q2 $
(ss,) <$> ns) v2
117 | chain : Visited k -> Fin k -> SnocList (Fin k)
118 | chain vis x = lcf [<] (enqueue empty ([<], x)) (visit x vis)
120 | nextComp : Visited k -> (a,x : Fin k) -> Component k e n
122 | maybe (C (Attach a x) (chain v x <>> []) False ()) (setAttach a x) (at m x)
126 | chains : SnocComps k e n -> Queue (Fin k,Fin k) -> Visited k -> (Comps k e n)
129 | Nothing => sx <>> []
131 | let c := nextComp vis a n
132 | vis2 := assert_smaller vis $
visitAll (nodes c) vis
133 | q3 := enqueueAll q2 (children g vis2 c)
134 | in chains (sx:<c) q3 vis2
144 | components : {k : _} -> IGraph k e n -> List (Component k e n)
145 | components {k = Z} g = []
146 | components {k = S x} g =
149 | let vis := visitAll (nodes c) ini
150 | in chains g m [<c] (fromList $
children g vis c) vis
152 | let m := fill (S x) Nothing
153 | _ :< n := chain g m ini FZ | [<] => []
154 | ns := reverse $
chain g m ini n <>> []
155 | c := C None ns False ()
156 | vis := visitAll ns ini
157 | in chains g m [<c] (fromList $
children g vis c) vis