DeBruijn.hs (2970B)
1 module PlUtils.DeBruijn ( 2 Depth (..), 3 Index (..), 4 Level (..), 5 descend, 6 idxInBounds, 7 lvlInBounds, 8 assertIdxInBounds, 9 assertLvlInBounds, 10 idxToLvl, 11 lvlToIdx, 12 ) where 13 14 import Naturals.Nat 15 16 import PlUtils.Util 17 18 -------------------------------------------------------------------------------- 19 -- Indices and levels 20 21 -- | A @Nat@ representing the number of free variables in some context. 22 newtype Depth = Depth {unDepth :: Nat} deriving (Show, Eq) 23 24 -- | A de Bruijn index represented as a @Nat@, that is, an index into a context 25 -- "from the right", such that the innermost free variable gets index 0. 26 newtype Index = Index {unIndex :: Nat} deriving (Show, Eq) 27 28 -- | A de Bruijn level represented as a @Nat@, that is, an index into a context 29 -- "from the left", such that the outermost free variable gets index 0. 30 newtype Level = Level {unLevel :: Nat} deriving (Show, Eq) 31 32 descend :: Depth -> (Level, Depth) 33 descend (Depth d) = assert (d < maxBound) "PlUtils: depth overflow" (Level d, Depth (d + 1)) 34 35 idxInBounds :: Depth -> Index -> Bool 36 idxInBounds (Depth d) (Index i) = i < d 37 38 lvlInBounds :: Depth -> Level -> Bool 39 lvlInBounds (Depth d) (Level l) = l < d 40 41 assertIdxInBounds :: Depth -> Index -> a -> a 42 assertIdxInBounds d i = assert (idxInBounds d i) "PlUtils: index out of bounds" 43 44 assertLvlInBounds :: Depth -> Level -> a -> a 45 assertLvlInBounds d l = assert (lvlInBounds d l) "PlUtils: level out of bounds" 46 47 idxToLvl :: Depth -> Index -> Level 48 idxToLvl d i = assertIdxInBounds d i $ Level (unDepth d - unIndex i - 1) 49 50 lvlToIdx :: Depth -> Level -> Index 51 lvlToIdx d l = assertLvlInBounds d l $ Index (unDepth d - unLevel l - 1) 52 53 -------------------------------------------------------------------------------- 54 -- TODO 55 56 {- 57 Data structures required for elaboration of surface (shadowing names) to 58 core (de Bruijn indices): 59 60 ULC (standard): 61 Depth: `Nat` (Peano-indexed?) 62 VarMap: `ShadowMap Name Level` OR `ShadowMap Name Value` 63 The latter provides a convenient way to implement predeclared names. 64 STLC (no type variables): 65 Depth: `Nat` 66 DVarMap: `ShadowMap DName (DLevel, Type)` OR `ShadowMap DName (DValue, Type)` 67 STLC/PLC (type variables but no higher kinds): 68 Depth: `Nat` 69 DVarMap: `ShadowMap DName (DLevel, Type)` OR `ShadowMap DName (DValue, Type)` 70 SVarMap: `ShadowMap SName SLevel` OR `ShadowMap SName SValue` 71 STLC/HOPLC (type variables and higher kinds): 72 Depth: `Nat` 73 DVarMap: `ShadowMap DName (DLevel, Type)` OR `ShadowMap DName (DValue, Type)` 74 SVarMap: `ShadowMap SName (SLevel, Kind)` OR `ShadowMap SName (SValue, Kind)` 75 -} 76 77 {- 78 TODO: Do same thing but with evaluation. 79 TODO: Do we need to carry a substitution on static variables during elaboration? 80 This is what I've done in the past, but I don't think it's necessary. At times 81 when we need to evaluate during elaboration, we can just convert the elaboration 82 context to an evaluation environment with an empty substitution. 83 -}