Environment.hs (1973B)
1 module PlUtils.Environment ( 2 Environment, 3 empty, 4 depth, 5 bind, 6 assign, 7 lookup, 8 define, 9 eval, 10 ) where 11 12 import Data.Maybe (fromMaybe) 13 import Naturals.NatMap (NatMap) 14 import Naturals.NatMap qualified as NatMap 15 import Prelude hiding (lookup) 16 17 import PlUtils.DeBruijn 18 19 -- | A collection of free variables and a substitution on them, intended for 20 -- evaluation with semantic variables represented as de Bruijn levels (which are 21 -- stable under weakening, so we don't need to modify the environment when 22 -- descending under a binder) and with syntactic variables represented as 23 -- de Bruijn indices. 24 data Environment v = Environment Depth (NatMap v) deriving (Show) 25 26 empty :: Environment v 27 empty = Environment (Depth 0) NatMap.empty 28 29 depth :: Environment v -> Depth 30 depth (Environment d _) = d 31 32 -- | Bind a new variable (without introducing a substitution for it). 33 bind :: Environment v -> (Level, Environment v) 34 bind (Environment d s) = 35 let (l, d') = descend d 36 in (l, Environment d' s) 37 38 weaken :: Environment v -> Environment v 39 weaken = snd . bind 40 41 -- | Assign a value to an existing variable. 42 assign :: Level -> v -> Environment v -> Environment v 43 assign l v (Environment d s) = assertLvlInBounds d l $ Environment d (NatMap.insert (unLevel l) v s) 44 45 -- | Lookup the substitution for a variable. 46 lookup :: Level -> Environment v -> Maybe v 47 lookup l (Environment d s) = assertLvlInBounds d l $ NatMap.lookup (unLevel l) s 48 49 -- | Bind and a new variable and assign a value to it. 50 define :: (Level -> v) -> Environment v -> Environment v 51 define makeVal env = 52 let (l, env') = bind env 53 in assign l (makeVal l) env' 54 55 -- | Evaluate an index in an environment, falling back to making a value with 56 -- the given function in case the environment doesn't have a substitution for 57 -- the index. 58 eval :: (Level -> v) -> Index -> Environment v -> v 59 eval makeVal i env = 60 let l = idxToLvl (depth env) i 61 in fromMaybe (makeVal l) $ lookup l env