/compiler/Eta/Core/TrieMap.hs

https://github.com/typelead/eta · Haskell · 839 lines · 585 code · 123 blank · 131 comment · 6 complexity · a2f433a1a5e486ce40d19798ed25c690 MD5 · raw file

  1. {-
  2. (c) The University of Glasgow 2006
  3. (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
  4. -}
  5. {-# LANGUAGE RankNTypes, TypeFamilies #-}
  6. module Eta.Core.TrieMap(
  7. CoreMap, emptyCoreMap, extendCoreMap, lookupCoreMap, foldCoreMap,
  8. TypeMap, emptyTypeMap, extendTypeMap, lookupTypeMap, foldTypeMap,
  9. CoercionMap,
  10. MaybeMap,
  11. ListMap,
  12. TrieMap(..), insertTM, deleteTM,
  13. lookupTypeMapTyCon
  14. ) where
  15. import Eta.Core.CoreSyn
  16. import Eta.Types.Coercion
  17. import Eta.BasicTypes.Literal
  18. import Eta.BasicTypes.Name
  19. import Eta.Types.Type
  20. import Eta.Types.TypeRep
  21. import Eta.Types.TyCon(TyCon)
  22. import Eta.BasicTypes.Var
  23. import Eta.Utils.UniqFM
  24. import Eta.BasicTypes.Unique( Unique )
  25. import Eta.Utils.FastString(FastString)
  26. import Eta.Types.CoAxiom(CoAxiomRule(coaxrName))
  27. import qualified Data.Map as Map
  28. import qualified Data.IntMap as IntMap
  29. import Eta.BasicTypes.VarEnv
  30. import Eta.BasicTypes.NameEnv
  31. import Eta.Utils.Outputable
  32. import Control.Monad( (>=>) )
  33. {-
  34. This module implements TrieMaps, which are finite mappings
  35. whose key is a structured value like a CoreExpr or Type.
  36. The code is very regular and boilerplate-like, but there is
  37. some neat handling of *binders*. In effect they are deBruijn
  38. numbered on the fly.
  39. ************************************************************************
  40. * *
  41. The TrieMap class
  42. * *
  43. ************************************************************************
  44. -}
  45. type XT a = Maybe a -> Maybe a -- How to alter a non-existent elt (Nothing)
  46. -- or an existing elt (Just)
  47. class TrieMap m where
  48. type Key m :: *
  49. emptyTM :: m a
  50. lookupTM :: forall b. Key m -> m b -> Maybe b
  51. alterTM :: forall b. Key m -> XT b -> m b -> m b
  52. mapTM :: (a->b) -> m a -> m b
  53. foldTM :: (a -> b -> b) -> m a -> b -> b
  54. -- The unusual argument order here makes
  55. -- it easy to compose calls to foldTM;
  56. -- see for example fdE below
  57. insertTM :: TrieMap m => Key m -> a -> m a -> m a
  58. insertTM k v m = alterTM k (\_ -> Just v) m
  59. deleteTM :: TrieMap m => Key m -> m a -> m a
  60. deleteTM k m = alterTM k (\_ -> Nothing) m
  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. {-
  81. ************************************************************************
  82. * *
  83. IntMaps
  84. * *
  85. ************************************************************************
  86. -}
  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.foldr 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.foldr 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. {-
  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. -}
  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. {-
  171. ************************************************************************
  172. * *
  173. Basic maps
  174. * *
  175. ************************************************************************
  176. -}
  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. {-
  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. -}
  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. {-
  379. ************************************************************************
  380. * *
  381. Coercions
  382. * *
  383. ************************************************************************
  384. -}
  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. , km_axiom_rule :: Map.Map FastString
  402. (ListMap TypeMap (ListMap CoercionMap a))
  403. }
  404. wrapEmptyKM :: CoercionMap a
  405. wrapEmptyKM = KM { km_refl = emptyTM, km_tc_app = emptyTM
  406. , km_app = emptyTM, km_forall = emptyTM
  407. , km_var = emptyTM, km_axiom = emptyNameEnv
  408. , km_univ = emptyTM, km_sym = emptyTM, km_trans = emptyTM
  409. , km_nth = emptyTM, km_left = emptyTM, km_right = emptyTM
  410. , km_inst = emptyTM, km_sub = emptyTM
  411. , km_axiom_rule = emptyTM }
  412. instance TrieMap CoercionMap where
  413. type Key CoercionMap = Coercion
  414. emptyTM = EmptyKM
  415. lookupTM = lkC emptyCME
  416. alterTM = xtC emptyCME
  417. foldTM = fdC
  418. mapTM = mapC
  419. mapC :: (a->b) -> CoercionMap a -> CoercionMap b
  420. mapC _ EmptyKM = EmptyKM
  421. mapC f (KM { km_refl = krefl, km_tc_app = ktc
  422. , km_app = kapp, km_forall = kforall
  423. , km_var = kvar, km_axiom = kax
  424. , km_univ = kuniv , km_sym = ksym, km_trans = ktrans
  425. , km_nth = knth, km_left = kml, km_right = kmr
  426. , km_inst = kinst, km_sub = ksub
  427. , km_axiom_rule = kaxr })
  428. = KM { km_refl = mapTM (mapTM f) krefl
  429. , km_tc_app = mapTM (mapNameEnv (mapTM f)) ktc
  430. , km_app = mapTM (mapTM f) kapp
  431. , km_forall = mapTM (mapTM f) kforall
  432. , km_var = mapTM f kvar
  433. , km_axiom = mapNameEnv (IntMap.map (mapTM f)) kax
  434. , km_univ = mapTM (mapTM (mapTM f)) kuniv
  435. , km_sym = mapTM f ksym
  436. , km_trans = mapTM (mapTM f) ktrans
  437. , km_nth = IntMap.map (mapTM f) knth
  438. , km_left = mapTM f kml
  439. , km_right = mapTM f kmr
  440. , km_inst = mapTM (mapTM f) kinst
  441. , km_sub = mapTM f ksub
  442. , km_axiom_rule = mapTM (mapTM (mapTM f)) kaxr
  443. }
  444. lkC :: CmEnv -> Coercion -> CoercionMap a -> Maybe a
  445. lkC env co m
  446. | EmptyKM <- m = Nothing
  447. | otherwise = go co m
  448. where
  449. go (Refl r ty) = km_refl >.> lookupTM r >=> lkT env ty
  450. go (TyConAppCo r tc cs) = km_tc_app >.> lookupTM r >=> lkNamed tc >=> lkList (lkC env) cs
  451. go (AxiomInstCo ax ind cs) = km_axiom >.> lkNamed ax >=> lookupTM ind >=> lkList (lkC env) cs
  452. go (AppCo c1 c2) = km_app >.> lkC env c1 >=> lkC env c2
  453. go (TransCo c1 c2) = km_trans >.> lkC env c1 >=> lkC env c2
  454. -- the provenance is not used in the map
  455. go (UnivCo _ r t1 t2) = km_univ >.> lookupTM r >=> lkT env t1 >=> lkT env t2
  456. go (InstCo c t) = km_inst >.> lkC env c >=> lkT env t
  457. go (ForAllCo v c) = km_forall >.> lkC (extendCME env v) c >=> lkBndr env v
  458. go (CoVarCo v) = km_var >.> lkVar env v
  459. go (SymCo c) = km_sym >.> lkC env c
  460. go (NthCo n c) = km_nth >.> lookupTM n >=> lkC env c
  461. go (LRCo CLeft c) = km_left >.> lkC env c
  462. go (LRCo CRight c) = km_right >.> lkC env c
  463. go (SubCo c) = km_sub >.> lkC env c
  464. go (AxiomRuleCo co ts cs) = km_axiom_rule >.>
  465. lookupTM (coaxrName co) >=>
  466. lkList (lkT env) ts >=>
  467. lkList (lkC env) cs
  468. xtC :: CmEnv -> Coercion -> XT a -> CoercionMap a -> CoercionMap a
  469. xtC env co f EmptyKM = xtC env co f wrapEmptyKM
  470. xtC env (Refl r ty) f m = m { km_refl = km_refl m |> xtR r |>> xtT env ty f }
  471. 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 }
  472. xtC env (AxiomInstCo ax ind cs) f m = m { km_axiom = km_axiom m |> xtNamed ax |>> xtInt ind |>> xtList (xtC env) cs f }
  473. xtC env (AppCo c1 c2) f m = m { km_app = km_app m |> xtC env c1 |>> xtC env c2 f }
  474. xtC env (TransCo c1 c2) f m = m { km_trans = km_trans m |> xtC env c1 |>> xtC env c2 f }
  475. -- the provenance is not used in the map
  476. xtC env (UnivCo _ r t1 t2) f m = m { km_univ = km_univ m |> xtR r |>> xtT env t1 |>> xtT env t2 f }
  477. xtC env (InstCo c t) f m = m { km_inst = km_inst m |> xtC env c |>> xtT env t f }
  478. xtC env (ForAllCo v c) f m = m { km_forall = km_forall m |> xtC (extendCME env v) c
  479. |>> xtBndr env v f }
  480. xtC env (CoVarCo v) f m = m { km_var = km_var m |> xtVar env v f }
  481. xtC env (SymCo c) f m = m { km_sym = km_sym m |> xtC env c f }
  482. xtC env (NthCo n c) f m = m { km_nth = km_nth m |> xtInt n |>> xtC env c f }
  483. xtC env (LRCo CLeft c) f m = m { km_left = km_left m |> xtC env c f }
  484. xtC env (LRCo CRight c) f m = m { km_right = km_right m |> xtC env c f }
  485. xtC env (SubCo c) f m = m { km_sub = km_sub m |> xtC env c f }
  486. xtC env (AxiomRuleCo co ts cs) f m = m { km_axiom_rule = km_axiom_rule m
  487. |> alterTM (coaxrName co)
  488. |>> xtList (xtT env) ts
  489. |>> xtList (xtC env) cs f}
  490. fdC :: (a -> b -> b) -> CoercionMap a -> b -> b
  491. fdC _ EmptyKM = \z -> z
  492. fdC k m = foldTM (foldTM k) (km_refl m)
  493. . foldTM (foldTM (foldTM k)) (km_tc_app m)
  494. . foldTM (foldTM k) (km_app m)
  495. . foldTM (foldTM k) (km_forall m)
  496. . foldTM k (km_var m)
  497. . foldTM (foldTM (foldTM k)) (km_axiom m)
  498. . foldTM (foldTM (foldTM k)) (km_univ m)
  499. . foldTM k (km_sym m)
  500. . foldTM (foldTM k) (km_trans m)
  501. . foldTM (foldTM k) (km_nth m)
  502. . foldTM k (km_left m)
  503. . foldTM k (km_right m)
  504. . foldTM (foldTM k) (km_inst m)
  505. . foldTM k (km_sub m)
  506. . foldTM (foldTM (foldTM k)) (km_axiom_rule m)
  507. newtype RoleMap a = RM { unRM :: (IntMap.IntMap a) }
  508. instance TrieMap RoleMap where
  509. type Key RoleMap = Role
  510. emptyTM = RM emptyTM
  511. lookupTM = lkR
  512. alterTM = xtR
  513. foldTM = fdR
  514. mapTM = mapR
  515. lkR :: Role -> RoleMap a -> Maybe a
  516. lkR Nominal = lookupTM 1 . unRM
  517. lkR Representational = lookupTM 2 . unRM
  518. lkR Phantom = lookupTM 3 . unRM
  519. xtR :: Role -> XT a -> RoleMap a -> RoleMap a
  520. xtR Nominal f = RM . alterTM 1 f . unRM
  521. xtR Representational f = RM . alterTM 2 f . unRM
  522. xtR Phantom f = RM . alterTM 3 f . unRM
  523. fdR :: (a -> b -> b) -> RoleMap a -> b -> b
  524. fdR f (RM m) = foldTM f m
  525. mapR :: (a -> b) -> RoleMap a -> RoleMap b
  526. mapR f = RM . mapTM f . unRM
  527. {-
  528. ************************************************************************
  529. * *
  530. Types
  531. * *
  532. ************************************************************************
  533. -}
  534. data TypeMap a
  535. = EmptyTM
  536. | TM { tm_var :: VarMap a
  537. , tm_app :: TypeMap (TypeMap a)
  538. , tm_fun :: TypeMap (TypeMap a)
  539. , tm_tc_app :: NameEnv (ListMap TypeMap a)
  540. , tm_forall :: TypeMap (BndrMap a)
  541. , tm_tylit :: TyLitMap a
  542. }
  543. instance Outputable a => Outputable (TypeMap a) where
  544. ppr m = text "TypeMap elts" <+> ppr (foldTypeMap (:) [] m)
  545. foldTypeMap :: (a -> b -> b) -> b -> TypeMap a -> b
  546. foldTypeMap k z m = fdT k m z
  547. emptyTypeMap :: TypeMap a
  548. emptyTypeMap = EmptyTM
  549. lookupTypeMap :: TypeMap a -> Type -> Maybe a
  550. lookupTypeMap cm t = lkT emptyCME t cm
  551. -- Returns the type map entries that have keys starting with the given tycon.
  552. -- This only considers saturated applications (i.e. TyConApp ones).
  553. lookupTypeMapTyCon :: TypeMap a -> TyCon -> [a]
  554. lookupTypeMapTyCon EmptyTM _ = []
  555. lookupTypeMapTyCon TM { tm_tc_app = cs } tc =
  556. case lookupUFM cs tc of
  557. Nothing -> []
  558. Just xs -> foldTM (:) xs []
  559. extendTypeMap :: TypeMap a -> Type -> a -> TypeMap a
  560. extendTypeMap m t v = xtT emptyCME t (\_ -> Just v) m
  561. wrapEmptyTypeMap :: TypeMap a
  562. wrapEmptyTypeMap = TM { tm_var = emptyTM
  563. , tm_app = EmptyTM
  564. , tm_fun = EmptyTM
  565. , tm_tc_app = emptyNameEnv
  566. , tm_forall = EmptyTM
  567. , tm_tylit = emptyTyLitMap }
  568. instance TrieMap TypeMap where
  569. type Key TypeMap = Type
  570. emptyTM = EmptyTM
  571. lookupTM = lkT emptyCME
  572. alterTM = xtT emptyCME
  573. foldTM = fdT
  574. mapTM = mapT
  575. mapT :: (a->b) -> TypeMap a -> TypeMap b
  576. mapT _ EmptyTM = EmptyTM
  577. mapT f (TM { tm_var = tvar, tm_app = tapp, tm_fun = tfun
  578. , tm_tc_app = ttcapp, tm_forall = tforall, tm_tylit = tlit })
  579. = TM { tm_var = mapTM f tvar
  580. , tm_app = mapTM (mapTM f) tapp
  581. , tm_fun = mapTM (mapTM f) tfun
  582. , tm_tc_app = mapNameEnv (mapTM f) ttcapp
  583. , tm_forall = mapTM (mapTM f) tforall
  584. , tm_tylit = mapTM f tlit }
  585. -----------------
  586. lkT :: CmEnv -> Type -> TypeMap a -> Maybe a
  587. lkT env ty m
  588. | EmptyTM <- m = Nothing
  589. | otherwise = go ty m
  590. where
  591. go ty | Just ty' <- coreView ty = go ty'
  592. go (TyVarTy v) = tm_var >.> lkVar env v
  593. go (AppTy t1 t2) = tm_app >.> lkT env t1 >=> lkT env t2
  594. go (FunTy t1 t2) = tm_fun >.> lkT env t1 >=> lkT env t2
  595. go (TyConApp tc tys) = tm_tc_app >.> lkNamed tc >=> lkList (lkT env) tys
  596. go (LitTy l) = tm_tylit >.> lkTyLit l
  597. go (ForAllTy tv ty) = tm_forall >.> lkT (extendCME env tv) ty >=> lkBndr env tv
  598. -----------------
  599. xtT :: CmEnv -> Type -> XT a -> TypeMap a -> TypeMap a
  600. xtT env ty f m
  601. | EmptyTM <- m = xtT env ty f wrapEmptyTypeMap
  602. | Just ty' <- coreView ty = xtT env ty' f m
  603. xtT env (TyVarTy v) f m = m { tm_var = tm_var m |> xtVar env v f }
  604. xtT env (AppTy t1 t2) f m = m { tm_app = tm_app m |> xtT env t1 |>> xtT env t2 f }
  605. xtT env (FunTy t1 t2) f m = m { tm_fun = tm_fun m |> xtT env t1 |>> xtT env t2 f }
  606. xtT env (ForAllTy tv ty) f m = m { tm_forall = tm_forall m |> xtT (extendCME env tv) ty
  607. |>> xtBndr env tv f }
  608. xtT env (TyConApp tc tys) f m = m { tm_tc_app = tm_tc_app m |> xtNamed tc
  609. |>> xtList (xtT env) tys f }
  610. xtT _ (LitTy l) f m = m { tm_tylit = tm_tylit m |> xtTyLit l f }
  611. fdT :: (a -> b -> b) -> TypeMap a -> b -> b
  612. fdT _ EmptyTM = \z -> z
  613. fdT k m = foldTM k (tm_var m)
  614. . foldTM (foldTM k) (tm_app m)
  615. . foldTM (foldTM k) (tm_fun m)
  616. . foldTM (foldTM k) (tm_tc_app m)
  617. . foldTM (foldTM k) (tm_forall m)
  618. . foldTyLit k (tm_tylit m)
  619. ------------------------
  620. data TyLitMap a = TLM { tlm_number :: Map.Map Integer a
  621. , tlm_string :: Map.Map FastString a
  622. }
  623. instance TrieMap TyLitMap where
  624. type Key TyLitMap = TyLit
  625. emptyTM = emptyTyLitMap
  626. lookupTM = lkTyLit
  627. alterTM = xtTyLit
  628. foldTM = foldTyLit
  629. mapTM = mapTyLit
  630. emptyTyLitMap :: TyLitMap a
  631. emptyTyLitMap = TLM { tlm_number = Map.empty, tlm_string = Map.empty }
  632. mapTyLit :: (a->b) -> TyLitMap a -> TyLitMap b
  633. mapTyLit f (TLM { tlm_number = tn, tlm_string = ts })
  634. = TLM { tlm_number = Map.map f tn, tlm_string = Map.map f ts }
  635. lkTyLit :: TyLit -> TyLitMap a -> Maybe a
  636. lkTyLit l =
  637. case l of
  638. NumTyLit n -> tlm_number >.> Map.lookup n
  639. StrTyLit n -> tlm_string >.> Map.lookup n
  640. xtTyLit :: TyLit -> XT a -> TyLitMap a -> TyLitMap a
  641. xtTyLit l f m =
  642. case l of
  643. NumTyLit n -> m { tlm_number = tlm_number m |> Map.alter f n }
  644. StrTyLit n -> m { tlm_string = tlm_string m |> Map.alter f n }
  645. foldTyLit :: (a -> b -> b) -> TyLitMap a -> b -> b
  646. foldTyLit l m = flip (Map.foldr l) (tlm_string m)
  647. . flip (Map.foldr l) (tlm_number m)
  648. {-
  649. ************************************************************************
  650. * *
  651. Variables
  652. * *
  653. ************************************************************************
  654. -}
  655. type BoundVar = Int -- Bound variables are deBruijn numbered
  656. type BoundVarMap a = IntMap.IntMap a
  657. data CmEnv = CME { cme_next :: BoundVar
  658. , cme_env :: VarEnv BoundVar }
  659. emptyCME :: CmEnv
  660. emptyCME = CME { cme_next = 0, cme_env = emptyVarEnv }
  661. extendCME :: CmEnv -> Var -> CmEnv
  662. extendCME (CME { cme_next = bv, cme_env = env }) v
  663. = CME { cme_next = bv+1, cme_env = extendVarEnv env v bv }
  664. extendCMEs :: CmEnv -> [Var] -> CmEnv
  665. extendCMEs env vs = foldl extendCME env vs
  666. lookupCME :: CmEnv -> Var -> Maybe BoundVar
  667. lookupCME (CME { cme_env = env }) v = lookupVarEnv env v
  668. --------- Variable binders -------------
  669. -- | A 'BndrMap' is a 'TypeMap' which allows us to distinguish between
  670. -- binding forms whose binders have different types. For example,
  671. -- if we are doing a 'TrieMap' lookup on @\(x :: Int) -> ()@, we should
  672. -- not pick up an entry in the 'TrieMap' for @\(x :: Bool) -> ()@:
  673. -- we can disambiguate this by matching on the type (or kind, if this
  674. -- a binder in a type) of the binder.
  675. type BndrMap = TypeMap
  676. lkBndr :: CmEnv -> Var -> BndrMap a -> Maybe a
  677. lkBndr env v m = lkT env (varType v) m
  678. xtBndr :: CmEnv -> Var -> XT a -> BndrMap a -> BndrMap a
  679. xtBndr env v f = xtT env (varType v) f
  680. --------- Variable occurrence -------------
  681. data VarMap a = VM { vm_bvar :: BoundVarMap a -- Bound variable
  682. , vm_fvar :: VarEnv a } -- Free variable
  683. instance TrieMap VarMap where
  684. type Key VarMap = Var
  685. emptyTM = VM { vm_bvar = IntMap.empty, vm_fvar = emptyVarEnv }
  686. lookupTM = lkVar emptyCME
  687. alterTM = xtVar emptyCME
  688. foldTM = fdVar
  689. mapTM = mapVar
  690. mapVar :: (a->b) -> VarMap a -> VarMap b
  691. mapVar f (VM { vm_bvar = bv, vm_fvar = fv })
  692. = VM { vm_bvar = mapTM f bv, vm_fvar = mapVarEnv f fv }
  693. lkVar :: CmEnv -> Var -> VarMap a -> Maybe a
  694. lkVar env v
  695. | Just bv <- lookupCME env v = vm_bvar >.> lookupTM bv
  696. | otherwise = vm_fvar >.> lkFreeVar v
  697. xtVar :: CmEnv -> Var -> XT a -> VarMap a -> VarMap a
  698. xtVar env v f m
  699. | Just bv <- lookupCME env v = m { vm_bvar = vm_bvar m |> xtInt bv f }
  700. | otherwise = m { vm_fvar = vm_fvar m |> xtFreeVar v f }
  701. fdVar :: (a -> b -> b) -> VarMap a -> b -> b
  702. fdVar k m = foldTM k (vm_bvar m)
  703. . foldTM k (vm_fvar m)
  704. lkFreeVar :: Var -> VarEnv a -> Maybe a
  705. lkFreeVar var env = lookupVarEnv env var
  706. xtFreeVar :: Var -> XT a -> VarEnv a -> VarEnv a
  707. xtFreeVar v f m = alterVarEnv f m v