-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRedSubProps.v
More file actions
492 lines (446 loc) · 17.5 KB
/
RedSubProps.v
File metadata and controls
492 lines (446 loc) · 17.5 KB
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
(* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *)
(* MiniJl:
Decidable, Tag-Based Semantic Subtyping
for Nominal Types, Pairs, and Unions. *)
(** * MiniJl: Propositions about Reductive Subtyping *)
(* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *)
Add LoadPath "../..". (* root directory of the repo *)
Require Import Mechanization.Aux.Identifier.
Require Import Mechanization.MiniJl.BaseDefs.
Require Import Mechanization.MiniJl.BaseProps.
Require Import Mechanization.MiniJl.MatchProps.
Require Import Coq.Lists.List.
Import ListNotations.
Require Import Coq.Arith.Arith.
Require Import Coq.Bool.Bool.
Close Scope btj_scope.
Open Scope btjm_scope.
Open Scope btjnf_scope.
Open Scope btjr_scope.
(* ################################################################# *)
(** ** Auxiliary Statements *)
(* ################################################################# *)
(* ================================================================= *)
(** *** Union of Normal Form *)
(* ================================================================= *)
(* DEP: mk_nf_nf__equal *)
Lemma union_nf_sub_r__components_sub_r : forall (t1 t2 t' : ty),
|- TUnion t1 t2 << t' ->
InNF(t1) -> InNF(t2) ->
|- t1 << t' /\ |- t2 << t'.
Proof.
intros t1 t2 t' H. remember (TUnion t1 t2) as t eqn:Heq.
induction H; intros Hnf1 Hnf2; try solve [inversion Heq].
- (* UnionL *)
inversion Heq; subst. split; assumption.
- (* UnionR1 *)
inversion Heq; subst. specialize (IHsub_r H0).
split; (apply SR_UnionR1 || apply SR_UnionR2); tauto.
- (* UnionR2 *)
inversion Heq; subst. specialize (IHsub_r H0).
split; (apply SR_UnionR2 || apply SR_UnionR2); tauto.
- (* NF *)
subst. simpl in *. apply IHsub_r; try assumption.
rewrite (mk_nf_nf__equal _ Hnf1).
rewrite (mk_nf_nf__equal _ Hnf2).
reflexivity.
Qed.
(* ================================================================= *)
(** *** About [unite_pairs] *)
(* ================================================================= *)
(* DEP: sub_r__rflxv, unite_pairs_t_union, unite_pairs_union_t,
union_in_nf__components_in_nf,
mk_nf_nf__equal, mk_nf__in_nf *)
Lemma unite_pairs_of_nf__preserves_sub_r : forall (t1 t2 t1' t2' : ty),
|- t1 << t1' ->
|- t2 << t2' ->
InNF(t1) -> InNF(t1') ->
InNF(t2) -> InNF(t2') ->
|- unite_pairs t1 t2 << unite_pairs t1' t2'.
Proof.
intros ta tb ta' tb' Hsub1.
generalize dependent tb'. generalize dependent tb.
induction Hsub1; intros tb tb' Hsub2;
try solve [
induction Hsub2; intros Hnfa Hnfa' Hnfb Hnfb';
try solve [
simpl; constructor; constructor; assumption
(* UnionL *)
| rewrite unite_pairs_t_union; try resolve_not_union;
destruct (union_in_nf__components_in_nf _ _ Hnfb) as [Hnfb1 Hnfb2];
constructor; [apply IHHsub2_1 | apply IHHsub2_2];
assumption || constructor
(* UnionR1 *)
| rewrite unite_pairs_t_union; try resolve_not_union;
destruct (union_in_nf__components_in_nf _ _ Hnfb') as [Hnfb1 Hnfb2];
apply SR_UnionR1; apply IHHsub2; assumption || constructor
(* UnionR2 *)
| rewrite unite_pairs_t_union; try resolve_not_union;
destruct (union_in_nf__components_in_nf _ _ Hnfb') as [Hnfb1 Hnfb2];
apply SR_UnionR2; apply IHHsub2; assumption || constructor
(* NF *)
| rewrite <- (mk_nf_nf__equal _ Hnfb);
apply IHHsub2; try assumption; apply mk_nf__in_nf ]
].
- (* UnionL, tb *)
intros Hnfa Hnfa' Hnfb Hnfb'. rewrite unite_pairs_union_t.
destruct (union_in_nf__components_in_nf _ _ Hnfa) as [Hnfa1 Hnfa2].
constructor; [apply IHHsub1_1 | apply IHHsub1_2]; assumption.
- (* UnionR1, tb *)
intros Hnfa Hnfa' Hnfb Hnfb'. rewrite unite_pairs_union_t.
destruct (union_in_nf__components_in_nf _ _ Hnfa') as [Hnfa1 Hnfa2].
apply SR_UnionR1; apply IHHsub1; assumption.
- (* UnionR2, tb *)
intros Hnfa Hnfa' Hnfb Hnfb'. rewrite unite_pairs_union_t.
destruct (union_in_nf__components_in_nf _ _ Hnfa') as [Hnfa1 Hnfa2].
apply SR_UnionR2; apply IHHsub1; assumption.
- (* NF, tb *)
intros Hnfa Hnfa' Hnfb Hnfb'.
rewrite <- (mk_nf_nf__equal _ Hnfa).
apply IHHsub1; try assumption. apply mk_nf__in_nf.
Qed.
(* DEP: unite_pairs_t_union, unite_pairs_union_t,
union_in_nf__components_in_nf, union_nf_sub_r__components_sub_r *)
Lemma unite_pairs_of_nf__preserves_sub_r1 : forall (t1 t2 t1' t2' : ty),
InNF(t1) -> |- t1 << t1' ->
InNF(t2) -> |- t2 << t2' ->
|- unite_pairs t1 t2 << TPair t1' t2'.
Proof.
intros ta; induction ta;
intros tb; induction tb;
intros ta' tb' Hnf1 Hsub1 Hnf2 Hsub2;
try solve [
simpl; constructor; assumption
| match goal with
| [Hnf1: InNF(?t), Hnf2: InNF(TUnion ?t1 ?t2),
Hsub: |- TUnion ?t1 ?t2 << _
|- |- unite_pairs ?t (TUnion ?t1 ?t2) << TPair _ _] =>
rewrite unite_pairs_t_union; try resolve_not_union;
destruct (union_in_nf__components_in_nf _ _ Hnf2) as [Hnfb1 Hnfb2];
destruct (union_nf_sub_r__components_sub_r _ _ _ Hsub Hnfb1 Hnfb2) as [Hsubb1 Hsubb2];
constructor; [apply IHtb1 | apply IHtb2]; assumption
| [Hnf1: InNF(?t), Hnf2: InNF(TUnion ?t1 ?t2),
Hsub: |- TUnion ?t1 ?t2 << _
|- |- unite_pairs (TUnion ?t1 ?t2) ?t << TPair _ _] =>
rewrite unite_pairs_union_t;
destruct (union_in_nf__components_in_nf _ _ Hnf2) as [Hnfb1 Hnfb2];
destruct (union_nf_sub_r__components_sub_r _ _ _ Hsub Hnfb1 Hnfb2) as [Hsubb1 Hsubb2];
constructor; [apply IHta1 | apply IHta2]; assumption
end
].
Qed.
(* ================================================================= *)
(** *** About [MkNF] *)
(* ================================================================= *)
(* DEP: unite_pairs_of_nf__preserves_sub_r1 *)
Lemma sub_r__mk_nf_sub_r1 : forall (t t' : ty),
|- t << t' ->
|- MkNF(t) << t'.
Proof.
intros t t' Hsub; induction Hsub;
try solve [simpl; constructor; constructor].
- (* Pair *)
simpl.
apply unite_pairs_of_nf__preserves_sub_r1;
assumption || apply mk_nf__in_nf.
- (* Union *)
simpl. constructor; assumption.
- (* UnionR1 *)
apply SR_UnionR1; assumption.
- (* UnionR2 *)
apply SR_UnionR2; assumption.
- (* NF *)
assumption.
Qed.
(* DEP: unite_pairs_of_nf__preserves_sub_r1, mk_nf__in_nf *)
Lemma mk_nf__sub_r1 : forall (t : ty),
|- MkNF(t) << t.
Proof.
intros t.
apply sub_r__mk_nf_sub_r1.
apply sub_r__rflxv.
Qed.
Lemma mk_nf__sub_r2 : forall (t : ty),
|- t << MkNF(t).
Proof.
intros t.
apply SR_NormalForm.
apply sub_r__rflxv.
Qed.
(* ================================================================= *)
(** *** Related to Transitivity *)
(* ================================================================= *)
(* DEP: sub_r__mk_nf_sub_r1, union_nf_sub_r__components_sub_r *)
Lemma union_sub_r__components_sub_r : forall (t1 t2 t' : ty),
|- TUnion t1 t2 << t' ->
|- t1 << t' /\ |- t2 << t'.
Proof.
intros t1 t2 t' Hsub.
pose proof (sub_r__mk_nf_sub_r1 _ _ Hsub).
simpl in H.
assert (Hsubnf: |- MkNF(t1) << t' /\ |- MkNF(t2) << t').
{ apply union_nf_sub_r__components_sub_r;
assumption || apply mk_nf__in_nf. }
split; apply SR_NormalForm; tauto.
Qed.
(* DEP: sub_r_value_types__equal, union_in_nf__components_in_nf,
mk_nf_nf__equal *)
Lemma sub_r_nf__transitive : forall (t1 t2 t3 : ty),
|- t1 << t2 ->
InNF(t1) -> InNF(t2) ->
|- t2 << t3 ->
|- t1 << t3.
Proof.
intros t1 t2 t3 Hsub1. generalize dependent t3.
induction Hsub1; intros t3 Hnf1 Hnf2 Hsub2;
try solve [
assumption
| inversion Hnf2; subst;
match goal with [H: value_type _ |- _] => inversion H end
].
- (* Pair *)
inversion Hnf1; subst. inversion Hnf2; subst.
inversion H; inversion H0; subst.
pose proof (sub_r_value_types__equal _ _ Hsub1_1 H3 H7).
pose proof (sub_r_value_types__equal _ _ Hsub1_2 H4 H8).
subst. assumption.
- (* UnionL *)
destruct (union_in_nf__components_in_nf _ _ Hnf1) as [Hnfa1 Hnfa2].
constructor; [apply IHHsub1_1 | apply IHHsub1_2]; assumption.
- (* UnionR1 *)
destruct (union_in_nf__components_in_nf _ _ Hnf2) as [Hnfa1 Hnfa2].
apply IHHsub1; try assumption.
pose proof (union_nf_sub_r__components_sub_r _ _ _ Hsub2 Hnfa1 Hnfa2); tauto.
- (* UnionR2 *)
destruct (union_in_nf__components_in_nf _ _ Hnf2) as [Hnfa1 Hnfa2].
apply IHHsub1; try assumption.
pose proof (union_nf_sub_r__components_sub_r _ _ _ Hsub2 Hnfa1 Hnfa2); tauto.
- (* NF *)
rewrite mk_nf_nf__equal in IHHsub1; try assumption.
apply IHHsub1; assumption.
Qed.
(* ################################################################# *)
(** ** Properties related to matching *)
(* ################################################################# *)
(* ================================================================= *)
(** *** Correctness of Subtyping with respect to Matching *)
(* ================================================================= *)
Theorem match_ty__sub_r_sound : forall (v t : ty),
|- v <$ t ->
|- v << t.
Proof.
intros v t H; induction H; try solve [constructor].
(* Pair *) constructor; assumption.
(* Union1 *) apply SR_UnionR1; assumption.
(* Union2 *) apply SR_UnionR2; assumption.
Qed.
(* ================================================================= *)
(** ** Matching value Type is Complete for Subtyping *)
(* ================================================================= *)
(* DEP: match_valty__rflxv, mk_nf_valty__equal *)
Theorem match_valty__sub_r_complete : forall (v t : ty),
|- v << t ->
value_type v ->
|- v <$ t.
Proof.
intros v t H; induction H; subst; intros Hval;
try solve [constructor | inversion Hval].
- (* Pair *)
inversion Hval; subst.
constructor; tauto.
- (* UnionR1 *)
apply MT_Union1; tauto.
- (* UnionR2 *)
apply MT_Union2; tauto.
- (* NF *)
rewrite (mk_nf_valty__equal _ Hval) in *.
tauto.
Qed.
(* ################################################################# *)
(** ** Properties related to Normal Form *)
(* ################################################################# *)
(** If types are subtypes, their normal forms are also subtypes. *)
(* DEP: unite_pairs_of_nf__preserves_sub_r,
mk_nf__in_nf, mk_nf__idempotent *)
Lemma sub_r__mk_nf_sub_r : forall (t t' : ty),
|- t << t' ->
|- MkNF(t) << MkNF(t').
Proof.
intros t t' Hsub; induction Hsub;
try solve [simpl; do 4 constructor].
- (* Pair *)
simpl.
apply unite_pairs_of_nf__preserves_sub_r;
assumption || apply mk_nf__in_nf.
- (* Union *)
simpl. constructor; assumption.
- (* UnionR1 *)
apply SR_UnionR1; assumption.
- (* UnionR2 *)
apply SR_UnionR2; assumption.
- (* NF *)
rewrite <- mk_nf__idempotent. assumption.
Qed.
(* DEP: mk_nf__in_nf *)
Lemma mk_nf_sub_r__sub_r : forall (t t' : ty),
|- MkNF(t) << MkNF(t') ->
|- t << t'.
Proof.
intros t t' Hsub.
apply SR_NormalForm.
apply sub_r_nf__transitive with (MkNF(t')); try (apply mk_nf__in_nf).
assumption. apply mk_nf__sub_r1.
Qed.
(* DEP: match_ty__sub_r_sound, match_valty__rflxv *)
Theorem nf_sem_sub__sub_r : forall (t : ty),
InNF(t) ->
forall (t' : ty),
||- [t] <= [t'] ->
|- t << t'.
Proof.
intros t Hnf; induction Hnf; intros t' Hval;
unfold sem_sub.
- (* Value *)
apply match_ty__sub_r_sound. apply Hval.
assumption. apply match_valty__rflxv. assumption.
- (* Union *)
constructor; [apply IHHnf1 | apply IHHnf2]; intros v Hv Hsub;
try assumption; apply Hval; try assumption.
apply MT_Union1; assumption.
apply MT_Union2; assumption.
Qed.
(* ################################################################# *)
(** ** Properties related to Declarative Subtyping *)
(* ################################################################# *)
(* ================================================================= *)
(** *** Reflexivity *)
(* ================================================================= *)
(* DEP: sub_r__rflxv *)
Lemma sub_r__reflexive : forall (t : ty),
|- t << t.
Proof.
apply sub_r__rflxv.
Qed.
(* ================================================================= *)
(** *** Transitivity *)
(* ================================================================= *)
(* DEP: sub_r__mk_nf_sub_r, sub_r_nf__transitive,
mk_nf__in_nf, union_sub_r__components_sub_r *)
Lemma sub_r__transitive : forall (t1 t2 t3 : ty),
|- t1 << t2 ->
|- t2 << t3 ->
|- t1 << t3.
Proof.
intros t1 t2 t3 Hsub1. generalize dependent t3.
induction Hsub1; intros t3 Hsub2;
try (apply sub_r__mk_nf_sub_r1 in Hsub2; simpl in Hsub2;
destruct (union_sub_r__components_sub_r _ _ _ Hsub2) as [Hsub21 Hsub22]);
try (destruct (union_sub_r__components_sub_r _ _ _ Hsub21));
try auto.
(* Pair *)
remember (TPair t1' t2') as tm eqn:Heq.
induction Hsub2; try solve [inversion Heq].
- (* Pair *)
inversion Heq; subst.
constructor; auto.
- (* UnionR1 *)
apply SR_UnionR1; tauto.
- (* UnionR2 *)
apply SR_UnionR2; tauto.
- (* NF *)
inversion Heq; subst. clear H.
assert (Hsub1: |- TPair t1 t2 << TPair t1' t2') by (constructor; assumption).
pose proof (sub_r__mk_nf_sub_r _ _ Hsub1) as Hsub1nf.
apply SR_NormalForm.
apply sub_r_nf__transitive with (MkNF( TPair t1' t2'));
assumption || apply mk_nf__in_nf.
Qed.
(* ================================================================= *)
(** *** Distributivity *)
(* ================================================================= *)
(* ----------------------------------------------------------------- *)
(** **** Aux *)
(* ----------------------------------------------------------------- *)
(* DEP: unite_pairs_t_union, unite_pairs_union_t,
sub_r__reflexive, sub_r__transitive *)
Lemma unite_pairs__distr21 : forall (t1 t21 t22 : ty),
InNF(t1) ->
|- unite_pairs t1 (TUnion t21 t22) <<
TUnion (unite_pairs t1 t21) (unite_pairs t1 t22).
Proof.
intros t1 t21 t22 Hnf1.
generalize dependent t22. generalize dependent t21.
induction Hnf1; intros t21 t22.
- (* Value *)
rewrite unite_pairs_t_union; try resolve_not_union.
apply sub_r__reflexive. subst; inversion H.
- (* Union *)
repeat rewrite unite_pairs_union_t.
constructor.
+ apply sub_r__transitive with (TUnion (unite_pairs t1 t21) (unite_pairs t1 t22)).
apply IHHnf1_1. constructor.
apply SR_UnionR1; apply SR_UnionR1; apply sub_r__reflexive.
apply SR_UnionR2; apply SR_UnionR1; apply sub_r__reflexive.
+ apply sub_r__transitive with (TUnion (unite_pairs t2 t21) (unite_pairs t2 t22)).
apply IHHnf1_2. constructor.
apply SR_UnionR1; apply SR_UnionR2; apply sub_r__reflexive.
apply SR_UnionR2; apply SR_UnionR2; apply sub_r__reflexive.
Qed.
(* ----------------------------------------------------------------- *)
(** **** Main Properties *)
(* ----------------------------------------------------------------- *)
(* DEP: unite_pairs_union_t, sub_r__reflexive *)
Lemma mk_nf__distr11 : forall (t11 t12 t2 : ty),
|- MkNF(TPair (TUnion t11 t12) t2) << MkNF(TUnion (TPair t11 t2) (TPair t12 t2)).
Proof.
intros t11 t12 t2.
change (|- MkNF( TPair (TUnion t11 t12) t2) << TUnion (MkNF(TPair t11 t2)) (MkNF(TPair t12 t2))).
change (|- unite_pairs (MkNF(TUnion t11 t12)) (MkNF(t2)) <<
TUnion (MkNF(TPair t11 t2)) (MkNF(TPair t12 t2))).
change (|- unite_pairs (TUnion (MkNF(t11)) (MkNF(t12))) (MkNF(t2)) <<
TUnion (MkNF(TPair t11 t2)) (MkNF(TPair t12 t2))).
rewrite unite_pairs_union_t.
apply sub_r__reflexive.
Qed.
(* DEP: unite_pairs__distr21, mk_nf__in_nf *)
Lemma mk_nf__distr21 : forall (t1 t21 t22 : ty),
|- MkNF(TPair t1 (TUnion t21 t22)) << MkNF(TUnion (TPair t1 t21) (TPair t1 t22)).
Proof.
intros t1 t21 t22.
change (|- MkNF(TPair t1 (TUnion t21 t22)) << TUnion (MkNF(TPair t1 t21)) (MkNF(TPair t1 t22))).
change (|- unite_pairs (MkNF(t1)) (TUnion (MkNF(t21)) (MkNF(t22))) <<
TUnion (MkNF(TPair t1 t21)) (MkNF(TPair t1 t22))).
change (|- unite_pairs (MkNF(t1)) (TUnion (MkNF(t21)) (MkNF(t22))) <<
TUnion (unite_pairs (MkNF(t1)) (MkNF(t21))) (unite_pairs (MkNF(t1)) (MkNF(t22)))).
apply unite_pairs__distr21.
apply mk_nf__in_nf.
Qed.
(* ################################################################# *)
(** ** Decidability *)
(* ################################################################# *)
(** Reductive subtyping of a normalized term on the left
is decidable. *)
(* DEP: match_ty__dcdbl, match_ty__sub_r_sound *)
Lemma nf_sub_r__decidable : forall (t1 t2 : ty),
InNF(t1) ->
Decidable.decidable (|- t1 << t2).
Proof.
intros t1 t2 Hnf1. generalize dependent t2.
induction Hnf1.
- (* Value *)
intros t2. destruct (match_ty__dcdbl v t2) as [Hm | Hm].
+ left. apply match_ty__sub_r_sound. assumption.
+ right; intros Hcontra.
assert (Hcontra': |- v <$ t2)
by (apply match_valty__sub_r_complete; assumption).
contradiction.
- (* Union *)
intros t'.
destruct (IHHnf1_1 t') as [IH1 | IH1];
destruct (IHHnf1_2 t') as [IH2 | IH2];
try solve [
right; intros Hcontra;
destruct (union_sub_r__components_sub_r _ _ _ Hcontra) as [Hsub1 Hsub2];
contradiction ].
left; constructor; assumption.
Qed.