4 | module Data.Telescope.Telescope
13 | plusAcc : Nat -> Nat -> Nat
15 | plusAcc (S m) n = plusAcc m (S n)
18 | plusAccIsPlus : (m, n : Nat) -> (m + n) === plusAcc m n
19 | plusAccIsPlus Z n = Refl
20 | plusAccIsPlus (S m) n =
21 | rewrite plusSuccRightSucc m n in
22 | plusAccIsPlus m (S n)
25 | plusAccZeroRightNeutral : (m : Nat) -> plusAcc m 0 === m
26 | plusAccZeroRightNeutral m =
27 | rewrite sym (plusAccIsPlus m 0) in
28 | rewrite plusZeroRightNeutral m in
33 | export typebind infixr 0 .-
40 | data Telescope : (k : Nat) -> Type where
42 | (-.) : (gamma : Left.Telescope k) -> (ty : TypeIn gamma) -> Telescope (S k)
46 | TypeIn : Left.Telescope k -> Type
47 | TypeIn gamma = (env : Environment gamma) -> Type
51 | Environment : Left.Telescope k -> Type
53 | Environment (gamma -. ty) = (env : Environment gamma ** ty env)
56 | weakenTypeIn : TypeIn gamma -> TypeIn (gamma -. sigma)
57 | weakenTypeIn ty env = ty (fst env)
60 | uncons : (gamma : Telescope (S k)) ->
62 | ** delta : (ty -> Telescope k)
63 | ** (v : ty) -> Environment (delta v) -> Environment gamma)
64 | uncons ([] -. ty) = (
ty () ** const [] ** \ v, _ => (
() ** v))
65 | uncons (gamma@(_ -. _) -. ty) =
66 | let (
sigma ** delta ** left)
= uncons gamma in
67 | (
sigma ** (\ v => delta v -. (\ env => ty (left v env)))
68 | ** (\ v, (
env ** w)
=> (
left v env ** w)
))
70 | export autobind infixr 0 \++
73 | (\++) : {n : Nat} -> (gamma : Left.Telescope m) -> (Environment gamma -> Left.Telescope n) ->
74 | Telescope (plusAcc n m)
75 | (\++) {n = Z} gamma delta = gamma
76 | (\++) {n = S n} gamma delta = (env <- gamma -. sigma) \++ uncurry theta env where
78 | sigma : Environment gamma -> Type
79 | sigma env = fst (uncons (delta env))
81 | theta : (env : Environment gamma) -> sigma env -> Telescope n
82 | theta env val with (uncons (delta env))
83 | theta env val | (
sig ** omega ** _)
= omega val
86 | cons : {k : Nat} -> (ty : Type) -> (ty -> Left.Telescope k) -> Left.Telescope (S k)
88 | rewrite plusCommutative 1 k in
89 | rewrite plusAccIsPlus k 1 in
90 | (env <- [] -. const sigma) \++ gamma (snd env)
96 | Position : {k : Nat} -> Telescope k -> Type
97 | Position {k} _ = Fin (S k)
101 | start : {k : Nat} -> (gamma : Telescope k) -> Position gamma
102 | start {k} gamma = last
109 | data Telescope : (k : Nat) -> Type where
111 | (.-) : (ty : Type) -> (gamma : ty -> Right.Telescope k) -> Telescope (S k)
115 | Environment : Right.Telescope k -> Type
116 | Environment [] = ()
117 | Environment (ty .- gamma) = (v : ty ** Environment (gamma v))
120 | empty : (0 gamma : Right.Telescope Z) -> Environment gamma
121 | empty {gamma = []} = ()
124 | snoc : (gamma : Right.Telescope k) -> (Environment gamma -> Type) -> Right.Telescope (S k)
125 | snoc [] tau = (v : tau ()) .- const [] v
126 | snoc (sigma .- gamma) tau = (v : sigma) .- snoc (gamma v) (\ env => tau (
v ** env)
)
129 | unsnoc : {k : Nat} -> (gamma : Right.Telescope (S k)) ->
130 | (delta : Right.Telescope k
131 | ** sigma : (Environment delta -> Type)
132 | ** (env : Environment delta) -> sigma env -> Environment gamma)
133 | unsnoc {k = Z} (sigma .- gamma) = (
[] ** const sigma ** \ (), v => (
v ** empty (gamma v)))
134 | unsnoc {k = S k} (sigma .- gamma)
135 | = (
(x : sigma) .- delta x ** uncurry tau ** \ (
v ** env)
=> transp v env)
where
137 | delta : sigma -> Right.Telescope k
138 | delta v = fst (unsnoc (gamma v))
140 | tau : (v : sigma) -> Environment (delta v) -> Type
141 | tau v = fst (snd (unsnoc (gamma v)))
143 | transp : (v : sigma) -> (env : Environment (delta v)) -> tau v env -> Environment ((x : sigma) .- gamma x)
144 | transp v env w = (
v ** (snd (snd (unsnoc (gamma v))) env w))
146 | export autobind infixr 0 ++/
149 | (++/) : (gamma : Right.Telescope m) -> (Environment gamma -> Right.Telescope n) -> Right.Telescope (m + n)
150 | [] ++/ delta = delta ()
151 | (sigma .- gamma) ++/ delta = (v : sigma) .- (env <- gamma v) ++/ delta (
v ** env)
154 | split : (gamma : Right.Telescope m) -> (delta : Environment gamma -> Right.Telescope n) ->
155 | Environment ((env <- gamma) ++/ delta env) ->
156 | (env : Environment gamma ** Environment (delta env))
157 | split [] delta env = (
() ** env)
158 | split (sigma .- gamma) delta (
v ** env)
=
159 | let (
env1 ** env2)
= split (gamma v) (\env => delta (
v ** env)
) env in
160 | ((
v ** env1)
** env2)
169 | data Telescope : (k : Nat) -> Type where
171 | Elt : Type -> Telescope 1
172 | (><) : (gamma : Tree.Telescope m) ->
173 | (delta : Tree.Environment gamma -> Tree.Telescope n) ->
178 | Environment : Tree.Telescope k -> Type
179 | Environment [] = ()
180 | Environment (Elt t) = t
181 | Environment (gamma >< delta) = (env : Environment gamma ** Environment (delta env))
184 | concat : (gamma : Tree.Telescope k) -> (delta : Right.Telescope k ** Environment delta -> Environment gamma)
185 | concat Nil = (
[] ** id)
186 | concat (Elt t) = (
(x : t) .- const [] x ** fst)
187 | concat (gamma >< delta) =
188 | let (
thetaL ** transpL)
= concat gamma in
189 | (
((envL <- thetaL) ++/ fst (concat (delta (transpL envL))))
191 | let (
env1 ** env2)
= split thetaL (\ envL => fst (concat (delta (transpL envL)))) env in
192 | (
transpL env1 ** snd (concat (delta (transpL env1))) env2)
195 | export autobind infixr 0 <++>
198 | (<++>) : (gamma : Left.Telescope m) -> (Environment gamma -> Right.Telescope n) -> Right.Telescope (plusAcc m n)
199 | [] <++> delta = delta ()
200 | (gamma -. sigma ) <++> delta = (env <- gamma) <++> (v : sigma env) .- delta (
env ** v)
202 | export autobind infixr 0 >++<
204 | (>++<) : {m, n : Nat} -> (gamma : Right.Telescope m) -> (Environment gamma -> Left.Telescope n) ->
205 | Left.Telescope (plusAcc m n)
206 | [] >++< delta = delta ()
207 | gamma@(_ .- _) >++< delta =
208 | let (
gamma ** sigma ** transp)
= unsnoc gamma in
209 | (env <- gamma) >++< cons (sigma env) (\ v => delta (transp env v))
212 | leftToRight : Left.Telescope m -> Right.Telescope m
213 | leftToRight gamma = rewrite sym (plusAccZeroRightNeutral m) in (env <- gamma) <++> const [] env
216 | rightToLeft : {m : Nat} -> Right.Telescope m -> Left.Telescope m
217 | rightToLeft gamma = rewrite sym (plusAccZeroRightNeutral m) in (env <- gamma) >++< const [] env