-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPatriciaTreeWithIORef.hs
60 lines (41 loc) · 1.68 KB
/
PatriciaTreeWithIORef.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
module Enqm.DirectedAcyclicHyperGraph.PatriciaTreeWithIORef where
----------------------------------------------------------------------
-- GRAPH REPRESENTATION
----------------------------------------------------------------------
newtype Gr a b = Gr (GraphRep a b)
#if __GLASGOW_HASKELL__ >= 702
deriving (Generic)
#endif
type GraphRep a b = IntMap (Context' a b)
type Context' a b = (IntMap [Edge b], a, IntMap [Edge b])
data Edge b = Edge (IORef b)
| Hyper (IORef b)
type UGr = Gr () ()
----------------------------------------------------------------------
-- OVERRIDING FUNCTIONS
----------------------------------------------------------------------
{-# RULES
"insNode/Data.Graph.Inductive.PatriciaTree" insNode = fastInsNode
#-}
fastInsNode :: LNode a -> Gr a b -> Gr a b
fastInsNode (v, l) (Gr g) = g' `seq` Gr g'
where
g' = IM.insert v (IM.empty, l, IM.empty) g
{-# RULES
"insEdge/Data.Graph.Inductive.PatriciaTree" insEdge = fastInsEdge
#-}
fastInsEdge :: LEdge b -> Gr a b -> Gr a b
fastInsEdge (LEdge (v, w, l)) (Gr g) = g2 `seq` Gr g2
where
label = Edge $ unsafePerformIO $ newIORef l
g1 = IM.adjust addS' v g
g2 = IM.adjust addP' w g1
addS' (ps, l', ss) = (ps, l', IM.insertWith addLists w [label] ss)
addP' (ps, l', ss) = (IM.insertWith addLists v [label] ps, l', ss)
fastInsEdge (LHyper (v, w, l)) (Gr g) = g2 `seq` Gr g2
where
label = Hyper $ unsafePerformIO $ newIORef l
g1 = foldr (\v g -> IM.adjust addS' v g ) g v
g2 = foldr (\w g1 -> IM.adjust addP' w g1) g1 w
addS' (ps, l', ss) = (ps, l', IM.insertWith addLists w [label] ss)
addP' (ps, l', ss) = (IM.insertWith addLists v [label] ps, l', ss)