2 | import Data.SortedMap
5 | import Control.Barbie
6 | import Derive.Prelude
10 | %language ElabReflection
15 | data NodeId : Type where
16 | MkNodeId : (id : Nat) -> NodeId
17 | %name NodeId
id, id_2, id_3
18 | %runElab derive "NodeId" [Eq, Ord]
21 | Show NodeId where show (MkNodeId id) = show id
23 | inner : NodeId -> Nat
24 | inner (MkNodeId id) = id
26 | next : List NodeId -> NodeId
27 | next [] = MkNodeId 0
29 | let ids = map inner $
x ::: xs
30 | max = foldl1 max ids
34 | data Field = NodeWeights | EdgeWeights
37 | Tpe : (n, e : Type) -> Field -> Type
38 | Tpe n e NodeWeights = n
39 | Tpe n e EdgeWeights = e
41 | %prefix_record_projections off
44 | record Graph (f : Field -> Type) where
46 | nodes : SortedMap NodeId (f NodeWeights)
47 | edges : SortedMap (NodeId, NodeId) (f EdgeWeights)
49 | FunctorB Field Graph where
50 | bmap_ f (MkGraph nodes edges) =
51 | let nodes = map (\x => (f NodeWeights) x) nodes
52 | edges = map (\x => (f EdgeWeights) x) edges
53 | in MkGraph nodes edges
56 | IGraph : (n, e : Type) -> Type
57 | IGraph n e = Graph (Tpe n e)
60 | Show (f NodeWeights) => Show (f EdgeWeights) => Show (Graph f) where
61 | show (MkGraph nodes edges) =
62 | let (node_size, edge_size) = (length . keys $
nodes, length . keys $
edges)
63 | header = "Graph with \{show node_size} nodes and \{show edge_size} edges"
66 | . map (\(x,y) => "\{show x}: \{show y}")
67 | . Data.SortedMap.toList
71 | . map (\(x,y) => "\{show x}: \{show y}")
72 | . Data.SortedMap.toList
74 | in "\{header}\n Nodes ->\n \{nodes}\n Edges ->\n \{edges}"
80 | empty = MkGraph empty empty
85 | (weight : f NodeWeights) -> (graph : Graph f)
86 | -> (NodeId, Graph f)
87 | insert_node weight (MkGraph nodes edges) =
88 | let node_id = next . keys $
nodes
89 | nodes = insert node_id weight nodes
90 | in (node_id, MkGraph nodes edges)
95 | (edge : (NodeId, NodeId)) -> (weight : f EdgeWeights) -> (graph : Graph f)
97 | insert_edge edge weight (MkGraph nodes edges) =
98 | let edges = insert edge weight edges
99 | in MkGraph nodes edges
104 | (node_id : NodeId) -> (graph : Graph f)
105 | -> Maybe (f NodeWeights)
106 | node_weight node_id (MkGraph nodes edges) = lookup node_id nodes
111 | (pair : (NodeId, NodeId)) -> (graph : Graph f)
112 | -> Maybe (f EdgeWeights)
113 | edge_weight pair (MkGraph nodes edges) = lookup pair edges
117 | contains_node_weight :
118 | Eq (f NodeWeights) =>
119 | (weight : f NodeWeights) -> (graph : Graph f)
121 | contains_node_weight weight (MkGraph nodes edges) =
122 | map fst . head' . filter ((== weight) . snd) . toList $
nodes
126 | contains_edge_weight :
127 | Eq (f EdgeWeights) =>
128 | (weight : f EdgeWeights) -> (graph : Graph f)
129 | -> Maybe (NodeId, NodeId)
130 | contains_edge_weight weight (MkGraph nodes edges) =
131 | map fst . head' . filter ((== weight) . snd) . toList $
edges
135 | nodes : (graph : Graph f) -> List NodeId
136 | nodes (MkGraph ns edges) = keys ns
140 | edges : (graph : Graph f) -> List (NodeId, NodeId)
141 | edges (MkGraph nodes es) = keys es
145 | outbound_edges : (node : NodeId) -> (graph : Graph f) -> Maybe (List (NodeId, NodeId))
146 | outbound_edges node (MkGraph nodes edges) = do
147 | _ <- lookup node nodes
148 | pure . filter ((== node) . fst) . keys $
edges
152 | inbound_edges : (node : NodeId) -> (graph : Graph f) -> Maybe (List (NodeId, NodeId))
153 | inbound_edges node (MkGraph nodes edges) = do
154 | _ <- lookup node nodes
155 | pure . filter ((== node) . snd) . keys $
edges
159 | visited : Graph (Tpe n e) -> Graph (const Bool)
160 | visited graph = bmap (const False) graph