PageRenderTime 56ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/compiler/coreSyn/TrieMap.lhs

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