/
ReplacementTyping.v
1315 lines (1229 loc) · 46.6 KB
/
ReplacementTyping.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
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
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
(** printing |-# %\vdash_{\#}% #⊢<sub>#</sub># *)
(** printing |-## %\vdash_{\#\#}% #⊢<sub>##</sub># *)
(** printing |-##v %\vdash_{\#\#v}% #⊢<sub>##v</sub># *)
(** printing |-! %\vdash_!% #⊢<sub>!</sub># *)
(** remove printing ~ *)
(** * Replacement (Introduction-qp) Typing *)
(** This module contains lemmas related to replacement typing
([|-//] and [|-//v]). *)
Set Implicit Arguments.
Require Import Coq.Program.Equality List String.
Require Import Sequences.
Require Import Definitions Binding InvertibleTyping Narrowing PreciseTyping
RecordAndInertTypes Replacement Subenvironments TightTyping Weakening.
(** Whereas invertible typing does replacement for singleton types in one direction,
replacement typing does the replacment in the other direction.
Note that we can't simply define this using three rules:
1) identity from invertible typing
2) two repl subtyping rules
The reason is that if we did that, repl typing would necessarily apply the replacement
in all subterms of a term, whereas we want to be able to say, for example:
[Г ⊢## p: T] #<br>#
[Г ⊢// p: U] #<br>#
[__________] #<br>#
[Г ⊢// p: T ∧ U] #<br>#
*)
(** ** Replacement Typing for Paths *)
Reserved Notation "G '⊢//' p ':' T" (at level 40, p at level 59).
Inductive ty_repl : ctx -> path -> typ -> Prop :=
(** [G ⊢## p: T] #<br>#
[―――――――――――――――] #<br>#
[G ⊢// p: T] *)
| ty_inv_r : forall G p T,
G ⊢## p: T ->
G ⊢// p: T
(** [G ⊢// p : T] #<br>#
[G ⊢// p : U] #<br>#
[――――――――――――――――] #<br>#
[G ⊢// p : T /\ U] *)
| ty_and_r : forall G p T U,
G ⊢// p: T ->
G ⊢// p: U ->
G ⊢// p: T ∧ U
(** [G ⊢## p : T^p] #<br>#
[――――――――――――――] #<br>#
[G ⊢## p : μ(T)] *)
| ty_bnd_r : forall G p T,
G ⊢// p: open_typ_p p T ->
G ⊢// p: μ T
(** [G ⊢// p : T] #<br>#
[G ⊢! q: _ ⪼ {A: T..T}] #<br>#
[―――――――――――――――――――――――] #<br>#
[G ⊢//p : q.A] *)
| ty_sel_r : forall G p T q S A,
G ⊢// p: T ->
G ⊢! q: S ⪼ typ_rcd {A >: T <: T} ->
G ⊢// p: q↓A
(** [G ⊢// p.a: T] #<br>#
[―――――――――――――――] #<br>#
[G ⊢// p: {a: T}] *)
| ty_rcd_intro_r : forall G p a T,
G ⊢// p•a : T ->
G ⊢// p : typ_rcd { a ⦂ T }
(** [G ⊢! p: q.type ⪼ q.type] #<br>#
[G ⊢!! q] #<br>#
[G ⊢// r: μ(T)] #<br>#
[――――――――――――――――――――] #<br>#
[G ⊢// p: μ(T[q/p])] *)
| ty_rec_qp_r : forall G p q r T T' U,
G ⊢! p : {{ q }} ⪼ {{ q }} ->
G ⊢!! q : U ->
G ⊢// r : μ T ->
repl_typ q p T T' ->
G ⊢// r : μ T'
(** [G ⊢! p: q.type ⪼ q.type] #<br>#
[G ⊢!! q] #<br>#
[G ⊢// r: r'.A] #<br>#x
[――――――――――――――――――――] #<br>#
[G ⊢// p: (r'.A)[q/p]] *)
| ty_sel_qp_r : forall G p q r A bs U,
G ⊢! p : {{ q }} ⪼ {{ q }} ->
G ⊢!! q: U ->
G ⊢// r : (q •• bs)↓A ->
G ⊢// r : (p •• bs)↓A
(** [G ⊢! p: q.type ⪼ q.type] #<br>#
[G ⊢!! q] #<br>#
[G ⊢// r: r'.type] #<br>#
[――――――――――――――――――――] #<br>#
[G ⊢// p: (r'.type)[q/p]] *)
| ty_sngl_qp_r : forall G p q r bs U,
G ⊢! p : {{ q }} ⪼ {{ q }} ->
G ⊢!! q: U ->
G ⊢// r : {{ q •• bs }} ->
G ⊢// r : {{ p •• bs }}
(** [G ⊢## p] #<br>#
[―――――――――――――] #<br>#
[G ⊢## p: top] *)
| ty_top_r : forall G p T,
G ⊢// p : T ->
G ⊢// p : ⊤
(** [G ⊢## p: {a: T}] #<br>#
[G ⊢# T <: U] #<br>#
[――――――――――――――――] #<br>#
[G ⊢## p: {a: U}] *)
| ty_dec_trm_r : forall G p a T U,
G ⊢// p : typ_rcd {a ⦂ T} ->
G ⊢# T <: U ->
G ⊢// p : typ_rcd {a ⦂ U}
(** [G ⊢## p: {A: T1..S1}] #<br>#
[G ⊢# T2 <: T1] #<br>#
[G ⊢# S1 <: S2] #<br>#
[―――――――――――――――――――――] #<br>#
[G ⊢## p: {A: T2..S2}] *)
| ty_dec_typ_r : forall G p A T1 T2 S1 S2,
G ⊢// p : typ_rcd {A >: T1 <: S1} ->
G ⊢# T2 <: T1 ->
G ⊢# S1 <: S2 ->
G ⊢// p : typ_rcd {A >: T2 <: S2}
(** [G ⊢## p: forall(S1)T1] #<br>#
[G ⊢# S2 <: S1] #<br>#
[G, y: S2 ⊢ T1^y <: T2^y] #<br>#
[y fresh] #<br>#
[――――――――――――――――――――――] #<br>#
[G ⊢## p: forall(S')T'] *)
| ty_all_r : forall G T1 T2 S1 S2 L p,
G ⊢// p : ∀(S1) T1 ->
G ⊢# S2 <: S1 ->
(forall y, y \notin L ->
G & y ~ S2 ⊢ open_typ y T1 <: open_typ y T2) ->
G ⊢// p : ∀(S2) T2
where "G '⊢//' p ':' T" := (ty_repl G p T).
Hint Constructors ty_repl.
(** *** From Replacement To Precise Typing *)
(** Replacement-to-precise typing for function types:
if [G ⊢// p: forall(S)T] then
- [exists S', T'. G ⊢!!! p: forall(S')T'],
- [G ⊢# S <: S'], and
- [G ⊢# T'^y <: T^y],
where [y] is fresh. *)
Lemma repl_to_precise_typ_all: forall G p S T,
inert G ->
G ⊢// p : ∀(S) T ->
exists S' T' L,
G ⊢!!! p : ∀(S') T' /\
G ⊢# S <: S' /\
(forall y,
y \notin L ->
G & y ~ S ⊢ open_typ y T' <: open_typ y T).
Proof.
introv Hi Hp. dependent induction Hp. apply* invertible_to_precise_typ_all.
specialize (IHHp _ _ Hi eq_refl). destruct IHHp as [S' [T' [L' [Hp' [Hs1 Hs]]]]].
exists S' T' (L \u L' \u dom G). repeat split; auto. eauto.
introv Hy. eapply subtyp_trans.
+ eapply narrow_subtyping. apply* Hs. apply subenv_last. apply* tight_to_general.
apply* ok_push.
+ eauto.
Qed.
(** Replacement-to-precise typing for records:
if [G |-// p: {A: S..U}] then
- [exists T. G |-// p: {A: T..T}],
- [G |-# T <: U], and
- [G |-# S <: T] *)
Lemma repl_to_precise_rcd: forall G p A S U,
inert G ->
G ⊢// p : typ_rcd {A >: S <: U} ->
exists T,
G ⊢!!! p : typ_rcd {A >: T <: T} /\
G ⊢# T <: U /\
G ⊢# S <: T.
Proof.
introv HG Hr. dependent induction Hr. apply* invertible_to_precise_rcd.
specialize (IHHr _ _ _ HG eq_refl).
destruct IHHr as [V [Hx [Hs1 Hs2]]]. exists V. split*.
Qed.
(** *** Properties of replacement typing *)
Lemma repl_and: forall G p T U,
inert G ->
G ⊢// p: T ∧ U ->
G ⊢// p: T /\ G ⊢// p: U.
Proof.
introv Hi Hp. dependent induction Hp; eauto.
destruct (invertible_and Hi H). split*.
Qed.
(** Replacement typing is closed under [qp] replacement
when we know [q]'s precise type *)
Lemma replacement_repl_closure_qp : forall G p q r T T' U,
inert G ->
G ⊢! q : {{ r }} ⪼ {{ r }} ->
G ⊢!! r : U ->
G ⊢// p : T ->
repl_typ r q T T' ->
G ⊢// p : T'.
Proof.
introv Hi Hq Hr Hp.
gen q r T' U. induction Hp; introv Hq; introv Hr' Hr; try solve [invert_repl; eauto 5].
- Case "ty_inv_r"%string.
gen q r T' U. induction H; introv Hq; introv Hr; introv Hr'; try solve [invert_repl; eauto 5].
-- SCase "ty_precise_inv"%string.
destruct (pt3_inertsngl Hi H) as [[Hit | Hs] | Hst].
+ SSCase "ty_precise_inv_1"%string.
inversions Hit; invert_repl.
++ eapply ty_all_r with (L := \{}).
apply ty_inv_r.
apply* ty_precise_inv. apply repl_swap in H5.
eauto. introv Hy. auto.
++ eapply ty_all_r with (L := dom G).
apply ty_inv_r.
apply* ty_precise_inv. auto. introv Hy.
eapply repl_open_var in H5; try solve_names.
eapply subtyp_sngl_qp. apply* weaken_ty_trm.
eapply precise_to_general. apply Hq. apply* weaken_ty_trm. apply* precise_to_general2. apply H5.
++ apply* ty_rec_qp_r.
+ SSCase "ty_precise_inv_2"%string.
inversions Hs. invert_repl.
eapply ty_sngl_qp_r; eauto.
+ SSCase "ty_precise_inv_3"%string.
inversion Hst as [x Hx].
generalize dependent T'.
dependent induction Hx; introv Hr; subst; invert_repl.
++ destruct D2.
* invert_repl. apply ty_precise_inv in H.
assert (Hts : G ⊢# t0 <: T1).
{ apply repl_swap in H6. eauto. }
eauto.
invert_repl. apply ty_precise_inv in H.
assert (Hts : G ⊢# T1 <: t1).
{ eauto. } eauto.
* invert_repl. eapply ty_precise_inv in H.
eapply ty_dec_trm_r; eauto.
++ assert (Hpt0 : G ⊢!!! p : T) by (eapply pt3_and_destruct1; eauto).
assert (Hpd : G ⊢!!! p : (typ_rcd D)) by (eapply pt3_and_destruct2; eauto).
apply* ty_and_r.
++ assert (Hpt0 : G ⊢!!! p : T) by (eapply pt3_and_destruct1; eauto).
assert (Hpd : G ⊢!!! p : (typ_rcd D)) by (eapply pt3_and_destruct2; eauto).
apply ty_and_r; eauto.
destruct D2; invert_repl;
apply ty_precise_inv in Hpd.
* eapply ty_dec_typ_r; eauto. apply repl_swap in H7. eauto.
* eapply ty_dec_typ_r; eauto.
* eapply ty_dec_trm_r; eauto.
-- SCase "ty_sel_qp_inv"%string.
inversions Hr.
specialize (ty_sel_pq_inv _ H H0 H1). intros Hr.
rewrite <- H5 in Hr. eapply ty_sel_qp_r; eauto.
-- SCase "ty_sngl_qp_inv"%string.
inversions Hr.
specialize (ty_sngl_pq_inv _ H H0 H1). intros Hr.
rewrite <- H5 in Hr. eapply ty_sngl_qp_r; eauto.
- Case "ty_sel_qp_r"%string.
invert_repl. specialize (IHHp Hi _ _ H _ _ H0 (rpath q p bs A)).
rewrite <- H4 in IHHp. eapply ty_sel_qp_r; eauto.
- Case "ty_sngl_qp_r"%string.
invert_repl. specialize (IHHp Hi _ _ H _ _ H0 (rsngl q p bs)).
rewrite <- H4 in IHHp. eapply ty_sngl_qp_r; eauto.
- Case "ty_dec_trm_r"%string.
invert_repl. eapply ty_dec_trm_r; eauto. eapply subtyp_trans_t; eauto.
- Case "ty_dec_typ_r"%string.
invert_repl; eapply ty_dec_typ_r; eauto.
-- eapply subtyp_trans_t. eapply subtyp_sngl_pq_t; eauto.
apply repl_swap in H8. eauto. auto.
-- eapply subtyp_trans_t. eauto. eapply subtyp_sngl_qp_t; eauto.
- Case "ty_all_r"%string.
invert_repl.
-- eapply ty_all_r with (L:=L \u dom G); eauto.
* apply repl_swap in H6. eapply subtyp_trans_t.
eapply subtyp_sngl_pq_t; eauto. auto.
* introv Hy. eapply narrow_subtyping. apply H0. auto. constructor; auto.
apply tight_to_general. eapply subtyp_sngl_pq_t; eauto. apply repl_swap.
auto.
-- eapply ty_all_r with (L:=L \u dom G); eauto.
introv Hy. eapply subtyp_trans. apply H0. auto.
eapply repl_open_var in H6; try solve_names.
eapply subtyp_sngl_qp. apply* weaken_ty_trm. eapply precise_to_general.
apply Hq.
apply* weaken_ty_trm. apply* precise_to_general2. eapply H6.
Qed.
(** Replacement typing is closed under [qp] replacement
when we know [q]'s II-level precise type *)
Lemma replacement_repl_closure_qp2 : forall G p q r T T' U,
inert G ->
G ⊢!! q : {{ r }} ->
G ⊢!! r : U ->
G ⊢// p : T ->
repl_typ r q T T' ->
G ⊢// p : T'.
Proof.
introv Hi Hq Hr' Hp Hr. gen U. dependent induction Hq; introv Hr'.
- lets Heq: (pf_sngl_T Hi H). subst.
apply* replacement_repl_closure_qp.
- pose proof (repl_field_elim _ _ _ Hr) as Hr''.
pose proof (pt2_backtrack _ _ Hr') as [U' Hq]. eauto.
Qed.
(** Replacement typing is closed under [qp] replacement
when we know [q]'s III-level precise type *)
Lemma replacement_repl_closure_qp3 : forall G p q r T T' U,
inert G ->
G ⊢!!! q : {{ r }} ->
G ⊢!! r : U ->
G ⊢// p : T ->
repl_typ r q T T' ->
G ⊢// p : T'.
Proof.
introv Hi Hq Hr' Hp Hr. gen p T T' U. dependent induction Hq; introv Hp; introv Hr; introv Hr'.
- apply* replacement_repl_closure_qp2.
- specialize (IHHq _ Hi eq_refl _ _ Hp).
destruct (repl_insert q Hr) as [V [Hr1 Hr2]].
pose proof (pt2_exists Hq) as [S Hs].
specialize (IHHq _ Hr1 _ Hr'). eapply replacement_repl_closure_qp2.
auto. auto. apply H. apply Hs. apply IHHq. eauto.
Qed.
(** Replacement typing is closed under repeated [qp] replacements *)
Lemma replacement_repl_closure_qp_comp: forall G p q r T T' U,
inert G ->
G ⊢// p: T ->
G ⊢!!! q: {{ r }} ->
G ⊢!! r : U ->
repl_repeat_typ r q T T' ->
G ⊢// p: T'.
Proof.
introv Hi Hp Hq Hr Hc. gen p. dependent induction Hc; introv Hp; eauto.
apply* IHHc. apply* replacement_repl_closure_qp3.
Qed.
Lemma replacement_repl_closure_pq_helper_mutind: (forall q p T T',
repl_typ q p T T' ->
forall q0 r0 T2 G, repl_typ q0 r0 T' T2 ->
inert G ->
G ⊢! p: {{ q }} ⪼ {{ q }} ->
G ⊢! q0: {{ r0 }} ⪼ {{ r0 }} ->
T = T2 \/ exists T3, repl_typ q0 r0 T T3 /\ repl_typ q p T3 T2) /\
(forall q p D D',
repl_dec q p D D' ->
forall q0 r0 D2 G,
repl_dec q0 r0 D' D2 ->
inert G ->
G ⊢! p: {{ q }} ⪼ {{ q }} ->
G ⊢! q0: {{ r0 }} ⪼ {{ r0 }} ->
D = D2 \/ exists D3, repl_dec q0 r0 D D3 /\ repl_dec q p D3 D2).
Proof.
apply repl_mutind; intros; eauto.
- invert_repl. destruct (H _ _ _ _ H7 H1 H2 H3); subst; eauto.
right. destruct H0 as [D4 [Hl Hr]]. exists (typ_rcd D4). split; eauto.
- invert_repl.
* destruct (H _ _ _ _ H9 H1 H2 H3); subst; eauto.
right. destruct H0 as [T5 [Hl Hr]]. exists (T5 ∧ U). split; eauto.
* right. exists (T1 ∧ T4). split; auto.
- invert_repl.
* right. exists (T4 ∧ T1). split; auto.
* destruct (H _ _ _ _ H9 H1 H2 H3); subst; eauto.
destruct H0 as [T5 [Hl Hr]]. right. exists (U ∧ T5). split; auto.
- invert_repl. left. assert (p •• bs = r0 •• bs0).
eapply pf_sngl_sel_unique; eauto. rewrite H. auto.
- invert_repl. destruct (H _ _ _ _ H7 H1 H2 H3); subst; eauto.
right. destruct H0 as [T5 [Hl Hr]]. exists (μ T5). split; auto.
- invert_repl.
* destruct (H _ _ _ _ H9 H1 H2 H3); subst; eauto.
right. destruct H0 as [T5 [Hl Hr]]. exists (∀ (T5) U). split; auto.
* right. exists (∀ (T1) T4). split; auto.
- invert_repl.
* right. exists (∀ (T4) T1). split; auto.
* destruct (H _ _ _ _ H9 H1 H2 H3); subst; eauto.
right. destruct H0 as [T5 [Hl Hr]]. exists (∀ (U) T5). split; auto.
- invert_repl. left. assert (p •• bs = r0 •• bs0).
eapply pf_sngl_sel_unique; eauto. rewrite H. auto.
- invert_repl.
* destruct (H _ _ _ _ H10 H1 H2 H3); subst; eauto.
right. destruct H0 as [T4 [Hl Hr]]. exists (dec_typ A T4 U). split; auto.
* right. exists (dec_typ A T1 T3). split; auto.
- invert_repl.
* right. exists (dec_typ A T3 T1). split; auto.
* destruct (H _ _ _ _ H10 H1 H2 H3); subst; eauto.
right. destruct H0 as [T4 [Hl Hr]]. exists (dec_typ A U T4). split; auto.
- invert_repl. destruct (H _ _ _ _ H9 H1 H2 H3); subst; eauto.
right. destruct H0 as [T4 [Hl Hr]]. exists ({a ⦂ T4}). split; auto.
Qed.
Lemma replacement_repl_closure_pq_helper: forall p q T T',
repl_typ q p T T' ->
forall q0 r0 T2 G, repl_typ q0 r0 T' T2 ->
inert G ->
G ⊢! p: {{ q }} ⪼ {{ q }} ->
G ⊢! q0: {{ r0 }} ⪼ {{ r0 }} ->
T = T2 \/ exists T3, repl_typ q0 r0 T T3 /\ repl_typ q p T3 T2.
Proof.
destruct replacement_repl_closure_pq_helper_mutind; eauto.
Qed.
Lemma invertible_repl_closure_helper :
(forall D,
record_dec D -> forall G p q r D' U,
inert G ->
G ⊢!!! p: typ_rcd D ->
G ⊢! q : {{ r }} ⪼ {{ r }} ->
G ⊢!! r : U ->
repl_dec q r D D' ->
G ⊢// p: typ_rcd D') /\
(forall U ls,
record_typ U ls -> forall G p q r U' V,
inert G ->
G ⊢!!! p: U ->
G ⊢! q : {{ r }} ⪼ {{ r }} ->
G ⊢!! r : V ->
repl_typ q r U U' ->
G ⊢// p: U') /\
(forall U,
inert_typ U -> forall G p q r U' V,
inert G ->
G ⊢!!! p: U ->
G ⊢! q : {{ r }} ⪼ {{ r }} ->
G ⊢!! r : V ->
repl_typ q r U U' ->
G ⊢// p: U').
Proof.
apply rcd_mutind; intros; try solve [invert_repl; eauto].
- invert_repl; eapply ty_dec_typ_r. eapply ty_inv_r.
eapply ty_precise_inv. apply H0.
solve_repl_sub. eauto. solve_repl_sub. eauto. eauto.
- invert_repl. eapply ty_dec_trm_r. eapply ty_inv_r.
eapply ty_precise_inv. eauto. eauto.
- invert_repl. eapply ty_dec_trm_r. eapply ty_inv_r.
eapply ty_precise_inv. eauto. eauto.
- invert_repl; eapply ty_and_r. apply* H. apply* pt3_and_destruct1.
apply pt3_and_destruct2 in H2; auto.
apply pt3_and_destruct1 in H2; auto.
invert_repl. apply pt3_and_destruct2 in H2; auto. eauto.
- pose proof (typed_paths_named (precise_to_general H1)) as Ht.
invert_repl; eapply ty_all_r with (L:=dom G). eauto. apply repl_swap in H9. eauto.
introv Hy. eauto. eauto. eauto.
introv Hy.
pose proof (typed_paths_named (precise_to_general2 H2)) as Hs.
lets Ho: (repl_open_var y H9 Ht Hs). eapply weaken_subtyp. solve_repl_sub.
apply* ok_push.
Qed.
(** Singleton-subtyping closure for invertible typing:
If [Γ ⊢## p: T] and [Γ ⊢! q: r.type] then [Γ ⊢## p: T[r/q]] *)
Lemma invertible_repl_closure : forall G p q r T T' U,
inert G ->
G ⊢## p : T ->
G ⊢! q : {{ r }} ⪼ {{ r }} ->
G ⊢!! r : U ->
repl_typ q r T T' ->
G ⊢// p : T'.
Proof.
introv Hi Hp Hqr Hr Hrep. gen q r T' U.
induction Hp; introv Hq; introv Hrep; introv Hr'.
- Case "ty_precise_inv"%string.
destruct (pt3_inertsngl Hi H) as [[Hin | Hs] | Hr].
* inversions Hin.
** apply* invertible_repl_closure_helper.
** invert_repl. eauto.
* inversions Hs. invert_repl. eapply ty_inv_r. eapply ty_sngl_pq_inv; eauto.
* inversions Hr. eapply (proj32 invertible_repl_closure_helper); eauto.
- Case "ty_rec_pq_inv"%string.
invert_repl. eauto.
- Case "ty_sel_pq_inv"%string.
assert (exists r''', T' = r'''↓A) as [r''' Heq]. {
invert_repl. eauto.
} subst.
destruct (repl_prefixes_sel Hrep) as [bs0 [He1 He2]]. subst.
apply ty_inv_r.
apply ty_sel_pq_inv with (p:=q0) (U:=U0); auto.
rewrite <- He1; auto. eapply ty_sel_pq_inv; eauto.
- Case "ty_sngl_qp_inv"%string.
assert (exists r''', T' = {{ r'''}}) as [r''' Heq]. {
invert_repl. eauto.
} subst.
destruct (repl_prefixes_sngl Hrep) as [bs0 [He1 He2]]. subst.
apply ty_inv_r.
apply ty_sngl_pq_inv with (p:=q0) (U:=U0); auto.
rewrite <- He1; auto. eapply ty_sngl_pq_inv; eauto.
Qed.
(** Replacement typing is closed under [pq] replacement
when we know [q]'s precise type *)
Lemma replacement_repl_closure_pq : forall G p q r T T' U,
inert G ->
G ⊢// p : T ->
G ⊢! q : {{ r }} ⪼ {{ r }} ->
G ⊢!! r : U ->
repl_typ q r T T' ->
G ⊢// p : T'.
Proof.
introv Hi Hp Hq Hqr.
gen q r T' U. induction Hp; introv Hq; introv Hr' Hr; eauto.
- Case "ty_inv_r"%string.
apply* invertible_repl_closure.
- Case "ty_and_r"%string.
invert_repl; eauto.
- Case "ty_bnd_r"%string.
invert_repl. apply (repl_open p) in H2; try solve_names. eauto.
- Case "ty_sel_r"%string.
clear IHHp. invert_repl. lets Heq: (pf_sngl_flds_elim _ Hi Hq H). subst.
rewrite field_sel_nil in *.
lets Heq: (pf_T_unique Hi H Hq). subst.
apply pf_sngl_U in H. inversion H.
- Case "ty_rcd_intro_r"%string. invert_repl. eauto.
- Case "ty_rec_qp_r"%string.
invert_repl. specialize (IHHp Hi _ _ Hq).
destruct (replacement_repl_closure_pq_helper H1 H5 Hi H Hq).
* rewrite <- H2. auto.
* destruct H2 as [T3 [Hl Hr]].
assert (G ⊢// r : μ T3) by (eapply IHHp; eauto).
apply (ty_rec_qp_r H H0 H2 Hr).
- Case "ty_sel_pq_r"%string. invert_repl.
specialize (pf_sngl_sel_unique _ _ Hi H Hq H4) as Heq. rewrite <- Heq.
auto.
- Case "ty_sngl_pq_r"%string. invert_repl.
specialize (pf_sngl_sel_unique _ _ Hi H Hq H4) as Heq. rewrite <- Heq.
auto.
- Case "ty_top_r"%string. invert_repl.
- Case "ty_dec_trm_r"%string. invert_repl. eapply ty_dec_trm_r; eauto.
eapply subtyp_trans_t; eauto.
- Case "ty_dec_typ_r"%string. invert_repl; eapply ty_dec_typ_r; eauto.
* eapply subtyp_trans_t. apply repl_swap in H8. eapply subtyp_sngl_qp_t; eauto.
auto.
* eapply subtyp_trans_t; eauto.
- Case "ty_all_r"%string. invert_repl; eapply ty_all_r with (L:=L \u dom G); eauto.
* eapply subtyp_trans_t. apply repl_swap in H6. eapply subtyp_sngl_qp_t; eauto.
auto.
* introv Hy. eapply narrow_subtyping. apply H0. eauto.
constructor; auto. apply tight_to_general.
eapply subtyp_sngl_qp_t; eauto. apply repl_swap; auto.
* introv Hy. apply repl_swap in H6. eapply subtyp_trans.
+ apply H0. eauto.
+ eapply repl_open_var in H6; try solve_names.
eapply subtyp_sngl_pq. apply* weaken_ty_trm.
eapply precise_to_general. apply Hq.
apply* weaken_ty_trm. apply* precise_to_general2.
apply repl_swap in H6. eauto.
Qed.
(** Replacement typing is closed under [pq] replacement
when we know [q]'s II-level precise type *)
Lemma replacement_repl_closure_pq2 : forall G p q r T T' U,
inert G ->
G ⊢// p : T ->
G ⊢!! q : {{ r }} ->
G ⊢!! r : U ->
repl_typ q r T T' ->
G ⊢// p : T'.
Proof.
introv Hi Hp Hq Hr' Hr. gen U. dependent induction Hq; introv Hr'.
- apply* replacement_repl_closure_pq. lets Heq: (pf_sngl_T Hi H). subst. auto.
- pose proof (repl_field_elim _ _ _ Hr).
pose proof (pt2_backtrack _ _ Hr') as [U' Hq'].
specialize (IHHq1 _ Hi Hp eq_refl H _ Hq').
eauto.
Qed.
(** Replacement typing is closed under [pq] replacement
when we know [q]'s III-level precise type *)
Lemma replacement_repl_closure_pq3 : forall G p q r T T' U,
inert G ->
G ⊢// p : T ->
G ⊢!!! q : {{ r }} ->
G ⊢!! r : U ->
repl_typ q r T T' ->
G ⊢// p : T'.
Proof.
introv Hi Hp Hq Hr. gen p T U. dependent induction Hq; introv Hp; introv Hr' Hr.
- apply* replacement_repl_closure_pq2.
- destruct (repl_insert q Hr) as [U' [Hr1 Hr2]].
pose proof (pt2_exists Hq) as [S Hq'].
lets Hc: (replacement_repl_closure_pq2 Hi Hp H Hq' Hr1). apply* IHHq.
Qed.
(** Replacement typing is closed under repeated [pq] replacement *)
Lemma replacement_repl_closure_pq_comp: forall G p q r T T' U,
inert G ->
G ⊢// p: T ->
G ⊢!!! q: {{ r }} ->
G ⊢!! r : U ->
repl_repeat_typ q r T T' ->
G ⊢// p: T'.
Proof.
introv Hi Hp Hq Hr Hc. gen p. dependent induction Hc; introv Hp; eauto.
apply* IHHc. apply* replacement_repl_closure_pq3.
Qed.
(** Replacement typing is closed under opening of recursive types *)
Lemma repl_rec_intro: forall G p T,
inert G ->
G ⊢// p: μ T ->
G ⊢// p: open_typ_p p T.
Proof.
introv Hi Hp. dependent induction Hp; auto.
- Case "ty_inv_r"%string.
dependent induction H.
+ destruct (pt3_bnd Hi H) as [Hp | [q [U [Hp1 [Hq Hp2]]]]].
* eapply ty_inv_r. eapply ty_precise_inv. eauto.
* eapply replacement_repl_closure_qp_comp. auto. auto. apply* ty_inv_r.
apply Hp1. eauto. apply* repl_comp_open.
+ specialize (IHty_path_inv _ eq_refl Hi).
eapply replacement_repl_closure_pq; eauto.
apply* repl_open. all: solve_names.
- Case "ty_rec_pq_r"%string.
specialize (IHHp _ Hi eq_refl).
apply repl_open with (r:= r) in H1; try solve_names. apply* replacement_repl_closure_qp.
Qed.
(** Replacement typing is closed under [<:-Sel] subtyping when
we know that a path's II-level precise type has a type member *)
Lemma path_sel_repl2: forall G p A T q,
inert G ->
G ⊢!! p : typ_rcd {A >: T <: T} ->
G ⊢// q : T ->
G ⊢// q : p ↓ A.
Proof.
introv Hi Hp Hq. dependent induction Hp; eauto.
Qed.
(** Replacement typing is closed under [<:-Sel] subtyping when
we know that a path's III-level precise type has a type member *)
Lemma path_sel_repl: forall G p A T q,
inert G ->
G ⊢!!! p : typ_rcd {A >: T <: T} ->
G ⊢// q : T ->
G ⊢// q : p ↓ A.
Proof.
introv Hi Hp Hq. dependent induction Hp; eauto.
apply* path_sel_repl2.
specialize (IHHp _ _ Hi eq_refl Hq).
assert (forall q, q = q •• nil) as Hnil. {
intro. rewrite* field_sel_nil.
}
lets He1: (Hnil q0). lets He2: (Hnil p).
pose proof (pt2_exists Hp) as [U Hp0].
eapply (replacement_repl_closure_qp2 Hi H Hp0 IHHp).
rewrite He1 at 2. rewrite He2 at 2. apply rpath.
Qed.
(** Replacement typing is closed under [Sel-<:] subtyping *)
Lemma path_sel_repl_inv: forall G p A T q,
inert G ->
G ⊢!!! p : typ_rcd {A >: T <: T} ->
G ⊢// q : p ↓ A ->
G ⊢// q : T.
Proof.
introv Hi Hp Hq. dependent induction Hq.
- Case "ty_inv_r"%string.
constructor. apply* path_sel_inv.
- Case "ty_sel_r"%string.
clear IHHq. lets Heq: (pf_pt3_unique Hi H Hp). subst*.
- Case "ty_sel_qp_r"%string.
assert (record_type (typ_rcd {A >: T <: T})) as Hrt by eauto.
apply IHHq with (p := q •• bs) (A0 := A); eauto.
eapply pf_pt3_trans_inv_mult'; eauto.
Qed.
(** If a path has a replacement type it has also an invertible type *)
Lemma repl_to_inv G p T :
G ⊢// p : T ->
exists U, G ⊢## p : U.
Proof.
induction 1; eauto. destruct IHty_repl as [U Hp].
clear H. apply inv_backtrack in Hp. eauto.
Qed.
(** Replacement typing is closed under tight subtyping *)
Lemma replacement_subtyping_closure : forall G T U p,
inert G ->
G ⊢# T <: U ->
G ⊢// p: T ->
G ⊢// p: U.
Proof.
introv Hi Hs. gen p. induction Hs; introv Hp; eauto.
- Case "subtyp_bot"%string.
inversions Hp. false* invertible_bot.
- Case "subtyp_and1"%string.
apply (repl_and Hi) in Hp. destruct_all. auto.
- Case "subtyp_and2"%string.
apply (repl_and Hi) in Hp. destruct_all. auto.
- Case "subtyp_sngl_pq"%string.
pose proof (pt2_exists H0) as [? ?].
apply* replacement_repl_closure_pq3.
- Case "subtyp_sngl_qp"%string.
pose proof (pt2_exists H0) as [? ?].
apply* replacement_repl_closure_qp3.
- Case "subtyp_sel2"%string.
apply* path_sel_repl.
- Case "subtyp_sel1"%string.
apply* path_sel_repl_inv.
Qed.
(** If a path has a replacement type it also has a III-level precise type *)
Lemma repl_prec_exists: forall G p T,
G ⊢// p: T ->
exists U, G ⊢!!! p: U.
Proof.
introv Hp. apply repl_to_inv in Hp as [? Hp].
induction Hp; eauto.
Qed.
(** Replacement is closed under field selection on paths *)
Lemma repl_fld : forall G p a T,
inert G ->
G ⊢// p: typ_rcd {a ⦂ T} ->
G ⊢// p•a : T.
Proof.
introv Hi Hp. dependent induction Hp; eauto.
dependent induction H; eauto.
- dependent induction H.
* dependent induction H; eauto.
apply pf_fld in H; apply ty_inv_r; apply* ty_precise_inv.
* lets Hq: (pt3_field_elim H0).
lets Hp: (pt3_trans _ H Hq). eauto.
- specialize (IHHp _ _ Hi eq_refl).
eapply replacement_subtyping_closure; eauto.
Qed.
(** If [G ⊢// p: T] and [T] and [T'] are equivalent then [G ⊢// p: T'] *)
Lemma replacement_repl_closure_comp_typed: forall G p T T',
inert G ->
G ⊢// p: T ->
G ⊢ T' ⟿ T ->
G ⊢// p: T'.
Proof.
introv Hi Hp Hr. dependent induction Hr; eauto.
destruct H as [p' [q' [S [Hpq [Hq Hr']]]]].
lets Hrc: (replacement_repl_closure_qp Hi Hpq Hq Hp Hr'). eauto.
Qed.
(** From replacement typing of singleton types to invertible typing of singleton types *)
Lemma repl_to_invertible_sngl_repl_comp: forall G p q,
inert G ->
G ⊢// p: {{ q }} ->
exists q', G ⊢ q ⟿' q' /\ G ⊢## p: {{ q' }}.
Proof.
introv Hi Hp. dependent induction Hp.
- Case "ty_inv_r"%string.
exists q. split*. apply star_refl.
- Case "ty_sngl_qp_r"%string.
specialize (IHHp _ Hi eq_refl). destruct IHHp as [p' [Hr Hr']].
eexists. split*. eapply star_trans. apply Hr. apply star_one. repeat eexists; eauto.
Qed.
(** If a path [p] has type [q.type] under replacement typing and [q] is well-typed,
then the invertible type of [p] has a singleton type [q'.type], and [q] and [q']
are aliases. *)
Lemma repl_to_invertible_sngl: forall G p q U,
inert G ->
G ⊢// p: {{ q }} ->
G ⊢!! q : U ->
exists q' S, G ⊢## p: {{ q' }} /\ G ⊢!! q' : S /\ (q = q' \/ G ⊢!!! q: {{ q' }}).
Proof.
introv Hi Hp Hq. gen U. dependent induction Hp; introv Hq.
- repeat eexists; eauto.
- destruct (pt2_qbs_typed _ Hi H H0 Hq) as [T Hq0bs].
specialize (IHHp _ Hi eq_refl _ Hq0bs).
destruct IHHp as [q' [S [Hr [Hq' [Heq | Hq0']]]]]. subst.
+ exists (q0 •• bs) T. split; auto. split; auto. right.
eapply pt3_trans_trans; eauto.
+ exists q' S. split; auto. split; auto. right. eapply pt3_sngl_trans; eauto.
eapply pt2_field_trans; eauto.
Qed.
Lemma replacement_repl_closure_comp_typed_path: forall G p q q',
inert G ->
G ⊢// p: {{ q }} ->
G ⊢ q' ⟿' q ->
G ⊢// p: {{ q' }}.
Proof.
introv Hi Hp Hr. dependent induction Hr; eauto.
inversions H. apply IHHr. eapply ty_sngl_qp_r; eauto.
Qed.
(** If [p]'s replacement type is [q.type] and [q] is well-typed, then
[p.a]'s replacement type is [q.a.type] *)
Lemma path_elim_repl: forall G p q a T,
inert G ->
G ⊢// p: {{ q }} ->
G ⊢// q•a : T ->
G ⊢// p•a : {{ q•a }}.
Proof.
introv Hi Hp Hq.
destruct (repl_to_invertible_sngl_repl_comp Hi Hp) as [p' [Hc Hpi]].
destruct (inv_to_precise_sngl_repl_comp Hpi) as [r' [Hp' Hrc]].
destruct (repl_prec_exists Hq) as [U Hq']. clear Hq.
destruct (field_typing_comp1 _ Hi Hc Hq') as [T1 Hra].
destruct (field_typing_comp2 _ Hi Hrc Hra) as[T2 Hr'a].
lets Hper: (path_elim_prec _ Hi Hp' Hr'a).
lets Hinv: (ty_precise_inv Hper).
assert (G ⊢ r' • a ⟿' p' • a) as Hr'
by apply* repl_composition_fld_elim.
assert (G ⊢ q • a ⟿' p' • a) as Hr''
by apply* repl_composition_fld_elim.
lets Hic: (invertible_repl_closure_comp_typed Hi Hinv Hr').
apply* replacement_repl_closure_comp_typed_path.
Qed.
(** Replacement typing is closed under singleton transitivity with a type [q.type]
if [q] is typeable under invertible typing *)
Lemma inv_sngl_trans: forall G p q T,
inert G ->
G ⊢// p : {{ q }} ->
G ⊢## q : T ->
G ⊢// p : T.
Proof.
introv Hi Hpq Hq. gen p. induction Hq; introv Hpq; eauto; try solve [apply* replacement_repl_closure_pq].
- pose proof (pt2_exists H) as [U H'].
destruct (repl_to_invertible_sngl Hi Hpq H') as [r [S [Hpr [Hq Hrc]]]].
destruct (inv_to_precise_sngl Hi Hpr (pt3 Hq)) as [r' [Hpr' Hrc']]. clear Hpr Hpq H'.
destruct Hrc, Hrc'; subst.
* do 2 constructor. apply* pt3_sngl_trans3.
* do 2 constructor. repeat apply* pt3_sngl_trans3.
* lets Hpi: (pt3_invert Hi H H0). destruct_all; subst; auto.
** do 2 constructor. apply* pt3_sngl_trans3.
** apply ty_precise_inv in Hpr'. apply ty_inv_r in Hpr'.
apply* replacement_repl_closure_qp3. apply* repl_intro_sngl.
* lets Hpi: (pt3_invert Hi H H0). destruct_all; subst.
** do 2 constructor. do 2 apply* pt3_sngl_trans3.
** do 2 constructor. apply* pt3_sngl_trans3.
** apply ty_precise_inv in Hpr'. apply ty_inv_r in Hpr'.
lets Hc: (replacement_repl_closure_pq3 Hi Hpr' H1 Hq (repl_intro_sngl r' r)).
apply* replacement_repl_closure_qp3. apply* repl_intro_sngl.
Qed.
(** Replacement typing is closed under singleton transitivity *)
Lemma repl_sngl_trans: forall G p q T,
inert G ->
G ⊢// p : {{ q }} ->
G ⊢// q : T ->
G ⊢// p : T.
Proof.
introv Hi Hpq Hq. gen p. induction Hq; introv Hpq; eauto.
- apply* inv_sngl_trans.
- specialize (IHHq Hi _ Hpq). apply ty_bnd_r.
pose proof (repl_to_inv Hq) as [_ [_ [U Hq']%pt2_exists]%inv_to_prec].
destruct (repl_to_invertible_sngl Hi Hpq Hq') as [r [S [Hpr [Hs Hor]]]].
destruct (inv_to_precise_sngl Hi Hpr (pt3 Hs)) as [r' [Hpr' Hor']]. clear Hpr Hpq.
destruct Hor, Hor'; subst.
* assert (repl_repeat_typ r p0 (open_typ_p r T) (open_typ_p p0 T)) as Hrr by apply* repl_comp_open_rec.
apply* replacement_repl_closure_qp_comp.
* assert (repl_repeat_typ r r' (open_typ_p r T) (open_typ_p r' T)) as Hrr by apply* repl_comp_open_rec.
lets Hc: (replacement_repl_closure_qp_comp Hi IHHq H0 Hs Hrr).
apply pt2_exists in H0 as [? ?].
eapply (replacement_repl_closure_qp_comp Hi Hc). apply Hpr'. eauto.
apply* repl_comp_open_rec.
* assert (repl_repeat_typ p r (open_typ_p p T) (open_typ_p r T)) as Hrr by apply* repl_comp_open_rec.
lets Hc: (replacement_repl_closure_pq_comp Hi IHHq H Hs Hrr).
apply* replacement_repl_closure_qp_comp. apply* repl_comp_open_rec.
* assert (repl_repeat_typ p r (open_typ_p p T) (open_typ_p r T)) as Hrr by apply* repl_comp_open_rec.
lets Hc: (replacement_repl_closure_pq_comp Hi IHHq H Hs Hrr).
assert (repl_repeat_typ r r' (open_typ_p r T) (open_typ_p r' T)) as Hrr' by apply* repl_comp_open_rec.
lets Hc': (replacement_repl_closure_qp_comp Hi Hc H0 Hs Hrr').
pose proof (pt2_exists H0) as [? ?].
eapply (replacement_repl_closure_qp_comp Hi). auto. apply Hc'. apply Hpr'. eauto. apply* repl_comp_open_rec.
- pose proof (path_elim_repl _ Hi Hpq Hq) as Hp0a. specialize (IHHq Hi _ Hp0a). eauto.
Qed.
(** Tight typing implies replacement typing *)
Lemma replacement_closure : forall G p T,
inert G ->
G ⊢# trm_path p : T ->
G ⊢// p: T.
Proof.
introv Hi Hp. dependent induction Hp; eauto.
- Case "ty_var_t"%string.
repeat econstructor; eauto.
- Case "ty_new_elim_t"%string.
apply* repl_fld.
- Case "ty_sngl_t"%string.
apply* repl_sngl_trans.
- Case "ty_path_elim_t"%string.
apply* path_elim_repl.
- Case "ty_rec_elim_t"%string.
specialize (IHHp _ Hi eq_refl). apply* repl_rec_intro.
- Case "ty_sub_t"%string.
specialize (IHHp _ Hi eq_refl).
eapply replacement_subtyping_closure; eauto.
Qed.
(** ** Replacement typing for values
The definition of replacement typing for values
is similar to replacement typing for paths, but simpler. The same holds for
its lemmas. To see the documentation for a replacement-typing-for-values lemma,
please refer to its replacement-typing-for-paths version. *)
Reserved Notation "G '⊢//v' v ':' T" (at level 40, v at level 59).
Inductive ty_replv : ctx -> val -> typ -> Prop :=
| ty_inv_rv : forall G v T,
G ⊢##v v: T ->
G ⊢//v v: T
| ty_and_rv : forall G v T U,
G ⊢//v v: T ->
G ⊢//v v: U ->
G ⊢//v v: T ∧ U
| ty_sel_rv : forall G v T q S A,
G ⊢//v v: T ->
G ⊢! q: S ⪼ typ_rcd {A >: T <: T} ->
G ⊢//v v: q ↓ A
| ty_rec_qp_rv : forall G p q v T T' U,
G ⊢! p : {{ q }} ⪼ {{ q }} ->
G ⊢!! q : U ->
G ⊢//v v : μ T ->
repl_typ q p T T' ->
G ⊢//v v : μ T'
| ty_sel_qp_rv : forall G p q v r' r'' A U,
G ⊢! p : {{ q }} ⪼ {{ q }} ->
G ⊢!! q : U ->
G ⊢//v v : r' ↓ A ->
repl_typ q p (r' ↓ A) (r'' ↓ A) ->
G ⊢//v v : r''↓A
(** [G ⊢## p: T] #<br>#
[―――――――――――――] #<br>#
[G ⊢## p: top] *)
| ty_top_rv : forall G v T,
G ⊢//v v : T ->
G ⊢//v v : ⊤
| ty_all_rv : forall G T1 T2 S1 S2 L v,
G ⊢//v v : ∀(S1) T1 ->
G ⊢# S2 <: S1 ->
(forall y, y \notin L ->
G & y ~ S2 ⊢ open_typ y T1 <: open_typ y T2) ->
G ⊢//v v : ∀(S2) T2
where "G '⊢//v' v ':' T" := (ty_replv G v T).
Hint Constructors ty_replv.
Lemma invertible_andv: forall G v T U,
inert G ->
G ⊢##v v: T ∧ U ->
G ⊢##v v: T /\ G ⊢##v v: U.
Proof.
introv Hi Hp. dependent induction Hp; eauto. inversion H.
Qed.
Lemma repl_andv: forall G v T U,
inert G ->
G ⊢//v v: T ∧ U ->
G ⊢//v v: T /\ G ⊢//v v: U.
Proof.
introv Hi Hv. dependent induction Hv; eauto.
destruct (invertible_andv Hi H). split*.
Qed.
Lemma replacement_repl_closure_qp_v G v p q T T' U :
inert G ->
G ⊢! p : {{ q }} ⪼ {{ q }} ->
G ⊢!! q : U ->
G ⊢//v v : T ->
repl_typ q p T T' ->
G ⊢//v v : T'.
Proof.
intros Hi Hpq Hq Hv.
gen p q T' U. induction Hv; introv Hpq; introv Hq Hr.
- Case "ty_inv_rv"%string.
gen p q T' U. induction H; introv Hpq; introv Hr; introv Hq;
try solve [invert_repl; eauto].
-- destruct (pfv_inert H).
+ invert_repl.
++ eapply ty_all_rv with (L := \{}).
eapply ty_inv_rv.
eapply ty_precise_invv. apply H.
apply repl_swap in H5.
eauto.
introv Hy. auto.
++ eapply ty_all_rv with (L := dom G).