PageRenderTime 59ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/compiler/coreSyn/TrieMap.lhs

https://github.com/crdueck/ghc
Haskell | 812 lines | 650 code | 134 blank | 28 comment | 1 complexity | befaec35d9fb76b34f62a21e7bf92df5 MD5 | raw file
  1. %
  2. % (c) The University of Glasgow 2006
  3. % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
  4. %
  5. \begin{code}
  6. {-# OPTIONS -fno-warn-tabs #-}
  7. -- The above warning supression flag is a temporary kludge.
  8. -- While working on this module you are encouraged to remove it and
  9. -- detab the module (please do the detabbing in a separate patch). See
  10. -- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
  11. -- for details
  12. {-# LANGUAGE TypeFamilies #-}
  13. module TrieMap(
  14. CoreMap, emptyCoreMap, extendCoreMap, lookupCoreMap, foldCoreMap,
  15. TypeMap, emptyTypeMap, extendTypeMap, lookupTypeMap, foldTypeMap,
  16. CoercionMap,
  17. MaybeMap,
  18. ListMap,
  19. TrieMap(..)
  20. ) where
  21. import CoreSyn
  22. import Coercion
  23. import Literal
  24. import Name
  25. import Type
  26. import TypeRep
  27. import Var
  28. import UniqFM
  29. import Unique( Unique )
  30. import FastString(FastString)
  31. import qualified Data.Map as Map
  32. import qualified Data.IntMap as IntMap
  33. import VarEnv
  34. import NameEnv
  35. import Outputable
  36. import Control.Monad( (>=>) )
  37. \end{code}
  38. This module implements TrieMaps, which are finite mappings
  39. whose key is a structured value like a CoreExpr or Type.
  40. The code is very regular and boilerplate-like, but there is
  41. some neat handling of *binders*. In effect they are deBruijn
  42. numbered on the fly.
  43. %************************************************************************
  44. %* *
  45. The TrieMap class
  46. %* *
  47. %************************************************************************
  48. \begin{code}
  49. type XT a = Maybe a -> Maybe a -- How to alter a non-existent elt (Nothing)
  50. -- or an existing elt (Just)
  51. class TrieMap m where
  52. type Key m :: *
  53. emptyTM :: m a
  54. lookupTM :: forall b. Key m -> m b -> Maybe b
  55. alterTM :: forall b. Key m -> XT b -> m b -> m b
  56. mapTM :: (a->b) -> m a -> m b
  57. foldTM :: (a -> b -> b) -> m a -> b -> b
  58. -- The unusual argument order here makes
  59. -- it easy to compose calls to foldTM;
  60. -- see for example fdE below
  61. ----------------------
  62. -- Recall that
  63. -- Control.Monad.(>=>) :: (a -> Maybe b) -> (b -> Maybe c) -> a -> Maybe c
  64. (>.>) :: (a -> b) -> (b -> c) -> a -> c
  65. -- Reverse function composition (do f first, then g)
  66. infixr 1 >.>
  67. (f >.> g) x = g (f x)
  68. infixr 1 |>, |>>
  69. (|>) :: a -> (a->b) -> b -- Reverse application
  70. x |> f = f x
  71. ----------------------
  72. (|>>) :: TrieMap m2
  73. => (XT (m2 a) -> m1 (m2 a) -> m1 (m2 a))
  74. -> (m2 a -> m2 a)
  75. -> m1 (m2 a) -> m1 (m2 a)
  76. (|>>) f g = f (Just . g . deMaybe)
  77. deMaybe :: TrieMap m => Maybe (m a) -> m a
  78. deMaybe Nothing = emptyTM
  79. deMaybe (Just m) = m
  80. \end{code}
  81. %************************************************************************
  82. %* *
  83. IntMaps
  84. %* *
  85. %************************************************************************
  86. \begin{code}
  87. instance TrieMap IntMap.IntMap where
  88. type Key IntMap.IntMap = Int
  89. emptyTM = IntMap.empty
  90. lookupTM k m = IntMap.lookup k m
  91. alterTM = xtInt
  92. foldTM k m z = IntMap.fold k z m
  93. mapTM f m = IntMap.map f m
  94. xtInt :: Int -> XT a -> IntMap.IntMap a -> IntMap.IntMap a
  95. xtInt k f m = IntMap.alter f k m
  96. instance Ord k => TrieMap (Map.Map k) where
  97. type Key (Map.Map k) = k
  98. emptyTM = Map.empty
  99. lookupTM = Map.lookup
  100. alterTM k f m = Map.alter f k m
  101. foldTM k m z = Map.fold k z m
  102. mapTM f m = Map.map f m
  103. instance TrieMap UniqFM where
  104. type Key UniqFM = Unique
  105. emptyTM = emptyUFM
  106. lookupTM k m = lookupUFM m k
  107. alterTM k f m = alterUFM f m k
  108. foldTM k m z = foldUFM k z m
  109. mapTM f m = mapUFM f m
  110. \end{code}
  111. %************************************************************************
  112. %* *
  113. Lists
  114. %* *
  115. %************************************************************************
  116. If m is a map from k -> val
  117. then (MaybeMap m) is a map from (Maybe k) -> val
  118. \begin{code}
  119. data MaybeMap m a = MM { mm_nothing :: Maybe a, mm_just :: m a }
  120. instance TrieMap m => TrieMap (MaybeMap m) where
  121. type Key (MaybeMap m) = Maybe (Key m)
  122. emptyTM = MM { mm_nothing = Nothing, mm_just = emptyTM }
  123. lookupTM = lkMaybe lookupTM
  124. alterTM = xtMaybe alterTM
  125. foldTM = fdMaybe
  126. mapTM = mapMb
  127. mapMb :: TrieMap m => (a->b) -> MaybeMap m a -> MaybeMap m b
  128. mapMb f (MM { mm_nothing = mn, mm_just = mj })
  129. = MM { mm_nothing = fmap f mn, mm_just = mapTM f mj }
  130. lkMaybe :: TrieMap m => (forall b. k -> m b -> Maybe b)
  131. -> Maybe k -> MaybeMap m a -> Maybe a
  132. lkMaybe _ Nothing = mm_nothing
  133. lkMaybe lk (Just x) = mm_just >.> lk x
  134. xtMaybe :: TrieMap m => (forall b. k -> XT b -> m b -> m b)
  135. -> Maybe k -> XT a -> MaybeMap m a -> MaybeMap m a
  136. xtMaybe _ Nothing f m = m { mm_nothing = f (mm_nothing m) }
  137. xtMaybe tr (Just x) f m = m { mm_just = mm_just m |> tr x f }
  138. fdMaybe :: TrieMap m => (a -> b -> b) -> MaybeMap m a -> b -> b
  139. fdMaybe k m = foldMaybe k (mm_nothing m)
  140. . foldTM k (mm_just m)
  141. --------------------
  142. data ListMap m a
  143. = LM { lm_nil :: Maybe a
  144. , lm_cons :: m (ListMap m a) }
  145. instance TrieMap m => TrieMap (ListMap m) where
  146. type Key (ListMap m) = [Key m]
  147. emptyTM = LM { lm_nil = Nothing, lm_cons = emptyTM }
  148. lookupTM = lkList lookupTM
  149. alterTM = xtList alterTM
  150. foldTM = fdList
  151. mapTM = mapList
  152. mapList :: TrieMap m => (a->b) -> ListMap m a -> ListMap m b
  153. mapList f (LM { lm_nil = mnil, lm_cons = mcons })
  154. = LM { lm_nil = fmap f mnil, lm_cons = mapTM (mapTM f) mcons }
  155. lkList :: TrieMap m => (forall b. k -> m b -> Maybe b)
  156. -> [k] -> ListMap m a -> Maybe a
  157. lkList _ [] = lm_nil
  158. lkList lk (x:xs) = lm_cons >.> lk x >=> lkList lk xs
  159. xtList :: TrieMap m => (forall b. k -> XT b -> m b -> m b)
  160. -> [k] -> XT a -> ListMap m a -> ListMap m a
  161. xtList _ [] f m = m { lm_nil = f (lm_nil m) }
  162. xtList tr (x:xs) f m = m { lm_cons = lm_cons m |> tr x |>> xtList tr xs f }
  163. fdList :: forall m a b. TrieMap m
  164. => (a -> b -> b) -> ListMap m a -> b -> b
  165. fdList k m = foldMaybe k (lm_nil m)
  166. . foldTM (fdList k) (lm_cons m)
  167. foldMaybe :: (a -> b -> b) -> Maybe a -> b -> b
  168. foldMaybe _ Nothing b = b
  169. foldMaybe k (Just a) b = k a b
  170. \end{code}
  171. %************************************************************************
  172. %* *
  173. Basic maps
  174. %* *
  175. %************************************************************************
  176. \begin{code}
  177. lkNamed :: NamedThing n => n -> NameEnv a -> Maybe a
  178. lkNamed n env = lookupNameEnv env (getName n)
  179. xtNamed :: NamedThing n => n -> XT a -> NameEnv a -> NameEnv a
  180. xtNamed tc f m = alterNameEnv f m (getName tc)
  181. ------------------------
  182. type LiteralMap a = Map.Map Literal a
  183. emptyLiteralMap :: LiteralMap a
  184. emptyLiteralMap = emptyTM
  185. lkLit :: Literal -> LiteralMap a -> Maybe a
  186. lkLit = lookupTM
  187. xtLit :: Literal -> XT a -> LiteralMap a -> LiteralMap a
  188. xtLit = alterTM
  189. \end{code}
  190. %************************************************************************
  191. %* *
  192. CoreMap
  193. %* *
  194. %************************************************************************
  195. Note [Binders]
  196. ~~~~~~~~~~~~~~
  197. * In general we check binders as late as possible because types are
  198. less likely to differ than expression structure. That's why
  199. cm_lam :: CoreMap (TypeMap a)
  200. rather than
  201. cm_lam :: TypeMap (CoreMap a)
  202. * We don't need to look at the type of some binders, notalby
  203. - the case binder in (Case _ b _ _)
  204. - the binders in an alternative
  205. because they are totally fixed by the context
  206. Note [Empty case alternatives]
  207. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  208. * For a key (Case e b ty (alt:alts)) we don't need to look the return type
  209. 'ty', because every alternative has that type.
  210. * For a key (Case e b ty []) we MUST look at the return type 'ty', because
  211. otherwise (Case (error () "urk") _ Int []) would compare equal to
  212. (Case (error () "urk") _ Bool [])
  213. which is utterly wrong (Trac #6097)
  214. We could compare the return type regardless, but the wildly common case
  215. is that it's unnecesary, so we have two fields (cm_case and cm_ecase)
  216. for the two possibilities. Only cm_ecase looks at the type.
  217. See also Note [Empty case alternatives] in CoreSyn.
  218. \begin{code}
  219. data CoreMap a
  220. = EmptyCM
  221. | CM { cm_var :: VarMap a
  222. , cm_lit :: LiteralMap a
  223. , cm_co :: CoercionMap a
  224. , cm_type :: TypeMap a
  225. , cm_cast :: CoreMap (CoercionMap a)
  226. , cm_tick :: CoreMap (TickishMap a)
  227. , cm_app :: CoreMap (CoreMap a)
  228. , cm_lam :: CoreMap (TypeMap a) -- Note [Binders]
  229. , cm_letn :: CoreMap (CoreMap (BndrMap a))
  230. , cm_letr :: ListMap CoreMap (CoreMap (ListMap BndrMap a))
  231. , cm_case :: CoreMap (ListMap AltMap a)
  232. , cm_ecase :: CoreMap (TypeMap a) -- Note [Empty case alternatives]
  233. }
  234. wrapEmptyCM :: CoreMap a
  235. wrapEmptyCM = CM { cm_var = emptyTM, cm_lit = emptyLiteralMap
  236. , cm_co = emptyTM, cm_type = emptyTM
  237. , cm_cast = emptyTM, cm_app = emptyTM
  238. , cm_lam = emptyTM, cm_letn = emptyTM
  239. , cm_letr = emptyTM, cm_case = emptyTM
  240. , cm_ecase = emptyTM, cm_tick = emptyTM }
  241. instance TrieMap CoreMap where
  242. type Key CoreMap = CoreExpr
  243. emptyTM = EmptyCM
  244. lookupTM = lkE emptyCME
  245. alterTM = xtE emptyCME
  246. foldTM = fdE
  247. mapTM = mapE
  248. --------------------------
  249. mapE :: (a->b) -> CoreMap a -> CoreMap b
  250. mapE _ EmptyCM = EmptyCM
  251. mapE f (CM { cm_var = cvar, cm_lit = clit
  252. , cm_co = cco, cm_type = ctype
  253. , cm_cast = ccast , cm_app = capp
  254. , cm_lam = clam, cm_letn = cletn
  255. , cm_letr = cletr, cm_case = ccase
  256. , cm_ecase = cecase, cm_tick = ctick })
  257. = CM { cm_var = mapTM f cvar, cm_lit = mapTM f clit
  258. , cm_co = mapTM f cco, cm_type = mapTM f ctype
  259. , cm_cast = mapTM (mapTM f) ccast, cm_app = mapTM (mapTM f) capp
  260. , cm_lam = mapTM (mapTM f) clam, cm_letn = mapTM (mapTM (mapTM f)) cletn
  261. , cm_letr = mapTM (mapTM (mapTM f)) cletr, cm_case = mapTM (mapTM f) ccase
  262. , cm_ecase = mapTM (mapTM f) cecase, cm_tick = mapTM (mapTM f) ctick }
  263. --------------------------
  264. lookupCoreMap :: CoreMap a -> CoreExpr -> Maybe a
  265. lookupCoreMap cm e = lkE emptyCME e cm
  266. extendCoreMap :: CoreMap a -> CoreExpr -> a -> CoreMap a
  267. extendCoreMap m e v = xtE emptyCME e (\_ -> Just v) m
  268. foldCoreMap :: (a -> b -> b) -> b -> CoreMap a -> b
  269. foldCoreMap k z m = fdE k m z
  270. emptyCoreMap :: CoreMap a
  271. emptyCoreMap = EmptyCM
  272. instance Outputable a => Outputable (CoreMap a) where
  273. ppr m = text "CoreMap elts" <+> ppr (foldCoreMap (:) [] m)
  274. -------------------------
  275. fdE :: (a -> b -> b) -> CoreMap a -> b -> b
  276. fdE _ EmptyCM = \z -> z
  277. fdE k m
  278. = foldTM k (cm_var m)
  279. . foldTM k (cm_lit m)
  280. . foldTM k (cm_co m)
  281. . foldTM k (cm_type m)
  282. . foldTM (foldTM k) (cm_cast m)
  283. . foldTM (foldTM k) (cm_tick m)
  284. . foldTM (foldTM k) (cm_app m)
  285. . foldTM (foldTM k) (cm_lam m)
  286. . foldTM (foldTM (foldTM k)) (cm_letn m)
  287. . foldTM (foldTM (foldTM k)) (cm_letr m)
  288. . foldTM (foldTM k) (cm_case m)
  289. . foldTM (foldTM k) (cm_ecase m)
  290. lkE :: CmEnv -> CoreExpr -> CoreMap a -> Maybe a
  291. -- lkE: lookup in trie for expressions
  292. lkE env expr cm
  293. | EmptyCM <- cm = Nothing
  294. | otherwise = go expr cm
  295. where
  296. go (Var v) = cm_var >.> lkVar env v
  297. go (Lit l) = cm_lit >.> lkLit l
  298. go (Type t) = cm_type >.> lkT env t
  299. go (Coercion c) = cm_co >.> lkC env c
  300. go (Cast e c) = cm_cast >.> lkE env e >=> lkC env c
  301. go (Tick tickish e) = cm_tick >.> lkE env e >=> lkTickish tickish
  302. go (App e1 e2) = cm_app >.> lkE env e2 >=> lkE env e1
  303. go (Lam v e) = cm_lam >.> lkE (extendCME env v) e >=> lkBndr env v
  304. go (Let (NonRec b r) e) = cm_letn >.> lkE env r
  305. >=> lkE (extendCME env b) e >=> lkBndr env b
  306. go (Let (Rec prs) e) = let (bndrs,rhss) = unzip prs
  307. env1 = extendCMEs env bndrs
  308. in cm_letr
  309. >.> lkList (lkE env1) rhss >=> lkE env1 e
  310. >=> lkList (lkBndr env1) bndrs
  311. go (Case e b ty as) -- See Note [Empty case alternatives]
  312. | null as = cm_ecase >.> lkE env e >=> lkT env ty
  313. | otherwise = cm_case >.> lkE env e
  314. >=> lkList (lkA (extendCME env b)) as
  315. xtE :: CmEnv -> CoreExpr -> XT a -> CoreMap a -> CoreMap a
  316. xtE env e f EmptyCM = xtE env e f wrapEmptyCM
  317. xtE env (Var v) f m = m { cm_var = cm_var m |> xtVar env v f }
  318. xtE env (Type t) f m = m { cm_type = cm_type m |> xtT env t f }
  319. xtE env (Coercion c) f m = m { cm_co = cm_co m |> xtC env c f }
  320. xtE _ (Lit l) f m = m { cm_lit = cm_lit m |> xtLit l f }
  321. xtE env (Cast e c) f m = m { cm_cast = cm_cast m |> xtE env e |>>
  322. xtC env c f }
  323. xtE env (Tick t e) f m = m { cm_tick = cm_tick m |> xtE env e |>> xtTickish t f }
  324. xtE env (App e1 e2) f m = m { cm_app = cm_app m |> xtE env e2 |>> xtE env e1 f }
  325. xtE env (Lam v e) f m = m { cm_lam = cm_lam m |> xtE (extendCME env v) e
  326. |>> xtBndr env v f }
  327. xtE env (Let (NonRec b r) e) f m = m { cm_letn = cm_letn m
  328. |> xtE (extendCME env b) e
  329. |>> xtE env r |>> xtBndr env b f }
  330. xtE env (Let (Rec prs) e) f m = m { cm_letr = let (bndrs,rhss) = unzip prs
  331. env1 = extendCMEs env bndrs
  332. in cm_letr m
  333. |> xtList (xtE env1) rhss
  334. |>> xtE env1 e
  335. |>> xtList (xtBndr env1) bndrs f }
  336. xtE env (Case e b ty as) f m
  337. | null as = m { cm_ecase = cm_ecase m |> xtE env e |>> xtT env ty f }
  338. | otherwise = m { cm_case = cm_case m |> xtE env e
  339. |>> let env1 = extendCME env b
  340. in xtList (xtA env1) as f }
  341. type TickishMap a = Map.Map (Tickish Id) a
  342. lkTickish :: Tickish Id -> TickishMap a -> Maybe a
  343. lkTickish = lookupTM
  344. xtTickish :: Tickish Id -> XT a -> TickishMap a -> TickishMap a
  345. xtTickish = alterTM
  346. ------------------------
  347. data AltMap a -- A single alternative
  348. = AM { am_deflt :: CoreMap a
  349. , am_data :: NameEnv (CoreMap a)
  350. , am_lit :: LiteralMap (CoreMap a) }
  351. instance TrieMap AltMap where
  352. type Key AltMap = CoreAlt
  353. emptyTM = AM { am_deflt = emptyTM
  354. , am_data = emptyNameEnv
  355. , am_lit = emptyLiteralMap }
  356. lookupTM = lkA emptyCME
  357. alterTM = xtA emptyCME
  358. foldTM = fdA
  359. mapTM = mapA
  360. mapA :: (a->b) -> AltMap a -> AltMap b
  361. mapA f (AM { am_deflt = adeflt, am_data = adata, am_lit = alit })
  362. = AM { am_deflt = mapTM f adeflt
  363. , am_data = mapNameEnv (mapTM f) adata
  364. , am_lit = mapTM (mapTM f) alit }
  365. lkA :: CmEnv -> CoreAlt -> AltMap a -> Maybe a
  366. lkA env (DEFAULT, _, rhs) = am_deflt >.> lkE env rhs
  367. lkA env (LitAlt lit, _, rhs) = am_lit >.> lkLit lit >=> lkE env rhs
  368. lkA env (DataAlt dc, bs, rhs) = am_data >.> lkNamed dc >=> lkE (extendCMEs env bs) rhs
  369. xtA :: CmEnv -> CoreAlt -> XT a -> AltMap a -> AltMap a
  370. xtA env (DEFAULT, _, rhs) f m = m { am_deflt = am_deflt m |> xtE env rhs f }
  371. xtA env (LitAlt l, _, rhs) f m = m { am_lit = am_lit m |> xtLit l |>> xtE env rhs f }
  372. xtA env (DataAlt d, bs, rhs) f m = m { am_data = am_data m |> xtNamed d
  373. |>> xtE (extendCMEs env bs) rhs f }
  374. fdA :: (a -> b -> b) -> AltMap a -> b -> b
  375. fdA k m = foldTM k (am_deflt m)
  376. . foldTM (foldTM k) (am_data m)
  377. . foldTM (foldTM k) (am_lit m)
  378. \end{code}
  379. %************************************************************************
  380. %* *
  381. Coercions
  382. %* *
  383. %************************************************************************
  384. \begin{code}
  385. data CoercionMap a
  386. = EmptyKM
  387. | KM { km_refl :: RoleMap (TypeMap a)
  388. , km_tc_app :: RoleMap (NameEnv (ListMap CoercionMap a))
  389. , km_app :: CoercionMap (CoercionMap a)
  390. , km_forall :: CoercionMap (TypeMap a)
  391. , km_var :: VarMap a
  392. , km_axiom :: NameEnv (IntMap.IntMap (ListMap CoercionMap a))
  393. , km_univ :: RoleMap (TypeMap (TypeMap a))
  394. , km_sym :: CoercionMap a
  395. , km_trans :: CoercionMap (CoercionMap a)
  396. , km_nth :: IntMap.IntMap (CoercionMap a)
  397. , km_left :: CoercionMap a
  398. , km_right :: CoercionMap a
  399. , km_inst :: CoercionMap (TypeMap a)
  400. , km_sub :: CoercionMap a }
  401. wrapEmptyKM :: CoercionMap a
  402. wrapEmptyKM = KM { km_refl = emptyTM, km_tc_app = emptyTM
  403. , km_app = emptyTM, km_forall = emptyTM
  404. , km_var = emptyTM, km_axiom = emptyNameEnv
  405. , km_univ = emptyTM, km_sym = emptyTM, km_trans = emptyTM
  406. , km_nth = emptyTM, km_left = emptyTM, km_right = emptyTM
  407. , km_inst = emptyTM, km_sub = emptyTM }
  408. instance TrieMap CoercionMap where
  409. type Key CoercionMap = Coercion
  410. emptyTM = EmptyKM
  411. lookupTM = lkC emptyCME
  412. alterTM = xtC emptyCME
  413. foldTM = fdC
  414. mapTM = mapC
  415. mapC :: (a->b) -> CoercionMap a -> CoercionMap b
  416. mapC _ EmptyKM = EmptyKM
  417. mapC f (KM { km_refl = krefl, km_tc_app = ktc
  418. , km_app = kapp, km_forall = kforall
  419. , km_var = kvar, km_axiom = kax
  420. , km_univ = kuniv , km_sym = ksym, km_trans = ktrans
  421. , km_nth = knth, km_left = kml, km_right = kmr
  422. , km_inst = kinst, km_sub = ksub })
  423. = KM { km_refl = mapTM (mapTM f) krefl
  424. , km_tc_app = mapTM (mapNameEnv (mapTM f)) ktc
  425. , km_app = mapTM (mapTM f) kapp
  426. , km_forall = mapTM (mapTM f) kforall
  427. , km_var = mapTM f kvar
  428. , km_axiom = mapNameEnv (IntMap.map (mapTM f)) kax
  429. , km_univ = mapTM (mapTM (mapTM f)) kuniv
  430. , km_sym = mapTM f ksym
  431. , km_trans = mapTM (mapTM f) ktrans
  432. , km_nth = IntMap.map (mapTM f) knth
  433. , km_left = mapTM f kml
  434. , km_right = mapTM f kmr
  435. , km_inst = mapTM (mapTM f) kinst
  436. , km_sub = mapTM f ksub }
  437. lkC :: CmEnv -> Coercion -> CoercionMap a -> Maybe a
  438. lkC env co m
  439. | EmptyKM <- m = Nothing
  440. | otherwise = go co m
  441. where
  442. go (Refl r ty) = km_refl >.> lookupTM r >=> lkT env ty
  443. go (TyConAppCo r tc cs) = km_tc_app >.> lookupTM r >=> lkNamed tc >=> lkList (lkC env) cs
  444. go (AxiomInstCo ax ind cs) = km_axiom >.> lkNamed ax >=> lookupTM ind >=> lkList (lkC env) cs
  445. go (AppCo c1 c2) = km_app >.> lkC env c1 >=> lkC env c2
  446. go (TransCo c1 c2) = km_trans >.> lkC env c1 >=> lkC env c2
  447. go (UnivCo r t1 t2) = km_univ >.> lookupTM r >=> lkT env t1 >=> lkT env t2
  448. go (InstCo c t) = km_inst >.> lkC env c >=> lkT env t
  449. go (ForAllCo v c) = km_forall >.> lkC (extendCME env v) c >=> lkBndr env v
  450. go (CoVarCo v) = km_var >.> lkVar env v
  451. go (SymCo c) = km_sym >.> lkC env c
  452. go (NthCo n c) = km_nth >.> lookupTM n >=> lkC env c
  453. go (LRCo CLeft c) = km_left >.> lkC env c
  454. go (LRCo CRight c) = km_right >.> lkC env c
  455. go (SubCo c) = km_sub >.> lkC env c
  456. xtC :: CmEnv -> Coercion -> XT a -> CoercionMap a -> CoercionMap a
  457. xtC env co f EmptyKM = xtC env co f wrapEmptyKM
  458. xtC env (Refl r ty) f m = m { km_refl = km_refl m |> xtR r |>> xtT env ty f }
  459. xtC env (TyConAppCo r tc cs) f m = m { km_tc_app = km_tc_app m |> xtR r |>> xtNamed tc |>> xtList (xtC env) cs f }
  460. xtC env (AxiomInstCo ax ind cs) f m = m { km_axiom = km_axiom m |> xtNamed ax |>> xtInt ind |>> xtList (xtC env) cs f }
  461. xtC env (AppCo c1 c2) f m = m { km_app = km_app m |> xtC env c1 |>> xtC env c2 f }
  462. xtC env (TransCo c1 c2) f m = m { km_trans = km_trans m |> xtC env c1 |>> xtC env c2 f }
  463. xtC env (UnivCo r t1 t2) f m = m { km_univ = km_univ m |> xtR r |>> xtT env t1 |>> xtT env t2 f }
  464. xtC env (InstCo c t) f m = m { km_inst = km_inst m |> xtC env c |>> xtT env t f }
  465. xtC env (ForAllCo v c) f m = m { km_forall = km_forall m |> xtC (extendCME env v) c
  466. |>> xtBndr env v f }
  467. xtC env (CoVarCo v) f m = m { km_var = km_var m |> xtVar env v f }
  468. xtC env (SymCo c) f m = m { km_sym = km_sym m |> xtC env c f }
  469. xtC env (NthCo n c) f m = m { km_nth = km_nth m |> xtInt n |>> xtC env c f }
  470. xtC env (LRCo CLeft c) f m = m { km_left = km_left m |> xtC env c f }
  471. xtC env (LRCo CRight c) f m = m { km_right = km_right m |> xtC env c f }
  472. xtC env (SubCo c) f m = m { km_sub = km_sub m |> xtC env c f }
  473. fdC :: (a -> b -> b) -> CoercionMap a -> b -> b
  474. fdC _ EmptyKM = \z -> z
  475. fdC k m = foldTM (foldTM k) (km_refl m)
  476. . foldTM (foldTM (foldTM k)) (km_tc_app m)
  477. . foldTM (foldTM k) (km_app m)
  478. . foldTM (foldTM k) (km_forall m)
  479. . foldTM k (km_var m)
  480. . foldTM (foldTM (foldTM k)) (km_axiom m)
  481. . foldTM (foldTM (foldTM k)) (km_univ m)
  482. . foldTM k (km_sym m)
  483. . foldTM (foldTM k) (km_trans m)
  484. . foldTM (foldTM k) (km_nth m)
  485. . foldTM k (km_left m)
  486. . foldTM k (km_right m)
  487. . foldTM (foldTM k) (km_inst m)
  488. . foldTM k (km_sub m)
  489. \end{code}
  490. \begin{code}
  491. newtype RoleMap a = RM { unRM :: (IntMap.IntMap a) }
  492. instance TrieMap RoleMap where
  493. type Key RoleMap = Role
  494. emptyTM = RM emptyTM
  495. lookupTM = lkR
  496. alterTM = xtR
  497. foldTM = fdR
  498. mapTM = mapR
  499. lkR :: Role -> RoleMap a -> Maybe a
  500. lkR Nominal = lookupTM 1 . unRM
  501. lkR Representational = lookupTM 2 . unRM
  502. lkR Phantom = lookupTM 3 . unRM
  503. xtR :: Role -> XT a -> RoleMap a -> RoleMap a
  504. xtR Nominal f = RM . alterTM 1 f . unRM
  505. xtR Representational f = RM . alterTM 2 f . unRM
  506. xtR Phantom f = RM . alterTM 3 f . unRM
  507. fdR :: (a -> b -> b) -> RoleMap a -> b -> b
  508. fdR f (RM m) = foldTM f m
  509. mapR :: (a -> b) -> RoleMap a -> RoleMap b
  510. mapR f = RM . mapTM f . unRM
  511. \end{code}
  512. %************************************************************************
  513. %* *
  514. Types
  515. %* *
  516. %************************************************************************
  517. \begin{code}
  518. data TypeMap a
  519. = EmptyTM
  520. | TM { tm_var :: VarMap a
  521. , tm_app :: TypeMap (TypeMap a)
  522. , tm_fun :: TypeMap (TypeMap a)
  523. , tm_tc_app :: NameEnv (ListMap TypeMap a)
  524. , tm_forall :: TypeMap (BndrMap a)
  525. , tm_tylit :: TyLitMap a
  526. }
  527. instance Outputable a => Outputable (TypeMap a) where
  528. ppr m = text "TypeMap elts" <+> ppr (foldTypeMap (:) [] m)
  529. foldTypeMap :: (a -> b -> b) -> b -> TypeMap a -> b
  530. foldTypeMap k z m = fdT k m z
  531. emptyTypeMap :: TypeMap a
  532. emptyTypeMap = EmptyTM
  533. lookupTypeMap :: TypeMap a -> Type -> Maybe a
  534. lookupTypeMap cm t = lkT emptyCME t cm
  535. extendTypeMap :: TypeMap a -> Type -> a -> TypeMap a
  536. extendTypeMap m t v = xtT emptyCME t (\_ -> Just v) m
  537. wrapEmptyTypeMap :: TypeMap a
  538. wrapEmptyTypeMap = TM { tm_var = emptyTM
  539. , tm_app = EmptyTM
  540. , tm_fun = EmptyTM
  541. , tm_tc_app = emptyNameEnv
  542. , tm_forall = EmptyTM
  543. , tm_tylit = emptyTyLitMap }
  544. instance TrieMap TypeMap where
  545. type Key TypeMap = Type
  546. emptyTM = EmptyTM
  547. lookupTM = lkT emptyCME
  548. alterTM = xtT emptyCME
  549. foldTM = fdT
  550. mapTM = mapT
  551. mapT :: (a->b) -> TypeMap a -> TypeMap b
  552. mapT _ EmptyTM = EmptyTM
  553. mapT f (TM { tm_var = tvar, tm_app = tapp, tm_fun = tfun
  554. , tm_tc_app = ttcapp, tm_forall = tforall, tm_tylit = tlit })
  555. = TM { tm_var = mapTM f tvar
  556. , tm_app = mapTM (mapTM f) tapp
  557. , tm_fun = mapTM (mapTM f) tfun
  558. , tm_tc_app = mapNameEnv (mapTM f) ttcapp
  559. , tm_forall = mapTM (mapTM f) tforall
  560. , tm_tylit = mapTM f tlit }
  561. -----------------
  562. lkT :: CmEnv -> Type -> TypeMap a -> Maybe a
  563. lkT env ty m
  564. | EmptyTM <- m = Nothing
  565. | otherwise = go ty m
  566. where
  567. go ty | Just ty' <- coreView ty = go ty'
  568. go (TyVarTy v) = tm_var >.> lkVar env v
  569. go (AppTy t1 t2) = tm_app >.> lkT env t1 >=> lkT env t2
  570. go (FunTy t1 t2) = tm_fun >.> lkT env t1 >=> lkT env t2
  571. go (TyConApp tc tys) = tm_tc_app >.> lkNamed tc >=> lkList (lkT env) tys
  572. go (LitTy l) = tm_tylit >.> lkTyLit l
  573. go (ForAllTy tv ty) = tm_forall >.> lkT (extendCME env tv) ty >=> lkBndr env tv
  574. -----------------
  575. xtT :: CmEnv -> Type -> XT a -> TypeMap a -> TypeMap a
  576. xtT env ty f m
  577. | EmptyTM <- m = xtT env ty f wrapEmptyTypeMap
  578. | Just ty' <- coreView ty = xtT env ty' f m
  579. xtT env (TyVarTy v) f m = m { tm_var = tm_var m |> xtVar env v f }
  580. xtT env (AppTy t1 t2) f m = m { tm_app = tm_app m |> xtT env t1 |>> xtT env t2 f }
  581. xtT env (FunTy t1 t2) f m = m { tm_fun = tm_fun m |> xtT env t1 |>> xtT env t2 f }
  582. xtT env (ForAllTy tv ty) f m = m { tm_forall = tm_forall m |> xtT (extendCME env tv) ty
  583. |>> xtBndr env tv f }
  584. xtT env (TyConApp tc tys) f m = m { tm_tc_app = tm_tc_app m |> xtNamed tc
  585. |>> xtList (xtT env) tys f }
  586. xtT _ (LitTy l) f m = m { tm_tylit = tm_tylit m |> xtTyLit l f }
  587. fdT :: (a -> b -> b) -> TypeMap a -> b -> b
  588. fdT _ EmptyTM = \z -> z
  589. fdT k m = foldTM k (tm_var m)
  590. . foldTM (foldTM k) (tm_app m)
  591. . foldTM (foldTM k) (tm_fun m)
  592. . foldTM (foldTM k) (tm_tc_app m)
  593. . foldTM (foldTM k) (tm_forall m)
  594. . foldTyLit k (tm_tylit m)
  595. ------------------------
  596. data TyLitMap a = TLM { tlm_number :: Map.Map Integer a
  597. , tlm_string :: Map.Map FastString a
  598. }
  599. instance TrieMap TyLitMap where
  600. type Key TyLitMap = TyLit
  601. emptyTM = emptyTyLitMap
  602. lookupTM = lkTyLit
  603. alterTM = xtTyLit
  604. foldTM = foldTyLit
  605. mapTM = mapTyLit
  606. emptyTyLitMap :: TyLitMap a
  607. emptyTyLitMap = TLM { tlm_number = Map.empty, tlm_string = Map.empty }
  608. mapTyLit :: (a->b) -> TyLitMap a -> TyLitMap b
  609. mapTyLit f (TLM { tlm_number = tn, tlm_string = ts })
  610. = TLM { tlm_number = Map.map f tn, tlm_string = Map.map f ts }
  611. lkTyLit :: TyLit -> TyLitMap a -> Maybe a
  612. lkTyLit l =
  613. case l of
  614. NumTyLit n -> tlm_number >.> Map.lookup n
  615. StrTyLit n -> tlm_string >.> Map.lookup n
  616. xtTyLit :: TyLit -> XT a -> TyLitMap a -> TyLitMap a
  617. xtTyLit l f m =
  618. case l of
  619. NumTyLit n -> m { tlm_number = tlm_number m |> Map.alter f n }
  620. StrTyLit n -> m { tlm_string = tlm_string m |> Map.alter f n }
  621. foldTyLit :: (a -> b -> b) -> TyLitMap a -> b -> b
  622. foldTyLit l m = flip (Map.fold l) (tlm_string m)
  623. . flip (Map.fold l) (tlm_number m)
  624. \end{code}
  625. %************************************************************************
  626. %* *
  627. Variables
  628. %* *
  629. %************************************************************************
  630. \begin{code}
  631. type BoundVar = Int -- Bound variables are deBruijn numbered
  632. type BoundVarMap a = IntMap.IntMap a
  633. data CmEnv = CME { cme_next :: BoundVar
  634. , cme_env :: VarEnv BoundVar }
  635. emptyCME :: CmEnv
  636. emptyCME = CME { cme_next = 0, cme_env = emptyVarEnv }
  637. extendCME :: CmEnv -> Var -> CmEnv
  638. extendCME (CME { cme_next = bv, cme_env = env }) v
  639. = CME { cme_next = bv+1, cme_env = extendVarEnv env v bv }
  640. extendCMEs :: CmEnv -> [Var] -> CmEnv
  641. extendCMEs env vs = foldl extendCME env vs
  642. lookupCME :: CmEnv -> Var -> Maybe BoundVar
  643. lookupCME (CME { cme_env = env }) v = lookupVarEnv env v
  644. --------- Variable binders -------------
  645. type BndrMap = TypeMap
  646. lkBndr :: CmEnv -> Var -> BndrMap a -> Maybe a
  647. lkBndr env v m = lkT env (varType v) m
  648. xtBndr :: CmEnv -> Var -> XT a -> BndrMap a -> BndrMap a
  649. xtBndr env v f = xtT env (varType v) f
  650. --------- Variable occurrence -------------
  651. data VarMap a = VM { vm_bvar :: BoundVarMap a -- Bound variable
  652. , vm_fvar :: VarEnv a } -- Free variable
  653. instance TrieMap VarMap where
  654. type Key VarMap = Var
  655. emptyTM = VM { vm_bvar = IntMap.empty, vm_fvar = emptyVarEnv }
  656. lookupTM = lkVar emptyCME
  657. alterTM = xtVar emptyCME
  658. foldTM = fdVar
  659. mapTM = mapVar
  660. mapVar :: (a->b) -> VarMap a -> VarMap b
  661. mapVar f (VM { vm_bvar = bv, vm_fvar = fv })
  662. = VM { vm_bvar = mapTM f bv, vm_fvar = mapVarEnv f fv }
  663. lkVar :: CmEnv -> Var -> VarMap a -> Maybe a
  664. lkVar env v
  665. | Just bv <- lookupCME env v = vm_bvar >.> lookupTM bv
  666. | otherwise = vm_fvar >.> lkFreeVar v
  667. xtVar :: CmEnv -> Var -> XT a -> VarMap a -> VarMap a
  668. xtVar env v f m
  669. | Just bv <- lookupCME env v = m { vm_bvar = vm_bvar m |> xtInt bv f }
  670. | otherwise = m { vm_fvar = vm_fvar m |> xtFreeVar v f }
  671. fdVar :: (a -> b -> b) -> VarMap a -> b -> b
  672. fdVar k m = foldTM k (vm_bvar m)
  673. . foldTM k (vm_fvar m)
  674. lkFreeVar :: Var -> VarEnv a -> Maybe a
  675. lkFreeVar var env = lookupVarEnv env var
  676. xtFreeVar :: Var -> XT a -> VarEnv a -> VarEnv a
  677. xtFreeVar v f m = alterVarEnv f m v
  678. \end{code}