1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
|
module Total.LogRel
import Data.Singleton
import Syntax.PreorderReasoning
import Total.Reduction
import Total.Term
import Total.Term.CoDebruijn
%prefix_record_projections off
public export
LogRel :
{ctx : SnocList Ty} ->
(P : {ctx, ty : _} -> FullTerm ty ctx -> Type) ->
{ty : Ty} ->
(t : FullTerm ty ctx) ->
Type
LogRel p {ty = N} t = p t
LogRel p {ty = ty ~> ty'} t =
(p t,
{ctx' : SnocList Ty} ->
(thin : ctx `Thins` ctx') ->
(u : FullTerm ty ctx') ->
LogRel p u ->
LogRel p (app (wkn t thin) u))
export
escape :
{0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} ->
{ty : Ty} ->
{0 t : FullTerm ty ctx} ->
LogRel P t ->
P t
escape {ty = N} pt = pt
escape {ty = ty ~> ty'} (pt, app) = pt
public export
record PreserveHelper
(P : {ctx, ty : _} -> FullTerm ty ctx -> Type)
(R : {ctx, ty : _} -> FullTerm ty ctx -> FullTerm ty ctx -> Type) where
constructor MkPresHelper
0 app :
{ctx : SnocList Ty} ->
{ty, ty' : Ty} ->
(t, u : FullTerm (ty ~> ty') ctx) ->
{ctx' : SnocList Ty} ->
(thin : ctx `Thins` ctx') ->
(v : FullTerm ty ctx') ->
R t u ->
R (app (wkn t thin) v) (app (wkn u thin) v)
pres :
{0 ctx : SnocList Ty} ->
{ty : Ty} ->
{0 t, u : FullTerm ty ctx} ->
P t ->
(0 _ : R t u) ->
P u
%name PreserveHelper help
export
backStepHelper :
{0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} ->
(forall ctx, ty. {0 t, u : FullTerm ty ctx} -> P t -> (0 _ : toTerm u > toTerm t) -> P u) ->
PreserveHelper P (flip (>) `on` CoDebruijn.toTerm)
backStepHelper pres =
MkPresHelper
(\t, u, thin, v, step =>
rewrite toTermApp (wkn u thin) v in
rewrite toTermApp (wkn t thin) v in
rewrite sym $ wknToTerm t thin in
rewrite sym $ wknToTerm u thin in
AppCong1 (wknStep step))
pres
export
preserve :
{0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} ->
{0 R : {ctx, ty : _} -> FullTerm ty ctx -> FullTerm ty ctx -> Type} ->
{ty : Ty} ->
{0 t, u : FullTerm ty ctx} ->
PreserveHelper P R ->
LogRel P t ->
(0 _ : R t u) ->
LogRel P u
preserve help {ty = N} pt prf = help.pres pt prf
preserve help {ty = ty ~> ty'} (pt, app) prf =
(help.pres pt prf, \thin, v, rel => preserve help (app thin v rel) (help.app _ _ thin v prf))
data AllLogRel : (P : {ctx, ty : _} -> FullTerm ty ctx -> Type) -> CoTerms ctx ctx' -> Type where
Lin :
{0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} ->
AllLogRel P [<]
(:<) :
{0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} ->
AllLogRel P sub ->
LogRel P t ->
AllLogRel P (sub :< t)
%name AllLogRel allRels
index :
{0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} ->
((i : Elem ty ctx') -> LogRel P (var i)) ->
{sub : CoTerms ctx ctx'} ->
AllLogRel P sub ->
(i : Elem ty ctx) ->
LogRel P (index sub i)
index f (allRels :< rel) Here = rel
index f (allRels :< rel) (There i) = index f allRels i
restrict :
{0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} ->
{0 sub : CoTerms ctx' ctx''} ->
AllLogRel P sub ->
(thin : ctx `Thins` ctx') ->
AllLogRel P (restrict sub thin)
restrict [<] Empty = [<]
restrict (allRels :< rel) (Drop thin) = restrict allRels thin
restrict (allRels :< rel) (Keep thin) = restrict allRels thin :< rel
Valid :
(P : {ctx, ty : _} -> FullTerm ty ctx -> Type) ->
{ctx : SnocList Ty} ->
{ty : Ty} ->
(t : FullTerm ty ctx) ->
Type
Valid p t =
{ctx' : SnocList Ty} ->
(sub : CoTerms ctx ctx') ->
(allRel : AllLogRel p sub) ->
LogRel p (subst t sub)
public export
record ValidHelper (P : {ctx, ty : _} -> FullTerm ty ctx -> Type) where
constructor MkValidHelper
var : forall ctx. Len ctx => {ty : Ty} -> (i : Elem ty ctx) -> LogRel P (var i)
abs : forall ctx, ty. {ty' : Ty} -> {0 t : FullTerm ty' (ctx :< ty)} -> LogRel P t -> P (abs t)
zero : forall ctx. Len ctx => P {ctx} zero
suc : forall ctx. {0 t : FullTerm N ctx} -> P t -> P (suc t)
rec :
{ctx : SnocList Ty} ->
{ty : Ty} ->
{0 t : FullTerm N ctx} ->
{u : FullTerm ty ctx} ->
{v : FullTerm (ty ~> ty) ctx} ->
LogRel P t ->
LogRel P u ->
LogRel P v ->
LogRel P (rec t u v)
step : forall ctx, ty. {0 t, u : FullTerm ty ctx} -> P t -> (0 _ : toTerm u > toTerm t) -> P u
wkn : forall ctx, ctx', ty.
{0 t : FullTerm ty ctx} ->
P t ->
(thin : ctx `Thins` ctx') ->
P (wkn t thin)
%name ValidHelper help
wknRel :
{0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} ->
ValidHelper P ->
{ty : Ty} ->
{0 t : FullTerm ty ctx} ->
LogRel P t ->
(thin : ctx `Thins` ctx') ->
LogRel P (wkn t thin)
wknRel help {ty = N} pt thin = help.wkn pt thin
wknRel help {ty = ty ~> ty'} (pt, app) thin =
( help.wkn pt thin
, \thin', u, rel =>
rewrite wknHomo t thin' thin in
app (thin' . thin) u rel
)
wknAllRel :
{0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} ->
ValidHelper P ->
{ctx : SnocList Ty} ->
{sub : CoTerms ctx ctx'} ->
AllLogRel P sub ->
(thin : ctx' `Thins` ctx'') ->
AllLogRel P (wknAll sub thin)
wknAllRel help [<] thin = [<]
wknAllRel help (allRels :< rel) thin = wknAllRel help allRels thin :< wknRel help rel thin
shiftRel :
{0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} ->
ValidHelper P ->
{ctx, ctx' : SnocList Ty} ->
{sub : CoTerms ctx ctx'} ->
AllLogRel P sub ->
AllLogRel P (shift {ty} sub)
shiftRel help [<] = [<]
shiftRel help (allRels :< rel) =
shiftRel help allRels :<
replace {p = LogRel P} (sym $ dropIsWkn _) (wknRel help rel (Drop id))
liftRel :
{0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} ->
ValidHelper P ->
{ctx, ctx' : SnocList Ty} ->
{ty : Ty} ->
{sub : CoTerms ctx ctx'} ->
AllLogRel P sub ->
AllLogRel P (lift {ty} sub)
liftRel help allRels = shiftRel help allRels :< help.var Here
absValid :
{0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} ->
ValidHelper P ->
{ctx : SnocList Ty} ->
{ty, ty' : Ty} ->
(t : CoTerm ty' (ctx ++ used)) ->
(thin : used `Thins` [<ty]) ->
(valid : {ctx' : SnocList Ty} ->
(sub : CoTerms (ctx ++ used) ctx') ->
AllLogRel P sub ->
LogRel P (subst' t sub)) ->
{ctx' : SnocList Ty} ->
(sub : CoTerms ctx ctx') ->
AllLogRel P sub ->
LogRel P (subst' (Abs (MakeBound t thin)) sub)
absValid help t (Drop Empty) valid sub allRels =
( help.abs (valid (shift sub) (shiftRel help allRels))
, \thin, u, rel =>
preserve
(backStepHelper help.step)
(valid (wknAll sub thin) (wknAllRel help allRels thin))
?betaStep
)
absValid help t (Keep Empty) valid sub allRels =
( help.abs (valid (lift sub) (liftRel help allRels))
, \thin, u, rel =>
preserve (backStepHelper help.step)
(valid (wknAll sub thin :< u) (wknAllRel help allRels thin :< rel))
?betaStep'
)
export
allValid :
{0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} ->
ValidHelper P ->
(s : Singleton ctx) =>
{ty : Ty} ->
(t : FullTerm ty ctx) ->
Valid P t
allValid' :
{0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} ->
ValidHelper P ->
(s : Singleton ctx) =>
{ty : Ty} ->
(t : CoTerm ty ctx) ->
{ctx' : SnocList Ty} ->
(sub : CoTerms ctx ctx') ->
AllLogRel P sub ->
LogRel P (subst' t sub)
allValid help (t `Over` thin) sub allRels =
allValid' help t (restrict sub thin) (restrict allRels thin)
allValid' help Var sub allRels = index help.var allRels Here
allValid' help {s = Val ctx} (Abs {ty, ty'} (MakeBound t thin)) sub allRels =
let s' = [| Val ctx ++ retractSingleton (Val [<ty]) thin |] in
absValid help t thin (allValid' help t) sub allRels
allValid' help (App (MakePair t u _)) sub allRels =
let (pt, app) = allValid help t sub allRels in
let rel = allValid help u sub allRels in
rewrite sym $ wknId (subst t sub) in
app id (subst u sub) rel
allValid' help Zero sub allRels = help.zero
allValid' help (Suc t) sub allRels =
let pt = allValid' help t sub allRels in
help.suc pt
allValid' help (Rec (MakePair t (MakePair u v _ `Over` thin) _)) sub allRels =
let relT = allValid help t sub allRels in
let relU = allValid help u (restrict sub thin) (restrict allRels thin) in
let relV = allValid help v (restrict sub thin) (restrict allRels thin) in
help.rec relT relU relV
-- -- allValid help (Var i) sub allRels = index help.var allRels i
-- -- allValid help (Abs t) sub allRels =
-- -- let valid = allValid help t in
-- -- (let
-- -- rec =
-- -- valid
-- -- (wknAll sub (Drop id) :< Var Here)
-- -- (wknAllRel help allRels (Drop id) :< help.var Here)
-- -- in
-- -- help.abs rec
-- -- , \thin, u, rel =>
-- -- let
-- -- eq :
-- -- (subst
-- -- (wkn (subst t (wknAll sub (Drop Thinning.id) :< Var Here)) (Keep thin))
-- -- (Base Thinning.id :< u) =
-- -- subst t (wknAll sub thin :< u))
-- -- eq =
-- -- Calc $
-- -- |~ subst (wkn (subst t (wknAll sub (Drop id) :< Var Here)) (Keep thin)) (Base id :< u)
-- -- ~~ subst (subst t (wknAll sub (Drop id) :< Var Here)) (restrict (Base id :< u) (Keep thin))
-- -- ...(substWkn (subst t (wknAll sub (Drop id) :< Var Here)) (Keep thin) (Base id :< u))
-- -- ~~ subst (subst t (wknAll sub (Drop id) :< Var Here)) (Base thin :< u)
-- -- ...(cong (subst (subst t (wknAll sub (Drop id) :< Var Here)) . (:< u) . Base) $ identityLeft thin)
-- -- ~~ subst t ((Base thin :< u) . wknAll sub (Drop id) :< u)
-- -- ...(substHomo t (wknAll sub (Drop id) :< Var Here) (Base thin :< u))
-- -- ~~ subst t (Base (thin . id) . sub :< u)
-- -- ...(cong (subst t . (:< u)) $ compWknAll sub (Base thin :< u) (Drop id))
-- -- ~~ subst t (Base thin . sub :< u)
-- -- ...(cong (subst t . (:< u) . (. sub) . Base) $ identityRight thin)
-- -- ~~ subst t (wknAll sub thin :< u)
-- -- ...(cong (subst t . (:< u)) $ baseComp thin sub)
-- -- in
-- -- preserve
-- -- (backStepHelper help.step)
-- -- (valid (wknAll sub thin :< u) (wknAllRel help allRels thin :< rel))
-- -- (replace {p = (App (wkn (subst (Abs t) sub) thin) u >)}
-- -- eq
-- -- (AppBeta (length _)))
-- -- )
-- -- allValid help (App t u) sub allRels =
-- -- let (pt, app) = allValid help t sub allRels in
-- -- let rel = allValid help u sub allRels in
-- -- rewrite sym $ wknId (subst t sub) in
-- -- app id (subst u sub) rel
-- -- allValid help Zero sub allRels = help.zero
-- -- allValid help (Suc t) sub allRels =
-- -- let pt = allValid help t sub allRels in
-- -- help.suc pt
-- -- allValid help (Rec t u v) sub allRels =
-- -- let relt = allValid help t sub allRels in
-- -- let relu = allValid help u sub allRels in
-- -- let relv = allValid help v sub allRels in
-- -- help.rec relt relu relv
idRel :
{0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} ->
{ctx : SnocList Ty} ->
ValidHelper P ->
AllLogRel P {ctx} (Base Thinning.id)
idRel help {ctx = [<]} = [<]
idRel help {ctx = ctx :< ty} = liftRel help (idRel help)
export
allRel :
{0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} ->
{ctx : SnocList Ty} ->
{ty : Ty} ->
ValidHelper P ->
(t : FullTerm ty ctx) ->
P t
allRel help t =
rewrite sym $ substId t in
escape {P} $
allValid help @{Val ctx} t (Base id) (idRel help)
|