-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEquation_C.v
2022 lines (1859 loc) · 75.8 KB
/
Equation_C.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
Require Import Arith Metatheory.
Require Import LibTactics LambdaES_Defs Rewriting.
Require Import LambdaES_FV LambdaES_Infra LambdaES_Tac.
Require Export Morphisms.
Instance iff_eq : Equivalence iff.
Proof.
split; intros_all.
split; trivial.
split; apply H.
split. intro H1. apply H0. apply H; trivial.
intro H1. apply H. apply H0; trivial.
Qed.
Inductive eqc : pterm -> pterm -> Prop :=
| eqc_def: forall t u v, term u -> term v -> eqc (t[u][v]) ((& t)[v][u]).
Lemma eqc_sym : forall t u, eqc t u -> eqc u t.
Proof.
intros_all. inversion H; subst; clear H.
replace t0 with (&(& t0)) at 2.
apply eqc_def; assumption. apply bswap_idemp.
Qed.
Lemma eqc_bvar_term : forall x t, eqc (pterm_bvar x) t -> pterm_bvar x = t.
Proof.
introv H; inversion H.
Qed.
Lemma eqc_fvar_term : forall x t, eqc (pterm_fvar x) t -> pterm_fvar x = t.
Proof.
introv H; inversion H.
Qed.
Lemma eqc_app_term : forall t u v, eqc (pterm_app u v) t -> pterm_app u v = t.
Proof.
intros t u v H; inversion H.
Qed.
Lemma eqc_abs_term : forall t t', eqc (pterm_abs t) t' -> pterm_abs t = t' .
Proof.
intros t t' H; inversion H.
Qed.
Lemma eqc_wregular: red_wregular eqc.
Proof.
unfold red_wregular. intros_all.
apply term_to_term' in H.
apply term'_to_term. unfold term' in *.
induction H0. simpl in *. destruct H as [ [ Ht Hu ] Hv]. split.
- split.
+ apply lc_at_bswap; [auto | assumption].
+ apply lc_at_weaken_ind with 0; [assumption | auto].
- apply term_to_term' in H0. assumption.
Qed.
Lemma red_out_eqc : red_out eqc.
Proof.
introv Hterm Heqc. destruct Heqc; simpl.
assert (Heqc:([x ~> u](& t)) = & ([x ~> u]t)).
{ rewrite (subst_bswap_rec 0). reflexivity.
rewrite <- term_eq_term'; trivial. }
rewrite Heqc. apply eqc_def.
apply subst_term; assumption.
apply subst_term; assumption.
Qed.
Lemma red_rename_eqc : red_rename eqc.
Proof.
intros_all.
rewrite* (@subst_intro x t).
rewrite* (@subst_intro x t').
apply red_out_eqc; trivial.
Qed.
Lemma eqc_open: forall n t u v, eqc t u -> eqc ({n ~> v}t) ({n ~> v}u).
Proof.
intros_all. gen n v. induction H.
intros n v'. unfold bswap. simpl. rewrite <- bswap_open_rec.
change (bswap_rec 0 ({(S (S n)) ~> v'}t)) with (& ({(S(S n)) ~> v'}t)).
assert (Hun: {n ~> v'}u = u).
{ rewrite <- open_rec_term; [ reflexivity | assumption ]. }
assert (HuSn: {(S n) ~> v'}u = u).
{ rewrite <- open_rec_term; [ reflexivity | assumption ]. }
assert (Hvn: {n ~> v'}v = v).
{ rewrite <- open_rec_term; [ reflexivity | assumption ]. }
assert (HvSn: {(S n) ~> v'}v = v).
{ rewrite <- open_rec_term; [ reflexivity | assumption ]. }
rewrite Hun. rewrite HuSn. rewrite Hvn. rewrite HvSn.
apply eqc_def. auto. auto. auto. auto.
Qed.
(** =c: the contextual closure of eqc. *)
Definition eqc_ctx (t u: pterm) := ES_contextual_closure eqc t u.
Notation "t =c u" := (eqc_ctx t u) (at level 66).
(** Compatibility of =c with the structure of terms. *)
Lemma ESctx_eqc_bvar : forall x t, (pterm_bvar x) =c t -> pterm_bvar x = t.
Proof.
intros x t H. inversion H. inversion H0; trivial.
Qed.
Lemma ESctx_eqc_fvar : forall x t, (pterm_fvar x) =c t -> pterm_fvar x = t.
Proof.
intros x t H. inversion H. inversion H0; trivial.
Qed.
Lemma ESctx_eqc_sym : forall t u, t =c u -> u =c t.
Proof.
introv H. induction H. apply ES_redex. apply eqc_sym; assumption.
apply ES_app_left; assumption.
apply ES_app_right; assumption.
apply ES_abs_in with L; assumption.
apply ES_subst_left with L; assumption.
apply ES_subst_right; assumption.
Qed.
Lemma ESctx_eqc_app_term : forall t u v, (pterm_app u v) =c t -> exists u' v', t = pterm_app u' v'.
Proof.
introv H. inversion H; subst.
- inversion H0.
- exists t' v. reflexivity.
- exists u u'. reflexivity.
Qed.
Lemma ESctx_eqc_app_one_step : forall t u v, (pterm_app u v) =c t -> exists u' v', t = pterm_app u' v' /\ (u =c u' \/ v =c v').
Proof.
introv H. remember (pterm_app u v) as t'. induction H.
- rewrite Heqt' in H. inversion H.
- inversion Heqt'; subst.
exists t' v. split.
+ reflexivity.
+ left. assumption.
- inversion Heqt'; subst.
exists u u'. split.
+ reflexivity.
+ right. assumption.
- inversion Heqt'.
- inversion Heqt'.
- inversion Heqt'.
Qed.
Lemma eqc_ctx_open: forall x t u, t =c u -> t^x =c u^x.
Proof.
intros x t u Heqc. unfold open. generalize 0. gen x. induction Heqc.
- intros x n. apply ES_redex. apply eqc_open; assumption.
- intros x n. simpl. apply ES_app_left. apply IHHeqc.
- intros x n. simpl. apply ES_app_right. apply IHHeqc.
- intros x n. simpl. apply ES_abs_in with L.
introv HL. unfold open. rewrite subst_com.
change ({0 ~> pterm_fvar x0}t) with (t ^ x0).
rewrite subst_com. apply H0; assumption. auto.
apply term_var. apply term_var. auto. apply term_var. apply term_var.
- intros x n. simpl. apply ES_subst_left with L.
introv HL. unfold open. rewrite subst_com.
change ({0 ~> pterm_fvar x0}t) with (t ^ x0).
rewrite subst_com. apply H0; assumption. auto.
apply term_var. apply term_var. auto. apply term_var. apply term_var.
- intros x n. simpl. apply ES_subst_right. apply IHHeqc.
Qed.
(*
Lemma ESctx_eqc_app_term : forall t1 t2 t, (pterm_app t1 t2) =c t -> exists u1 u2, t = (pterm_app u1 u2) /\ ((t1 =c u1 /\ t2 = u2) \/ (t1 = u1 /\ t2 =c u2)).
Proof.
introv H. remember (pterm_app t1 t2) as t'. induction H.
- subst. inversion H.
- exists t' u. split.
Admitted.
*)
(** Verificar necessidade deste lema.
Lemma ESctx_eqc_abs_term : forall t t', (pterm_abs t) =c t' ->
exists u, exists L, pterm_abs u = t' /\ (forall x, x \notin L -> (u ^ x) =c (t ^ x)).
Proof.
intros t t' H. inversion H; subst.
exists t {}. split; trivial.
apply eqc_abs_term in H0; assumption.
intros x H'. apply ES_redex. reflexivity.
exists t'0 L. split; trivial. intros.
apply ESctx_eqc_sym. apply H1; assumption.
Qed. *)
(** Verificar necessidade deste lema.
Lemma ESctx_eqc_sub_term : forall t u v, (t[u]) =c v -> exists t', exists u', v = (t'[u']).
Proof.
intros t u v H. inversion H; subst.
apply eqc_sub_term in H0.
destruct H0. subst.
exists t u; trivial.
destruct H0. destruct H0. destruct H0. destruct H1. destruct H2. subst.
exists (& x [u]) x0; trivial.
exists t' u; trivial.
exists t u'; reflexivity.
Qed. *)
Lemma red_out_eqc_ctx : red_out eqc_ctx.
Proof.
intros_all. unfold eqc_ctx in *. induction H0.
- apply ES_redex. apply red_out_eqc. assumption. assumption.
- simpl. apply ES_app_left. assumption.
- simpl. apply ES_app_right. assumption.
- simpl. apply ES_abs_in with ({{x}} \u L).
intros. apply notin_union in H2. destruct H2 as [H2 H2'].
apply notin_singleton in H2. repeat rewrite subst_open_var.
apply H1. assumption. assumption. assumption. assumption. assumption.
- simpl. apply ES_subst_left with ({{x}} \u L).
intros. apply notin_union in H2. destruct H2 as [H2 H2'].
apply notin_singleton in H2. repeat rewrite subst_open_var.
apply H1; assumption. assumption. assumption.
assumption. assumption.
- simpl. apply ES_subst_right. apply IHES_contextual_closure.
Qed.
Lemma red_rename_eqc_ctx: red_rename eqc_ctx.
Proof.
intros_all.
rewrite* (@subst_intro x t).
rewrite* (@subst_intro x t').
apply red_out_eqc_ctx.
apply term_var. assumption.
Qed.
Lemma red_wregular_eqc_ctx: red_wregular eqc_ctx.
Proof.
unfold eqc_ctx. apply red_wregular_ctx.
apply eqc_wregular.
Qed.
(** =c+: the transitive closure of =c. *)
Definition eqc_trans (t u: pterm) := trans_closure eqc_ctx t u.
Notation "t =c+ u" := (eqc_trans t u) (at level 66).
Lemma red_wregular_eqc_trans: red_wregular eqc_trans.
Proof.
intros_all. induction H0.
- generalize H0. apply red_wregular_eqc_ctx. assumption.
- apply IHtrans_closure. generalize H0.
apply red_wregular_ctx. apply eqc_wregular. assumption.
Qed.
Lemma ESctx_eqc_trans_app_term : forall t u v, (pterm_app u v) =c+ t -> exists u' v', t = pterm_app u' v'.
Proof.
introv H. remember (pterm_app u v) as t'.
generalize dependent u. generalize dependent v. induction H.
- introv H'. subst. inversion H.
+ inversion H0.
+ subst. exists t' v. reflexivity.
+ subst. exists u0 u'. reflexivity.
- introv H'. subst. apply ESctx_eqc_app_term in H.
destruct H. destruct H. apply IHtrans_closure in H. assumption.
Qed.
Lemma red_out_eqc_trans : red_out eqc_trans.
Proof.
intros_all. unfold eqc_trans in *. induction H0.
- apply one_step_reduction. apply red_out_eqc_ctx; assumption.
- apply (red_out_eqc_ctx x u) in H0.
apply transitive_reduction with ([x ~> u]u0); assumption. assumption.
Qed.
(*
Lemma red_rename_eqc_trans: red_rename eqc_trans.
Proof.
intros_all.
rewrite* (@subst_intro x t).
rewrite* (@subst_intro x t').
apply red_out_eqc_trans.
apply term_var. assumption.
Qed.
*)
Lemma eqc_trans_bvar : forall x t, (pterm_bvar x) =c+ t -> pterm_bvar x = t.
Proof.
introv H. remember (pterm_bvar x) as t0. induction H.
- subst. apply ESctx_eqc_bvar; assumption.
- subst. apply eq_trans with u.
apply ESctx_eqc_bvar in H. assumption.
apply IHtrans_closure. apply ESctx_eqc_bvar in H.
symmetry. assumption.
Qed.
Lemma eqc_trans_fvar : forall x t, (pterm_fvar x) =c+ t -> pterm_fvar x = t.
Proof.
introv H. remember (pterm_fvar x) as t0. induction H.
- subst. apply ESctx_eqc_fvar; assumption.
- subst. apply eq_trans with u. subst. apply ESctx_eqc_fvar; assumption.
apply IHtrans_closure. apply ESctx_eqc_fvar in H.
symmetry. assumption.
Qed.
Lemma close_rec_fresh: forall x t k, x \notin fv(close_rec k x t).
Proof.
intros x t. gen x. induction t.
intros x k. simpl. apply notin_empty.
intros x k. simpl. case_var*. simpl.
apply notin_empty. simpl. apply notin_singleton. auto.
intros x k. simpl. apply notin_union. split.
apply IHt1; assumption. apply IHt2; assumption.
intros x k. simpls. apply IHt.
intros x k. simpls. apply notin_union; split.
apply IHt1. apply IHt2. intros x k. simpls.
apply notin_union; split. apply IHt1. apply IHt2.
Qed.
Corollary close_fresh: forall x t, x \notin fv(close t x).
Proof.
intros x t. unfold close.
apply close_rec_fresh.
Qed.
Lemma close_spec: forall t x, term t -> exists u, t = u^x /\ body u /\ x \notin fv u.
Proof.
intros t x H. exists (close t x).
splits 3. apply open_close_var; assumption.
apply close_var_body. assumption.
apply close_fresh.
Qed.
Lemma eqc_trans_open: forall x t u, t =c+ u -> t^x =c+ u^x.
Proof.
Admitted.
Lemma eqc_trans_abs : forall t t' L, (forall x, x \notin L -> t^x =c+ t'^x) -> pterm_abs t =c+ pterm_abs t'.
Proof. Admitted.
(* introv H. pick_fresh x. forwards~ Red: (H x). *)
(* asserts Ht1: (term (pterm_abs t')). *)
(* apply_fresh term_abs as y. *)
(* asserts Ht': (term (t' ^ x)). *)
(* apply red_regular_trans in Red. apply Red. *)
(* apply red_regular_eqc_ctx. *)
(* apply term_open_rename with x; assumption. *)
(* gen_eq u:(t^x). gen_eq v:(t'^x). clear H. *)
(* gen t t' x L. induction Red; intros; subst. *)
(* apply one_step_reduction. apply ES_abs_in with L. *)
(* intros_all. apply* (red_rename_eqc_ctx x); simpls*. *)
(* destruct~ (@close_spec u x). *)
(* apply red_regular_eqc_trans in Red2. apply Red2. *)
(* destruct H. subst. *)
(* apply transitive_reduction with (pterm_abs x0). *)
(* apply IHRed1 with x L. *)
(* apply term_abs with (fv x0). intros_all. *)
(* destruct H0. apply body_to_term; assumption. *)
(* apply notin_union. split. apply notin_union in Fr. *)
(* destruct Fr. assumption. destruct H0. assumption. *)
(* reflexivity. reflexivity. *)
(* apply IHRed2 with x L. assumption. *)
(* apply notin_union. split. *)
(* apply notin_union. split. *)
(* apply notin_union in Fr. destruct Fr. *)
(* apply notin_union in H. destruct H. *)
(* assumption. destruct H0. assumption. *)
(* apply notin_union in Fr. destruct Fr. *)
(* assumption. reflexivity. reflexivity. *)
(* Qed. *)
Lemma eqc_trans_sub_left : forall t t' u L, (forall x, x \notin L -> t^x =c+ t'^x) -> (t[u]) =c+ (t'[u]).
Proof. Admitted.
Lemma eqc_trans_sub_right : forall t u u', u =c+ u' -> (t[u]) =c+ (t[u']).
Proof. Admitted.
Lemma eqc_trans_sym: forall t u, t =c+ u -> u =c+ t.
Proof.
intros_all. induction H.
- apply one_step_reduction.
apply ESctx_eqc_sym; assumption.
- inversion IHtrans_closure; subst.
+ apply ESctx_eqc_sym in H.
apply transitive_reduction with u.
assumption. apply one_step_reduction.
assumption.
+ apply ESctx_eqc_sym in H.
apply ESctx_eqc_sym in H1.
assert (u =c+ t).
{ apply one_step_reduction; assumption. }
apply transitive_closure_composition with u; assumption.
Qed.
Lemma eqc_trans_subst_out: forall t t' x u, t =c+ t' -> ([x ~> u]t) =c+ ([x ~> u]t').
Proof.
Admitted.
(** =e: the reflexive-transitive closure of =c. *)
Definition eqC (t : pterm) (u : pterm) := star_closure eqc_ctx t u.
Notation "t =e u" := (eqC t u) (at level 66).
(** =e is an equivalence relation *)
Lemma eqC_rf : forall t, t =e t.
Proof.
intros_all. apply reflexive_reduction.
Qed.
Lemma eqC_sym : forall t u, t =e u -> u =e t.
Proof.
intros t u H. induction H.
- apply eqC_rf.
- apply star_trans_reduction. apply eqc_trans_sym; assumption.
Qed.
Lemma eqC_trans : forall t u v, t =e u -> u =e v -> t =e v.
Proof.
introv H H'. apply star_closure_composition with u; trivial.
Qed.
Instance eqC_eq : Equivalence eqC.
Proof.
split; intros_all. apply eqC_rf.
apply eqC_sym; trivial.
apply eqC_trans with y; trivial.
Qed.
Lemma red_out_eqC : red_out eqC.
Proof.
intros_all. gen x u. induction H0.
- introv Hterm. apply reflexive_reduction.
- introv Hterm. apply star_trans_reduction.
apply red_out_eqc_trans; assumption.
Qed.
Lemma red_rename_eqC : red_rename eqC.
Proof.
intros_all.
rewrite* (@subst_intro x t).
rewrite* (@subst_intro x t').
apply red_out_eqC; trivial.
Qed.
Lemma red_wregular_eqC : red_wregular eqC.
Proof.
intros_all. induction H0.
- assumption.
- gen H0. apply red_wregular_eqc_trans. assumption.
Qed.
(** Verificar necessidade deste lema.
Lemma eqc_sub_term : forall t u t0, (t[u]) =e t0 ->
(t[u] = t0 \/ exists t', exists v, term u /\ term v /\ t'[v] = t /\ (& t')[u][v] = t0) .
Proof.
intros t u t0 H. inversion H; subst.
left; trivial. right. exists t1 u0.
split; trivial. split; trivial. split; trivial.
Qed. *)
Lemma eqC_bvar_term : forall x t, pterm_bvar x =e t -> pterm_bvar x = t.
Proof.
introv H. remember (pterm_bvar x) as t0.
inversion H; subst. reflexivity.
apply eqc_trans_bvar; assumption.
Qed.
Lemma eqC_fvar_term : forall x t, pterm_fvar x =e t -> pterm_fvar x = t.
Proof.
introv H. remember (pterm_fvar x) as t0.
inversion H; subst. reflexivity.
apply eqc_trans_fvar; trivial.
Qed.
Lemma eqC_app_term : forall t u v, pterm_app u v =e t -> exists u' v', t = pterm_app u' v'.
Proof.
introv H. remember (pterm_app u v) as t'.
generalize dependent u. generalize dependent v. induction H.
- introv H. subst. exists u v. reflexivity.
- introv H'. subst. inversion H; clear H.
+ subst. apply ESctx_eqc_app_term in H0. assumption.
+ subst. apply ESctx_eqc_app_term in H0. destruct H0.
destruct H. subst. apply ESctx_eqc_trans_app_term in H1. assumption.
Qed.
Lemma eqC_subst_in: forall t x u u', u =e u' -> ([x ~> u]t) =e ([x ~> u']t).
Proof.
Admitted.
(*
Lemma eqC_abs_term : forall t t', pterm_abs t =e t' ->
exists u, exists L, pterm_abs u = t' /\ (forall x, x \notin L -> (u ^ x) =e (t ^ x)).
Proof.
intros t t' H. gen_eq t0 : (pterm_abs t). generalize t; clear t. induction H.
intros t' H'. rewrite H' in H. apply pctx_eqc_abs_term in H.
case H; clear H; intros u0 H. case H; clear H; intros L H. destruct H.
exists u0 L. split; trivial. intros x Fr. apply one_step_reduction. apply H0; trivial.
intros t0 H'. rewrite H' in H. apply pctx_eqc_abs_term in H.
case H; clear H; intros u0 H. case H; clear H; intros L H. destruct H.
case (IHtrans_closure u0). rewrite H; trivial. intros t1 H2.
case H2; clear H2; intros L' H2. destruct H2. exists t1 (L \u L').
split; trivial. intros x Fr. apply notin_union in Fr. destruct Fr.
rewrite (H3 x); trivial. apply one_step_reduction. apply H1; trivial.
Qed.
Lemma eqC_sub_term : forall t u t0, t[u] =e t0 -> exists t', exists u', t'[u'] = t0 .
Proof.
intros t u v H. gen_eq t0 : (t [u]). generalize t u; clear t u. induction H.
intros t' u' H'. rewrite H' in H. apply pctx_eqc_sub_term in H; trivial.
intros t' u' H'. rewrite H' in H. apply pctx_eqc_sub_term in H.
case H; clear H; intros t0 H. case H; clear H; intros u0 H.
case (IHtrans_closure t0 u0). rewrite H; trivial. intros t1 H1.
case H1; clear H1; intros u1 H1. exists t1 u1; trivial.
Qed.
Lemma eqC_redex : forall t u v, ~(has_free_index 0 u) -> ~(has_free_index 0 v) -> (t[u][v]) =e ((& t)[v][u]) .
Proof.
intros t u v Tt Tu Tv. apply star_trans_reduction.
apply one_step_reduction. apply ES_redex. apply eqc_def; assumption.
Qed.
*)
Definition red_ctx_mod_eqC (R: pterm -> pterm -> Prop) (t: pterm) (u : pterm) :=
exists t', exists u', (t =e t') /\ (ES_contextual_closure R t' u') /\ (u' =e u).
(* ********************************************************************** *)
(** =e Properties *)
(** Not true because indexes inside substitution need to be updated.
Lemma lc_at_eqc : forall n t u, eqc t u -> (lc_at n t <-> lc_at n u).
Proof.
introv Heqc. gen n. induction Heqc.
intro n. split.
- intro Hlc_at. inversion Hlc_at; subst; clear Hlc_at.
inversion H1; subst; clear H1. simpl. split.
+ split.
* apply lc_at_bswap. apply lt_n_S. apply lt_0_Sn. assumption.
* apply lc_at_weaken_ind with n.
** assumption.
** apply le_n_Sn.
+ apply lc_at_weaken_ind with
+ Hlc_at. inversion Hlc_at; subst; clear Hlc_at.
inversion H1; subst; clear H1. simpl.
inversion H1; subst; clear H1. split.
+ split.
* apply lc_at_bswap. apply lt_n_S. apply lt_0_Sn. assumption.
* apply lc_at_weaken_ind with n. assumption. auto.
+
intro H2. destruct H2. destruct H2. split. split.
unfold bswap. apply lc_at_bswap. apply lt_n_S.
apply lt_0_Sn. assumption. apply term_to_term' in H1.
apply lc_at_weaken; assumption. apply term_to_term' in H0.
apply lc_at_weaken; assumption. intro H2. destruct H2.
destruct H2. split. split. apply lc_at_weaken_ind with 2.
assumption. apply lt_n_S. apply lt_0_Sn.
apply lc_at_weaken_ind with n. assumption.
apply le_n_Sn. apply term_to_term' in H1.
apply lc_at_weaken_ind with 0. assumption. apply le_0_n.
Qed.
*)
Lemma lc_at_ES_ctx_eqc : forall n t u, t =c u -> (lc_at n t <-> lc_at n u).
Proof.
(* introv H. generalize dependent n. induction H. *)
(* - intro n. apply lc_at_eqc. assumption. *)
(* - split; intro H'. *)
(* + inversion H'; subst. constructor. *)
(* rewrite <- IHES_contextual_closure. assumption. assumption. *)
(* + inversion H'; subst. constructor. rewrite IHES_contextual_closure. *)
(* assumption. assumption. *)
(* - split; intro H'. *)
(* + inversion H'; subst. constructor. assumption. *)
(* rewrite <- IHES_contextual_closure. assumption. *)
(* + inversion H'; subst. constructor. assumption. *)
(* rewrite IHES_contextual_closure. assumption. *)
(* - simpl. simpl in *. case var_fresh with L. intros. *)
(* rewrite <- lc_at_open' with (u := pterm_fvar x) (k := 0). *)
(* symmetry. rewrite <- lc_at_open' with (u := pterm_fvar x) (k := 0). *)
(* unfold open in *. symmetry. auto. intuition eauto. intuition eauto. *)
(* apply neq_0_lt. trivial. intuition eauto. apply neq_0_lt. trivial. *)
(* - split; simpl; intros H'. case var_fresh with L. intros x H1. *)
(* split; destruct H'; auto. *)
(* rewrite <- lc_at_open' with (u := pterm_fvar x) (k := 0); auto. *)
(* unfold open in *. rewrite <- H0. *)
(* rewrite lc_at_open' with (u := pterm_fvar x) (k := 0). assumption. *)
(* auto. apply lt_0_Sn. assumption. apply lt_0_Sn. split. *)
(* case var_fresh with (L := L). introv H1. *)
(* destruct H'. rewrite <- lc_at_open' with (u := pterm_fvar x) (k := 0). *)
(* unfold open in *. rewrite H0. rewrite lc_at_open' with (u := pterm_fvar x) (k := 0). *)
(* assumption. auto. apply lt_0_Sn. assumption. auto. *)
(* apply lt_0_Sn. destruct H'. assumption. *)
(* - intro n. split. *)
(* + intro H'. simpl. inversion H'. split. *)
(* * assumption. *)
(* * apply IHES_contextual_closure. assumption. *)
(* + intro H'. simpl. inversion H'. split. *)
(* * assumption. *)
(* * apply IHES_contextual_closure; assumption. *)
(* Qed. *)
Admitted.
Lemma lc_at_ES_ctx_eqc_trans : forall n t t', t =c+ t' -> (lc_at n t <-> lc_at n t').
Proof.
introv H. generalize dependent n. induction H.
- intro n. apply lc_at_ES_ctx_eqc. assumption.
- intro n. apply (lc_at_ES_ctx_eqc n) in H.
apply iff_trans with (lc_at n u). assumption.
apply IHtrans_closure.
Qed.
Lemma lc_at_eqC : forall n t t', t =e t' -> (lc_at n t <-> lc_at n t').
Proof.
introv H. generalize dependent n. induction H.
- reflexivity.
- intro n. apply lc_at_ES_ctx_eqc_trans. assumption.
Qed.
(*
Lemma eqc_fv : forall x t t', eqc t t' -> ((x \in fv t) <-> (x \in fv t')).
Proof.
introv H. induction H. simpl. unfold bswap.
rewrite fv_bswap_rec. rewrite <- union_assoc.
assert (H'': fv v \u fv u [=] fv u \u fv v).
{ apply union_comm. } rewrite <- H''.
rewrite union_assoc. split.
- intro H'; assumption.
- intro H'; assumption.
Qed.
Lemma ESctx_eqc_fv : forall x t t', t =c t' -> ((x \in fv t) <-> (x \in fv t')).
Proof.
introv H. generalize dependent x. induction H.
- intro x. apply eqc_fv; assumption.
- simpl. split.
+ intro H'. apply in_union in H'. destruct H'. apply in_union.
left. rewrite <- IHES_contextual_closure; assumption.
apply in_union. right; assumption.
+ intro H'. apply in_union in H'. destruct H'. apply in_union.
left. rewrite IHES_contextual_closure; assumption.
apply in_union; right; assumption.
- simpl. split.
+ intro H'. apply in_union in H'. destruct H'.
apply in_union. left; assumption.
apply in_union. right. rewrite <- IHES_contextual_closure; assumption.
+ intro H'. apply in_union in H'. destruct H'.
apply in_union. left; assumption.
apply in_union. right. rewrite IHES_contextual_closure; assumption.
- simpl. pick_fresh y. apply notin_union in Fr. destruct Fr. apply notin_union in H1.
destruct H1. split.
+ intro H4.
assert (Q: (x \in fv (t ^ y) <-> x \in fv t)).
{ apply fv_open_. intuition eauto. subst. apply H3; assumption. }
assert (S: (x \in fv (t' ^ y) <-> x \in fv t')).
{ apply fv_open_. intuition eauto. subst. apply H3; assumption. }
apply S. apply H0. assumption. apply Q; assumption.
+ intro H4.
assert (Q: (x \in fv (t ^ y) <-> x \in fv t)).
{ apply fv_open_. intuition eauto. subst. apply H2; assumption. }
assert (S: (x \in fv (t' ^ y) <-> x \in fv t')).
{ apply fv_open_. intuition eauto. subst. apply H2; assumption. }
apply Q. apply H0. assumption. apply S; assumption.
- simpl. pick_fresh y. apply notin_union in Fr. destruct Fr. apply notin_union in H1.
destruct H1. apply notin_union in H1. destruct H1. split.
+ intro H5. apply in_union in H5. destruct H5. apply in_union. left.
assert (Q: (x \in fv (t ^ y) <-> x \in fv t)).
{ apply fv_open_. intuition eauto. subst. apply H4; assumption. }
assert (S: (x \in fv (t' ^ y) <-> x \in fv t')).
{ apply fv_open_. intuition eauto. subst. apply H4; assumption. }
apply S. apply H0. assumption. apply Q. assumption.
apply in_union. right; assumption.
+ intro H5. apply in_union in H5. destruct H5. apply in_union. left.
assert (Q: (x \in fv (t ^ y) <-> x \in fv t)).
{ apply fv_open_. intuition eauto. subst. apply H3; assumption. }
assert (S: (x \in fv (t' ^ y) <-> x \in fv t')).
{ apply fv_open_. intuition eauto. subst. apply H3; assumption. }
apply Q. apply H0. assumption. apply S. assumption.
apply in_union. right; assumption.
- split.
+ introv H'. simpl in *. apply in_union in H'. destruct H'.
apply in_union; left; assumption.
apply in_union. right. apply IHES_contextual_closure. assumption.
+ intro H'. simpl in *. apply in_union in H'. destruct H'.
apply in_union; left; assumption.
apply in_union. right. apply IHES_contextual_closure; assumption.
Qed.
Lemma eqC_fv_trans : forall x t t', t =c+ t' -> ((x \in fv t) <-> (x \in fv t')).
Proof.
introv H. generalize dependent x. induction H.
- intro x. apply ESctx_eqc_fv; assumption.
- intro x. apply (ESctx_eqc_fv x) in H.
apply iff_trans with (x \in fv u). assumption.
apply IHtrans_closure.
Qed.
Lemma eqC_fv : forall x t t', t =e t' -> ((x \in fv t) <-> (x \in fv t')).
Proof.
introv H. generalize dependent x. induction H.
- reflexivity.
- intro x. apply eqC_fv_trans; assumption.
Qed.
*)
Lemma red_regular'_eqc : red_regular' eqc.
Proof.
(* unfold red_regular'. intros t0 t1 H'. rewrite term_eq_term'. *)
(* rewrite term_eq_term'. unfold term'. apply lc_at_eqc; trivial. *)
(* Qed. *)
Admitted.
(*
Lemma pctx_eqc_fv : forall x t u, (p_contextual_closure eqc) t u -> (x \in (fv t) <-> x \in (fv u)).
Proof.
intros x t u H. induction H. induction H.
split; trivial. simpl. split.
intro H1. apply in_union in H1. case H1; clear H1.
intro H1. apply in_union in H1. case H1; clear H1.
intro H1. apply in_union. left. apply in_union.
left. unfold bswap. rewrite fv_bswap_rec; trivial.
intro H1. apply in_union. right. trivial.
intro H1. apply in_union. left. apply in_union. right. trivial.
intro H1. apply in_union in H1. case H1; clear H1.
intro H1. apply in_union in H1. case H1; clear H1.
intro H1. apply in_union. left. apply in_union.
left. unfold bswap in H1. rewrite fv_bswap_rec in H1; trivial.
intro H1. apply in_union. right. trivial.
intro H1. apply in_union. left. apply in_union. right; trivial.
simpl. split.
intro H1. apply in_union in H1. case H1; clear H1.
intro H1. apply in_union. left. apply IHp_contextual_closure1; trivial.
intro H1. apply in_union. right; trivial. apply IHp_contextual_closure2; trivial.
intro H1. apply in_union in H1. case H1; clear H1.
intro H1. apply in_union. left. apply IHp_contextual_closure1; trivial.
intro H1. apply in_union. right; trivial. apply IHp_contextual_closure2; trivial.
simpl. pick_fresh z. apply notin_union in Fr. case Fr; clear Fr.
intros H1 H2. apply notin_union in H1. case H1; clear H1. intros H1 H3.
apply notin_union in H1. case H1; clear H1. intros H1 H4.
apply notin_singleton in H4.
assert (Q: (x \in fv (t ^ z) <-> x \in fv t)).
unfold open. apply fv_open_. intro.
apply H4. apply symmetry; trivial.
assert (Q': (x \in fv (t' ^ z) <-> x \in fv t')).
unfold open. apply fv_open_. intro.
apply H4. apply symmetry; trivial.
split.
intro H5. apply Q'. apply H0; trivial. apply Q; trivial.
intro H5. apply Q. apply H0; trivial. apply Q'; trivial.
simpl. pick_fresh z. apply notin_union in Fr. case Fr; clear Fr.
intros H2 H3. apply notin_union in H2. case H2; clear H2.
intros H2 H4. apply notin_union in H2. case H2; clear H2.
intros H2 H5. apply notin_union in H2. case H2; clear H2.
intros H2 H6. apply notin_union in H2. case H2; clear H2.
intros H2 H7. apply notin_singleton in H7.
assert (Q: (x \in fv (t ^ z) <-> x \in fv t)).
unfold open. apply fv_open_. intro.
apply H7. apply symmetry; trivial.
assert (Q': (x \in fv (t' ^ z) <-> x \in fv t')).
unfold open. apply fv_open_. intro.
apply H7. apply symmetry; trivial.
split.
intro H8. apply in_union in H8. apply in_union. case H8; clear H8; intro H8.
left. apply Q'. apply H0; trivial. apply Q; trivial.
right. apply IHp_contextual_closure; trivial.
intro H8. apply in_union in H8. apply in_union. case H8; clear H8; intro H8.
left. apply Q. apply H0; trivial. apply Q'; trivial.
right. apply IHp_contextual_closure; trivial.
Qed.
*)
Lemma red_wregular_mod_eqC : forall R, red_wregular R ->
red_wregular (red_ctx_mod_eqC R).
Proof.
introv H. unfold red_wregular. introv H0 H1.
unfold red_ctx_mod_eqC in H1. destruct H1 as [x [x' [He [Hes He'] ] ] ].
generalize He'; clear He'.
apply red_wregular_eqC.
generalize Hes; clear Hes.
apply red_wregular_ctx. assumption.
generalize He; clear He.
apply red_wregular_eqC; assumption.
Qed.
(*
Lemma red_out_pctx_eqc : red_out (p_contextual_closure eqc).
Proof.
apply red_out_pctx. apply red_out_eqc.
Qed.
Lemma red_out_pctx_eqc' : forall x t u u', term t -> term u ->
p_contextual_closure eqc u u' ->
p_contextual_closure eqc ([x ~> u]t) ([x ~> u']t).
Proof.
intros x t u u' Tt Tu H.
apply term_size_induction with (t := t); trivial; simpl.
intro z. case (z == x). intro; trivial. intro. apply p_redex. apply eqc_rf.
intros t1 B Ht1. apply p_abs_in with (L := {{x}} \u (fv t1)).
intros z Fr. apply notin_union in Fr. destruct Fr.
apply notin_singleton in H0.
rewrite subst_open_var; trivial.
rewrite subst_open_var; trivial.
apply Ht1; trivial. apply body_to_term; trivial.
apply (lc_at_pctx_eqc 0) in H.
rewrite <- term_eq_term' in H.
rewrite <- term_eq_term' in H. apply H; trivial.
intros t1 t2 Tt1 Ht1 Tt2 Ht2. apply p_app; trivial.
intros t1 t2 Tt2 Ht2 B Ht1.
apply p_subst with (L := {{x}} \u (fv t1)); trivial.
intros z Fr. apply notin_union in Fr. destruct Fr.
apply notin_singleton in H0.
rewrite subst_open_var; trivial.
rewrite subst_open_var; trivial.
apply Ht1; trivial. apply body_to_term; trivial.
apply (lc_at_pctx_eqc 0) in H.
rewrite <- term_eq_term' in H.
rewrite <- term_eq_term' in H.
apply H; trivial.
Qed.
Lemma pctx_eqc_open : forall n t t' u, term u -> p_contextual_closure eqc t t' ->
p_contextual_closure eqc ({n ~> u}t) ({n ~> u}t').
Proof.
intros n t t' u Tu H. generalize n; clear n.
induction H. destruct H. intro n. apply p_redex. apply eqc_rf.
intro n. unfold open. simpl.
replace ({S (S n) ~> u}(& t)) with (& ({S (S n) ~> u}t)).
replace ({S n ~> u}v) with v. replace ({n ~> u}v) with v.
replace ({S n ~> u}u0) with u0. replace ({n ~> u}u0) with u0.
apply p_redex. apply eqc_rx; trivial.
rewrite open_lc_at; trivial.
apply lc_at_weaken_ind with (k1 := 0); try omega.
rewrite <- term_eq_term'; trivial.
rewrite open_lc_at; trivial.
apply lc_at_weaken_ind with (k1 := 0); try omega.
rewrite <- term_eq_term'; trivial.
rewrite open_lc_at; trivial.
apply lc_at_weaken_ind with (k1 := 0); try omega.
rewrite <- term_eq_term'; trivial.
rewrite open_lc_at; trivial.
apply lc_at_weaken_ind with (k1 := 0); try omega.
rewrite <- term_eq_term'; trivial.
unfold bswap. rewrite <- bswap_open_rec; try omega; trivial.
apply lc_at_weaken_ind with (k1 := 0); try omega.
rewrite <- term_eq_term'; trivial.
simpl; intro n. apply p_app; trivial.
simpl; intro n. apply p_abs_in with (L := (fv u) \u L).
intros x H2. apply notin_union in H2. case H2; clear H2.
intros H2 H3. unfold open in *|-*.
replace ({0 ~> pterm_fvar x}({S n ~> u}t))
with ({S n ~> u}({0 ~> pterm_fvar x}t)).
replace ({0 ~> pterm_fvar x}({S n ~> u}t'))
with ({S n ~> u}({0 ~> pterm_fvar x}t')).
apply H0; trivial.
rewrite subst_com; trivial. omega.
rewrite subst_com; trivial. omega.
simpl; intro n. apply p_subst with (L := (fv u) \u L); trivial.
intros x H2. apply notin_union in H2. case H2; clear H2.
intros H2 H3. unfold open in *|-*.
replace ({0 ~> pterm_fvar x}({S n ~> u}t))
with ({S n ~> u}({0 ~> pterm_fvar x}t)).
replace ({0 ~> pterm_fvar x}({S n ~> u}t'))
with ({S n ~> u}({0 ~> pterm_fvar x}t')).
apply H0; trivial.
rewrite subst_com; trivial. omega.
rewrite subst_com; trivial. omega.
Qed.
Lemma eqC_open : forall n t t' u, term u -> t =e t'-> (open_rec n u t) =e (open_rec n u t').
Proof.
intros n t t' u Tu H. induction H.
apply one_step_reduction. apply pctx_eqc_open; trivial.
apply transitive_reduction with (u := ({n ~> u}u0)); trivial.
apply pctx_eqc_open; trivial.
Qed.
Lemma eqC_open_var : forall (x:var) t1 t2 u, x \notin (fv t1) ->
x \notin (fv t2) -> term u -> (t1 ^ x =e t2 ^ x) -> ((t1^^u) =e (t2^^u)).
Proof.
intros x t1 t2 u H1 H2 T H3.
assert (Q : subst x u (t1 ^ x) =e subst x u (t2 ^ x)).
apply red_out_eqC; trivial.
rewrite subst_intro with (x := x); trivial.
rewrite subst_intro with (x := x) (t := t2); trivial.
Qed.
(** Compatibility of =c+ with the structure of terms. *)
Lemma eqc_trans_app_l: forall t t' u, term u -> t =c+ t' -> (pterm_app t u) =c+ (pterm_app t' u).
Proof.
intros t t' u H1 H2.
induction H2.
apply one_step_reduction.
apply ES_app_left; assumption.
apply transitive_reduction with (pterm_app u0 u).
apply ES_app_left; assumption. assumption.
Qed.
Lemma eqc_trans_app_r: forall t u u', term t -> u =c+ u' -> (pterm_app t u) =c+ (pterm_app t u').
Proof.
intros t u u' H1 H2.
induction H2.
apply one_step_reduction.
apply ES_app_right; assumption.
apply transitive_reduction with (pterm_app t u).
apply ES_app_right; assumption. assumption.
Qed.
Lemma eqc_trans_abs: forall t t' L, (forall x, x \notin L -> t^x =c+ t'^x) -> (pterm_abs t) =c+ (pterm_abs t').
Proof.
introv H.
pick_fresh z. apply notin_union in Fr. destruct Fr.
apply notin_union in H0. destruct H0.
assert (t^z =c+ t'^z). apply H; assumption.
inversion H3; subst.
apply one_step_reduction. apply ES_abs_in with L.
introv H'. apply red_rename
Lemma eqc_trans_sub: forall t t' u L, term u -> (forall x, x \notin L -> t^x =c+ t'^x) -> (pterm_sub t u) =c+ (pterm_sub t' u).
Proof. Admitted.
(** Compatibility of =e with the structure of pre-terms. *)
Lemma eqC_app_l: forall t t' u, term u -> t =e t' -> (pterm_app t u) =e (pterm_app t' u).
Proof.
introv H1 H2.
induction H2. reflexivity.
apply star_trans_reduction. apply eqc_trans_app_l; assumption.
Qed.
Lemma eqC_app_r: forall t u u', term t -> u =e u' -> (pterm_app t u) =e (pterm_app t u').
Proof.
introv H1 H2.
induction H2. reflexivity.
apply star_trans_reduction. apply eqc_trans_app_r; assumption.
Qed.
Lemma eqC_abs: forall t t' L, (forall x, x \notin L -> t^x =e t'^x) -> (pterm_abs t) =e (pterm_abs t').
Proof. Admitted.
Lemma eqC_sub: forall t t' u L, term u -> (forall x, x \notin L -> t^x =e t'^x) -> (pterm_sub t u) =e (pterm_sub t' u).
Proof. Admitted.
*)
(* ********************************************************************** *)
(** =e Rewriting *)
Instance rw_eqC_app : Proper (eqC ==> eqC ==> eqC) pterm_app.
Proof.
intros_all. apply star_closure_composition with (pterm_app y x0).
- induction H.
+ reflexivity.
+ constructor. induction H.
* constructor. constructor 2. assumption.
* constructor 2 with (pterm_app u x0).
constructor 2. assumption. assumption.
- induction H0.
+ reflexivity.
+ induction H0.
* constructor. constructor. constructor 3.
assumption.
* assert ((pterm_app y t) =c (pterm_app y u)).
{ apply ES_app_right. assumption. }
apply (one_step_reduction eqc_ctx (pterm_app y t) (pterm_app y u)) in H2.
apply star_transitive_closure_composition_1 with (pterm_app y u); assumption.
Qed.
Instance rw_eqC_abs : Proper (eqC ==> eqC) pterm_abs.
Proof.
intros t t' Heq. induction Heq.
- apply eqC_rf.
- inversion H; subst; clear H.
+ unfold eqC. apply star_trans_reduction.
apply one_step_reduction. pick_fresh y.
apply notin_union in Fr.
destruct Fr as [Hfv_t Hfv_u].
apply ES_abs_in with (fv t \u fv u).
introv Hfv. apply notin_union in Hfv.
destruct Hfv as [Hfv_t' Hfv_u'].
apply eqc_ctx_open; assumption.
+ apply star_trans_reduction.
assert (t =c+ u).
{ apply transitive_reduction with u0; assumption. }
pick_fresh x. apply notin_union in Fr.
destruct Fr as [Fr Hfv_u0]. apply notin_union in Fr.
destruct Fr as [Hfv_t Hfv_u].
apply eqc_trans_abs with (fv t \u fv u).
introv Hfv. apply notin_union in Hfv.
destruct Hfv as [Hfv_t' Hfv_u'].
apply eqc_trans_open; assumption.
Qed.
Instance rw_eqC_sub : Proper (eqC ==> eqC ==> eqC) pterm_sub.
Proof.
intros_all. apply star_closure_composition with (y[x0]).
- inversion H; subst.
+ reflexivity.
+ apply star_trans_reduction. inversion H1; subst.
apply one_step_reduction. pick_fresh z.
apply ES_subst_left with (fv x \u fv y \u fv x0 \u fv y0).
introv Hfv. apply eqc_ctx_open; assumption.
assert (x =c+ y).
{ apply transitive_reduction with u; assumption. }
pick_fresh z.
apply eqc_trans_sub_left with (fv x \u fv y \u fv x0 \u fv y0 \u fv u).
introv Hfv. apply eqc_trans_open; assumption.
- induction H0.
+ reflexivity.
+ apply star_trans_reduction. induction H0.
* apply one_step_reduction.
apply ES_subst_right; assumption.
(* * apply transitive_reduction with (y[u]). *)
(* ** apply ES_subst_right; assumption. *)
(* ** assumption. *)
(* Qed. *)
Admitted. (* Fabrício *)
Instance rw_eqC_sub' : Proper (eqC ==> eqC ==> eqC) pterm_sub'.