@@ -5,6 +5,7 @@ module Agda2Lambox.Compile.Type
5
5
) where
6
6
7
7
8
+ import Control.Monad.Reader
8
9
import Control.Monad ( mapM )
9
10
import Data.List ( foldl' )
10
11
import Data.Function ( (&) )
@@ -18,27 +19,80 @@ import qualified LambdaBox as LBox
18
19
import Agda2Lambox.Compile.Utils ( qnameToKName )
19
20
import Agda2Lambox.Compile.Monad
20
21
22
+ -- NOTE(flupe):
23
+ -- strategy for type compilation (for future me)
24
+ -- like for terms, we need to keep track of bound variables.
25
+ -- In particular, in λ□ type syntax, variables refer to type variables, using DeBruijn *levels*.
26
+ -- So, when compiling var k,
27
+ -- we should check that if k is below the amount of locally bound bars.
28
+ -- If such => tBox.
29
+ -- otherwise, it HAS to point to a type variable, and we
30
+ --
21
31
22
- compileType :: Type -> TCM LBox. Type
23
- compileType = compileType' . unEl
32
+ -- | λ□ type compilation environment.
33
+ data CompileEnv = CompileEnv
34
+ { typeVars :: Int
35
+ -- ^ Type variables, bound outside of the type.
36
+ , boundVars :: Int
37
+ -- ^ Amount of locally-bound variables.
38
+ }
24
39
40
+ initEnv :: Int -> CompileEnv
41
+ initEnv tvs = CompileEnv
42
+ { typeVars = tvs
43
+ , boundVars = 0
44
+ }
45
+
46
+ runC :: Int -> C a -> CompileM a
47
+ runC tvs m = runReaderT m (initEnv tvs)
48
+
49
+ -- | Increment the number of locally-bound variables.
50
+ underBinder :: C a -> C a
51
+ underBinder = local \ e -> e { boundVars = boundVars e + 1 }
52
+
53
+ -- | Compilation monad.
54
+ type C a = ReaderT CompileEnv CompileM a
55
+
56
+
57
+ compileTopLevelType :: Type -> CompileM (LBox. Type )
58
+ compileTopLevelType = undefined
59
+
60
+ -- | Compile a type, given a number of type variables in scope.
61
+ compileType :: Type -> CompileM LBox. Type
62
+ compileType = runC 0 . compileType'
63
+
64
+ compileType' :: Type -> C LBox. Type
65
+ compileType' = compileType'' . unEl
66
+
67
+ compileType'' :: Term -> C LBox. Type
68
+ compileType'' = \ case
69
+ Var n es -> do
70
+ CompileEnv {.. } <- ask
71
+ if n < boundVars then
72
+ pure LBox. TBox -- NOTE(flupe): should we still apply the parameters to the box?
73
+ else do
74
+ let k = typeVars - (n - boundVars)
75
+ -- NOTE(flupe): reading the paper, type variables are restricted to Hindley-Milner
76
+ -- so cannot be type constructors: we don't compile elims
77
+ pure $ LBox. TVar k
78
+ -- foldl' LBox.TApp (LBox.TVar k) <$> compileElims es
25
79
26
- compileType' :: Term -> TCM LBox. Type
27
- compileType' = \ case
28
- Var n es -> foldl' LBox. TApp (LBox. TVar n) <$> compileElims es
29
80
Def q es -> do
30
- -- TODO(flupe): check if it's an inductive
81
+ -- TODO(flupe): check if it's an inductive, or a type alias
31
82
foldl' LBox. TApp (LBox. TConst $ qnameToKName q) <$> compileElims es
32
83
Pi dom abs ->
33
- LBox. TArr <$> compileType (unDom dom)
34
- <*> compileType (unAbs abs )
84
+ LBox. TArr <$> compileType' (unDom dom)
85
+ <*> underBinder ( compileType' (unAbs abs ) )
35
86
36
- Lit {} -> genericError " type-level literals not supported."
37
- Lam {} -> genericError " type-level abstractions not supported."
38
- Con {} -> genericError " type-level constructors not supported."
39
- Sort {} -> pure LBox. TBox
40
- Level {} -> pure LBox. TBox
41
- t -> genericError $ " unsupported type: " <> prettyShow t
87
+ -- NOTE(flupe):
88
+ -- My current understanding of typed lambox is that the type translation
89
+ t -> pure LBox. TBox
90
+
91
+ compileElims :: Elims -> C [LBox. Type ]
92
+ compileElims = mapM \ case
93
+ Apply a -> compileType'' $ unArg a
94
+ Proj {} -> genericError " type-level projection elim not supported."
95
+ IApply {} -> genericError " type-level cubical path application not supported."
42
96
43
97
-- See: https://github.com/MetaCoq/metacoq/blob/coq-8.20/erasure/theories/Typed/Erasure.v#L780-L817
44
98
-- | Compile a telescope (of parameters) into a list of λ□ type variables.
@@ -57,12 +111,7 @@ compileTele tel =
57
111
, tvarIsArity = False
58
112
-- ^ type t is an arity if it is "an n-ary dependent function ending with a sort"
59
113
, tvarIsSort = False
60
- -- ^ t : Prop?
114
+ -- ^ if the type of the parameter ends in a sort.
115
+ -- say, @(T : Type)@ or @(T : nat -> Type)@ or @(T : Type -> Type)@.
61
116
}
62
117
63
-
64
- compileElims :: Elims -> TCM [LBox. Type ]
65
- compileElims = mapM \ case
66
- Apply a -> compileType' $ unArg a
67
- Proj {} -> genericError " type-level projection elim not supported."
68
- IApply {} -> genericError " type-level cubical path application not supported."
0 commit comments