1 -- | Wrapper around Data.Graph with support for edge labels
2 {-# LANGUAGE ScopedTypeVariables #-}
3 module Distribution
.Solver
.Modular
.LabeledGraph
(
12 -- ** Graph properties
15 -- ** Operations on the underlying unlabeled graph
20 import Distribution
.Solver
.Compat
.Prelude
24 import Data
.Graph
(Vertex
, Bounds
)
25 import qualified Data
.Graph
as G
27 {-------------------------------------------------------------------------------
29 -------------------------------------------------------------------------------}
31 type Graph e
= Array Vertex
[(e
, Vertex
)]
32 type Edge e
= (Vertex
, e
, Vertex
)
34 {-------------------------------------------------------------------------------
36 -------------------------------------------------------------------------------}
38 -- | Construct an edge-labeled graph
40 -- This is a simple adaptation of the definition in Data.Graph
41 graphFromEdges
:: forall key node edge
. Ord key
42 => [ (node
, key
, [(edge
, key
)]) ]
44 , Vertex
-> (node
, key
, [(edge
, key
)])
47 graphFromEdges edges0
=
48 (graph
, \v -> vertex_map
! v
, key_vertex
)
50 max_v
= length edges0
- 1
51 bounds0
= (0, max_v
) :: (Vertex
, Vertex
)
52 sorted_edges
= sortBy lt edges0
53 edges1
= zip [0..] sorted_edges
55 graph
= array bounds0
[(v
, (mapMaybe mk_edge ks
))
56 |
(v
, (_
, _
, ks
)) <- edges1
]
57 key_map
= array bounds0
[(v
, k
)
58 |
(v
, (_
, k
, _
)) <- edges1
]
59 vertex_map
= array bounds0 edges1
61 (_
,k1
,_
) `lt`
(_
,k2
,_
) = k1 `
compare` k2
63 mk_edge
:: (edge
, key
) -> Maybe (edge
, Vertex
)
64 mk_edge
(edge
, key
) = do v
<- key_vertex key
; return (edge
, v
)
66 -- returns Nothing for non-interesting vertices
67 key_vertex
:: key
-> Maybe Vertex
68 key_vertex k
= findVertex
0 max_v
72 |
otherwise = case compare k
(key_map
! mid
) of
73 LT
-> findVertex a
(mid
-1)
75 GT
-> findVertex
(mid
+1) b
77 mid
= a
+ (b
- a
) `
div`
2
79 graphFromEdges
' :: Ord key
80 => [ (node
, key
, [(edge
, key
)]) ]
82 , Vertex
-> (node
, key
, [(edge
, key
)])
84 graphFromEdges
' x
= (a
,b
)
86 (a
,b
,_
) = graphFromEdges x
88 transposeG
:: Graph e
-> Graph e
89 transposeG g
= buildG
(bounds g
) (reverseE g
)
91 buildG
:: Bounds
-> [Edge e
] -> Graph e
92 buildG bounds0 edges0
= accumArray (flip (:)) [] bounds0
(map reassoc edges0
)
94 reassoc
(v
, e
, w
) = (v
, (e
, w
))
96 reverseE
:: Graph e
-> [Edge e
]
97 reverseE g
= [ (w
, e
, v
) |
(v
, e
, w
) <- edges g
]
99 {-------------------------------------------------------------------------------
101 -------------------------------------------------------------------------------}
103 vertices
:: Graph e
-> [Vertex
]
106 edges
:: Graph e
-> [Edge e
]
107 edges g
= [ (v
, e
, w
) | v
<- vertices g
, (e
, w
) <- g
!v
]
109 {-------------------------------------------------------------------------------
110 Operations on the underlying unlabelled graph
111 -------------------------------------------------------------------------------}
113 forgetLabels
:: Graph e
-> G
.Graph
114 forgetLabels
= fmap (map snd)
116 topSort
:: Graph e
-> [Vertex
]
117 topSort
= G
.topSort
. forgetLabels