forked from MetaCoq/metacoq
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPCUICRetyping.v
256 lines (215 loc) · 7.14 KB
/
PCUICRetyping.v
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
(* Distributed under the terms of the MIT license. *)
From Coq Require Import Bool String List Program BinPos Compare_dec Omega.
From MetaCoq.Template Require Import config monad_utils utils.
From MetaCoq.PCUIC Require Import PCUICAst PCUICAstUtils PCUICInduction PCUICLiftSubst PCUICUnivSubst PCUICTyping PCUICChecker PCUICConversion PCUICCumulativity.
Require Import String.
Local Open Scope string_scope.
Set Asymmetric Patterns.
Import monad_utils.MonadNotation.
(** * Retyping
The [type_of] function provides a fast (and loose) type inference
function which assumes that the provided term is already well-typed in
the given context and recomputes its type. Only reduction (for
head-reducing types to uncover dependent products or inductives) and
substitution are costly here. No universe checking or conversion is done
in particular. *)
Axiom reduce_to_sort :
global_env -> context -> term -> typing_result universe.
Axiom reduce_to_prod :
global_env -> context -> term -> typing_result (term × term).
Axiom reduce_to_ind :
global_env -> context -> term
-> typing_result ((inductive × list Level.t) × list term).
Section TypeOf.
Context {cf : checker_flags}.
Context `{F : Fuel}.
Context (Σ : global_env_ext).
Section SortOf.
Context (type_of : context -> term -> typing_result term).
Definition type_of_as_sort Γ t :=
tx <- type_of Γ t ;;
reduce_to_sort (fst Σ) Γ tx.
End SortOf.
Fixpoint type_of (Γ : context) (t : term) : typing_result term :=
match t with
| tRel n =>
match nth_error Γ n with
| Some d => ret (lift0 (S n) d.(decl_type))
| None => raise (UnboundRel n)
end
| tVar n => raise (UnboundVar n)
| tEvar ev args => raise (UnboundEvar ev)
| tSort s => ret (tSort (Universe.try_suc s))
| tProd n t b =>
s1 <- type_of_as_sort type_of Γ t ;;
s2 <- type_of_as_sort type_of (Γ ,, vass n t) b ;;
ret (tSort (Universe.sort_of_product s1 s2))
| tLambda n t b =>
t2 <- type_of (Γ ,, vass n t) b ;;
ret (tProd n t t2)
| tLetIn n b b_ty b' =>
b'_ty <- type_of (Γ ,, vdef n b b_ty) b' ;;
ret (tLetIn n b b_ty b'_ty)
| tApp t a =>
ty <- type_of Γ t ;;
pi <- reduce_to_prod (fst Σ) Γ ty ;;
let '(a1, b1) := pi in
ret (subst10 a b1)
| tConst cst u => lookup_constant_type Σ cst u
| tInd (mkInd ind i) u => lookup_ind_type Σ ind i u
| tConstruct (mkInd ind i) k u =>
lookup_constructor_type Σ ind i k u
| tCase (ind, par) p c brs =>
ty <- type_of Γ c ;;
indargs <- reduce_to_ind (fst Σ) Γ ty ;;
let '(ind', u, args) := indargs in
ret (mkApps p (List.skipn par args ++ [c]))
| tProj p c =>
ty <- type_of Γ c ;;
indargs <- reduce_to_ind (fst Σ) Γ ty ;;
(* FIXME *)
ret ty
| tFix mfix n =>
match nth_error mfix n with
| Some f => ret f.(dtype)
| None => raise (IllFormedFix mfix n)
end
| tCoFix mfix n =>
match nth_error mfix n with
| Some f => ret f.(dtype)
| None => raise (IllFormedFix mfix n)
end
end.
Definition sort_of (Γ : context) (t : term) : typing_result universe :=
ty <- type_of Γ t;;
type_of_as_sort type_of Γ ty.
Open Scope type_scope.
Conjecture cumul_reduce_to_sort : forall {Γ T s},
reduce_to_sort (fst Σ) Γ T = Checked s ->
Σ ;;; Γ |- T <= tSort s.
Conjecture cumul_reduce_to_prod : forall {Γ T A B},
reduce_to_prod (fst Σ) Γ T = Checked (A, B) ->
forall n, Σ ;;; Γ |- T <= tProd n A B.
Conjecture congr_cumul_letin : forall {Γ n a A t n' a' A' t'},
Σ ;;; Γ |- a <= a' ->
Σ ;;; Γ |- A <= A' ->
Σ ;;; Γ ,, vdef n a A' |- t <= t' ->
Σ ;;; Γ |- tLetIn n a A t <= tLetIn n' a' A' t'.
Ltac case_eq_match :=
lazymatch goal with
| |- context [ match ?t with _ => _ end ] =>
case_eq t ; try solve [ intros ; discriminate ]
| h : context [ match ?t with _ => _ end ] |- _ =>
revert h ;
case_eq t ; try solve [ intros ; discriminate ]
end.
Ltac deal_as_sort :=
lazymatch goal with
| h : type_of_as_sort _ _ _ = _ |- _ =>
unfold type_of_as_sort in h ;
simpl in h
end.
Ltac deal_reduce_to_sort :=
lazymatch goal with
| h : reduce_to_sort _ _ _ = Checked _ |- _ =>
pose proof (cumul_reduce_to_sort h) ;
clear h
end.
Ltac deal_reduce_to_prod :=
lazymatch goal with
| h : reduce_to_prod _ _ _ = Checked _ |- _ =>
let hh := fresh h in
pose proof (cumul_reduce_to_prod h) as hh ;
clear h ;
lazymatch goal with
| na : name |- _ => specialize (hh na)
| |- _ => specialize (hh nAnon)
end
end.
Ltac deal_Checked :=
match goal with
| h : Checked _ = Checked _ |- _ =>
inversion h ; subst ; clear h
end.
Ltac go eq :=
simpl in eq ; revert eq ;
repeat (case_eq_match ; intros) ;
repeat deal_as_sort ;
repeat (case_eq_match ; intros) ;
repeat deal_Checked ;
repeat deal_reduce_to_sort ;
repeat deal_reduce_to_prod.
Ltac one_ih :=
lazymatch goal with
| h : _ -> _ -> (_ ;;; _ |- ?t : _) * _ |- _ ;;; _ |- ?t : _ =>
eapply h
| h : _ -> _ -> _ * (_ ;;; _ |- _ <= ?A) |- _ ;;; _ |- _ <= ?A =>
eapply h
end.
Ltac ih :=
one_ih ; eassumption.
Ltac cih :=
eapply type_Cumul ; [
ih
| try eassumption
| try eassumption
].
Theorem type_of_sound :
forall {Γ t A B},
Σ ;;; Γ |- t : A ->
type_of Γ t = Checked B ->
(Σ ;;; Γ |- t : B) * (Σ ;;; Γ |- B <= A).
Proof.
intros Γ t A B h eq. revert B eq.
induction h ; intros T eq.
- cbn in eq. rewrite e in eq.
inversion eq. subst. clear eq.
split.
+ econstructor ; eassumption.
+ eapply cumul_refl'.
- cbn in eq. inversion eq. subst. clear eq.
split.
+ (* Proving Typeᵢ : Typeᵢ₊₁ shouldn't be hard... *)
admit.
+ (* destruct l. all: cbn. all: econstructor. all: cbn. all: try reflexivity. *)
admit.
- go eq.
split.
+ econstructor ; try eassumption ; try ih ; try cih.
(* Again we're missing result on how to type sorts... *)
left. red. exists [], a.
unfold app_context; simpl; intuition auto with pcuic.
eapply typing_wf_local; tea.
left. red. exists [], a0. unfold app_context; simpl; intuition auto with pcuic.
eapply typing_wf_local; tea.
+ (* Sorts again *)
simpl.
admit.
- go eq. split.
+ econstructor ; try eassumption ; try ih ; try cih.
+ eapply congr_cumul_prod.
* eapply conv_alt_refl. reflexivity.
* ih.
- go eq. split.
+ econstructor ; try eassumption ; try ih ; try cih.
+ eapply congr_cumul_letin. all: try eapply cumul_refl'.
ih.
- go eq. split.
+ econstructor ; try eassumption ; try ih ; try cih.
all: admit.
+ (* eapply cumul_subst. *)
admit.
- simpl in eq. split.
+ admit.
+ admit.
- admit.
- admit.
- admit.
- admit.
- admit.
- admit.
- split.
+ ih.
+ eapply cumul_trans ; try eassumption.
Admitted.
End TypeOf.