]> matita.cs.unibo.it Git - helm.git/blob - matita/matita/contribs/lambdadelta/basic_2/relocation/lleq_lleq.ma
- improved arithmetics for natural numbers with infinity
[helm.git] / matita / matita / contribs / lambdadelta / basic_2 / relocation / lleq_lleq.ma
1 (**************************************************************************)
2 (*       ___                                                              *)
3 (*      ||M||                                                             *)
4 (*      ||A||       A project by Andrea Asperti                           *)
5 (*      ||T||                                                             *)
6 (*      ||I||       Developers:                                           *)
7 (*      ||T||         The HELM team.                                      *)
8 (*      ||A||         http://helm.cs.unibo.it                             *)
9 (*      \   /                                                             *)
10 (*       \ /        This file is distributed under the terms of the       *)
11 (*        v         GNU General Public License Version 2                  *)
12 (*                                                                        *)
13 (**************************************************************************)
14
15 include "basic_2/relocation/ldrop_ldrop.ma".
16 include "basic_2/relocation/lleq.ma".
17
18 (* LAZY EQUIVALENCE FOR LOCAL ENVIRONMENTS **********************************)
19
20 (* Advanced inversion lemmas ************************************************)
21
22 lemma lleq_inv_lref_dx: ∀L1,L2,d,i. L1 ⋕[d, #i] L2 →
23                         ∀I,K2,V. ⇩[0, i] L2 ≡ K2.ⓑ{I}V →
24                         (∃∃K1. ⇩[0, i] L1 ≡ K1.ⓑ{I}V & K1 ⋕[0, V] K2 & d ≤ i) ∨
25                         ∃∃I1,K1,V1. ⇩[0, i] L1 ≡ K1.ⓑ{I1}V1 &
26                                     K1 ⋕[d-i-1, V1] K2 & K1 ⋕[d-i-1, V] K2 &
27                                     i < d.
28 #L1 #L2 #d #i #H #I #K2 #V #HLK2 elim (lleq_inv_lref … H) -H *
29 [ #_ #H elim (lt_refl_false i)
30   lapply (ldrop_fwd_length_lt2 … HLK2) -HLK2
31   /2 width=3 by lt_to_le_to_lt/ (**) (* full auto too slow *)
32 | #I1 #I2 #K11 #K22 #V1 #V2 #HLK11 #HLK22 #HV1 #HV2 #Hdi lapply (ldrop_mono … HLK22 … HLK2) -L2
33   #H destruct /3 width=6 by ex4_3_intro, or_intror/
34 | #I0 #K1 #K0 #V0 #HLK1 #HLK0 #HK10 #Hdi lapply (ldrop_mono … HLK0 … HLK2) -L2
35   #H destruct /3 width=3 by ex3_intro, or_introl/
36 ]
37 qed-.
38
39 lemma lleq_inv_lref_sn: ∀L1,L2,d,i. L1 ⋕[d, #i] L2 →
40                         ∀I,K1,V. ⇩[0, i] L1 ≡ K1.ⓑ{I}V →
41                         (∃∃K2. ⇩[0, i] L2 ≡ K2.ⓑ{I}V & K1 ⋕[0, V] K2 & d ≤ i) ∨
42                         ∃∃I2,K2,V2. ⇩[0, i] L2 ≡ K2.ⓑ{I2}V2 &
43                                     K1 ⋕[d-i-1, V] K2 & K1 ⋕[d-i-1, V2] K2 &
44                                     i < d.
45 #L1 #L2 #d #i #HL12 #I #K1 #V #HLK1 elim (lleq_inv_lref_dx L2 … d … HLK1) -HLK1
46 [1,2: * ] /4 width=6 by lleq_sym, ex4_3_intro, ex3_intro, or_introl, or_intror/
47 qed-.
48
49 lemma lleq_inv_lref_ge_dx: ∀L1,L2,d,i. L1 ⋕[d, #i] L2 → d ≤ i →
50                            ∀I,K2,V. ⇩[0, i] L2 ≡ K2.ⓑ{I}V →
51                            ∃∃K1. ⇩[0, i] L1 ≡ K1.ⓑ{I}V & K1 ⋕[0, V] K2.
52 #L1 #L2 #d #i #H #Hdi #I #K2 #V #HLK2 elim (lleq_inv_lref … H) -H *
53 [ #_ #H elim (lt_refl_false i)
54   lapply (ldrop_fwd_length_lt2 … HLK2) -HLK2
55   /2 width=3 by lt_to_le_to_lt/ (**) (* full auto too slow *)
56 | -HLK2 #I1 #I2 #K11 #K22 #V1 #V2 #_ #_ #_ #_ #H elim (lt_refl_false i)
57   /2 width=3 by lt_to_le_to_lt/
58 | #I0 #K1 #K0 #V0 #HLK1 #HLK0 #HK10 #_ lapply (ldrop_mono … HLK0 … HLK2) -L2
59   #H destruct /2 width=3 by ex2_intro/
60 ]
61 qed-.
62
63 lemma lleq_inv_lref_ge_sn: ∀L1,L2,d,i. L1 ⋕[d, #i] L2 → d ≤ i →
64                            ∀I,K1,V. ⇩[0, i] L1 ≡ K1.ⓑ{I}V →
65                            ∃∃K2. ⇩[0, i] L2 ≡ K2.ⓑ{I}V & K1 ⋕[0, V] K2.
66 #L1 #L2 #d #i #HL12 #Hdi #I #K1 #V #HLK1 elim (lleq_inv_lref_ge_dx L2 … Hdi … HLK1) -Hdi -HLK1
67 /3 width=3 by lleq_sym, ex2_intro/
68 qed-.
69
70 fact lleq_inv_S_aux: ∀L1,L2,T,d0. L1 ⋕[d0, T] L2 → ∀d. d0 = d + 1 →
71                      ∀K1,K2,I,V. ⇩[0, d] L1 ≡ K1.ⓑ{I}V → ⇩[0, d] L2 ≡ K2.ⓑ{I}V →
72                      L1 ⋕[d, T] L2.
73 #L1 #L2 #T #d0 #H elim H -L1 -L2 -T -d0
74 /2 width=1 by lleq_sort, lleq_free, lleq_gref/
75 [ #I1 #I2 #L1 #L2 #K11 #K22 #V1 #V2 #d0 #i #Hid0 #HLK11 #HLK22 #HV1 #_ #IHV1 #IHV2 #d #H #K1 #K2 #J #W #HLK1 #HLK2 destruct
76   elim (le_to_or_lt_eq i d) /2 width=1 by lleq_skip, monotonic_pred/ -Hid0 
77   [ -HV1 #Hid
78     lapply (ldrop_fwd_ldrop2 … HLK11) #H1
79     lapply (ldrop_fwd_ldrop2 … HLK22) #H2
80     lapply (ldrop_conf_ge … H1 … HLK1 ?) // -H1 -HLK1
81     lapply (ldrop_conf_ge … H2 … HLK2 ?) // -H2 -HLK2
82     <minus_plus /4 width=10 by lleq_skip, arith_i/
83   | -IHV1 -IHV2 #H destruct
84     lapply (ldrop_mono … HLK11 … HLK1) -HLK11 #H destruct
85     lapply (ldrop_mono … HLK22 … HLK2) -HLK22 #H destruct
86     /2 width=7 by lleq_lref/
87   ]
88 | #I #L1 #L2 #K11 #K22 #V #d0 #i #Hid0 #HLK11 #HLK22 #HV #_ #d #H #K1 #K2 #J #W #HLK1 #HLK2 destruct
89   /3 width=7 by lleq_lref, lt_to_le/
90 | #a #I #L1 #L2 #V #T #d0 #_ #_ #IHV #IHT #d #H #K1 #K2 #J #W #HLK1 #HLK2 destruct
91   /4 width=6 by lleq_bind, ldrop_ldrop/
92 | #I #L1 #L2 #V #T #d0 #_ #_ #IHV #IHT #d #H #K1 #K2 #J #W #HLK1 #HLK2 destruct
93   /3 width=6 by lleq_flat/
94 ]
95 qed-.
96
97 lemma lleq_inv_S: ∀T,L1,L2,d. L1 ⋕[d+1, T] L2 →
98                   ∀K1,K2,I,V. ⇩[0, d] L1 ≡ K1.ⓑ{I}V → ⇩[0, d] L2 ≡ K2.ⓑ{I}V →
99                   L1 ⋕[d, T] L2.
100 /2 width=6 by lleq_inv_S_aux/ qed-.
101
102 lemma lleq_inv_bind_O: ∀a,I,L1,L2,V,T. L1 ⋕[0, ⓑ{a,I}V.T] L2 →
103                        L1 ⋕[0, V] L2 ∧ L1.ⓑ{I}V ⋕[0, T] L2.ⓑ{I}V.
104 #a #I #L1 #L2 #V #T #H elim (lleq_inv_bind … H) -H
105 /3 width=6 by ldrop_pair, conj, lleq_inv_S/
106 qed-.
107
108 lemma lleq_inv_lift_le: ∀L1,L2,U,d0. L1 ⋕[d0, U] L2 →
109                         ∀K1,K2,d,e. ⇩[d, e] L1 ≡ K1 → ⇩[d, e] L2 ≡ K2 →
110                         ∀T. ⇧[d, e] T ≡ U → d0 ≤ d → K1 ⋕[d0, T] K2.
111 #L1 #L2 #U #d0 #H elim H -L1 -L2 -U -d0
112 [ #L1 #L2 #d0 #k #HL12 #K1 #K2 #d #e #HLK1 #HLK2 #X #H #_ >(lift_inv_sort2 … H) -X
113   lapply (ldrop_fwd_length_eq1 … HLK1 HLK2 HL12) -L1 -L2 -d -e
114   /2 width=1 by lleq_sort/
115 | #I1 #I2 #L1 #L2 #K11 #K22 #W1 #W2 #d0 #i #Hid0 #HLK11 #HLK22 #HW1 #HW2 #IHW1 #IHW2 #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_lref2 … H) -H
116   * #Hid #H destruct [ -HW1 -HW2 | -IHW1 -IHW2 ]
117   [ elim (ldrop_conf_lt … HLK1 … HLK11) // -L1
118     elim (ldrop_conf_lt … HLK2 … HLK22) // -Hid -L2
119     #L2 #V2 #HKL2 #HKL22 #HVW2 #L1 #V1 #HKL1 #HKL11 #HVW1
120     @(lleq_skip … HKL1 HKL2) -HKL1 -HKL2 /3 width=6 by monotonic_le_minus_l2/ (**) (* full auto fails *)
121   | lapply (ldrop_conf_ge … HLK1 … HLK11 ?) // -L1
122     lapply (ldrop_conf_ge … HLK2 … HLK22 ?) // -Hid -L2
123     #HK22 #HK11 @(lleq_skip … HK11 HK22) -HK11 -HK22
124     /2 width=3 by lleq_ge, le_to_lt_to_lt/ (**) (* full auto fails *)
125   ]
126 | #I #L1 #L2 #K11 #K22 #W #d0 #i #Hid0 #HLK11 #HLK22 #HW #IHW #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_lref2 … H) -H
127   * #Hid #H destruct [ -HW | -IHW ]
128   [ elim (ldrop_conf_lt … HLK1 … HLK11) // -L1 #L1 #V #HKL1 #KL11 #HVW
129     elim (ldrop_conf_lt … HLK2 … HLK22) // -Hid -L2 #L2 #V0 #HKL2 #KL22 #HV0
130     lapply (lift_inj … HV0 … HVW) -HV0 #H destruct /3 width=12 by lleq_lref/
131   | lapply (ldrop_conf_ge … HLK1 … HLK11 ?) // -L1
132     lapply (ldrop_conf_ge … HLK2 … HLK22 ?) // -L2 -Hid0
133     elim (le_inv_plus_l … Hid) -Hid /3 width=7 by lleq_lref, transitive_le/
134   ]
135 | #L1 #L2 #d0 #i #HL1 #HL2 #HL12 #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_lref2 … H) -H
136   * #_ #H destruct
137   lapply (ldrop_fwd_length_eq1 … HLK1 HLK2 HL12)
138   [ lapply (ldrop_fwd_length_le4 … HLK1) -HLK1
139     lapply (ldrop_fwd_length_le4 … HLK2) -HLK2
140     #HKL2 #HKL1 #HK12 @lleq_free // /2 width=3 by transitive_le/ (**) (* full auto too slow *)
141   | lapply (ldrop_fwd_length … HLK1) -HLK1 #H >H in HL1; -H
142     lapply (ldrop_fwd_length … HLK2) -HLK2 #H >H in HL2; -H
143     /3 width=1 by lleq_free, le_plus_to_minus_r/
144   ]
145 | #L1 #L2 #d0 #p #HL12 #K1 #K2 #d #e #HLK1 #HLK2 #X #H #_ >(lift_inv_gref2 … H) -X
146   lapply (ldrop_fwd_length_eq1 … HLK1 HLK2 HL12) -L1 -L2 -d -e
147   /2 width=1 by lleq_gref/
148 | #a #I #L1 #L2 #W #U #d0 #_ #_ #IHW #IHU #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_bind2 … H) -H
149   #V #T #HVW #HTU #H destruct /4 width=6 by lleq_bind, ldrop_skip, le_S_S/
150 | #I #L1 #L2 #W #U #d0 #_ #_ #IHW #IHU #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_flat2 … H) -H
151   #V #T #HVW #HTU #H destruct /3 width=6 by lleq_flat/
152 ]
153 qed-.
154
155 lemma lleq_inv_lift_ge: ∀L1,L2,U,d0. L1 ⋕[d0, U] L2 →
156                         ∀K1,K2,d,e. ⇩[d, e] L1 ≡ K1 → ⇩[d, e] L2 ≡ K2 →
157                         ∀T. ⇧[d, e] T ≡ U → d+e ≤ d0 → K1 ⋕[d0-e, T] K2.
158 #L1 #L2 #U #d0 #H elim H -L1 -L2 -U -d0
159 [ #L1 #L2 #d0 #k #HL12 #K1 #K2 #d #e #HLK1 #HLK2 #X #H #_ >(lift_inv_sort2 … H) -X
160   lapply (ldrop_fwd_length_eq1 … HLK1 HLK2 HL12) -L1 -L2 -d
161   /2 width=1 by lleq_sort/
162 | #I1 #I2 #L1 #L2 #K11 #K22 #W1 #W2 #d0 #i #Hid0 #HLK11 #HLK22 #HW1 #HW2 #IHW1 #IHW2 #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hded0 elim (lift_inv_lref2 … H) -H
163   * #Hid #H destruct [ -HW1 -HW2 | -IHW1 -IHW2 ]
164   [ elim (ldrop_conf_lt … HLK1 … HLK11) // -L1
165     elim (ldrop_conf_lt … HLK2 … HLK22) // -L2
166     elim (le_inv_plus_l … Hded0) #Hdd0e #_
167     #L2 #V2 #HKL2 #HKL22 #HVW2 #L1 #V1 #HKL1 #HKL11 #HVW1
168     @(lleq_skip … HKL1 HKL2) -HKL1 -HKL2 [ /2 width=3 by lt_to_le_to_lt/ ] (**) (* explicit constructor *)
169     >minus_minus_comm3 /3 width=6 by arith_k_sn/ (**) (* slow *)
170   | lapply (ldrop_conf_ge … HLK1 … HLK11 ?) // -L1
171     lapply (ldrop_conf_ge … HLK2 … HLK22 ?) // -L2 -Hded0
172     elim (le_inv_plus_l … Hid) -Hid #_ #Hei
173     #HK22 #HK11 @(lleq_skip … HK11 HK22) -HK11 -HK22 (**) (* explicit constructor *)
174     [ /2 width=1 by monotonic_lt_minus_l/ ] >arith_b1 //
175   ]
176 | #I #L1 #L2 #K11 #K22 #W #d0 #i #Hid0 #HLK11 #HLK22 #HW #_ #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hded0 elim (lift_inv_lref2 … H) -H
177   * #Hid #H destruct
178   [ -I -L1 -L2 -K11 -K22 -W elim (le_plus_xySz_x_false e 0 d)
179     /3 width=3 by transitive_le, le_to_lt_to_lt/
180   | lapply (ldrop_conf_ge … HLK1 … HLK11 ?) // -L1
181     lapply (ldrop_conf_ge … HLK2 … HLK22 ?) // -L2 -Hded0
182     /3 width=7 by lleq_lref, monotonic_le_minus_l/
183   ]
184 | #L1 #L2 #d0 #i #HL1 #HL2 #HL12 #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hded0 elim (lift_inv_lref2 … H) -H
185   * #_ #H destruct
186   lapply (ldrop_fwd_length_eq1 … HLK1 HLK2 HL12)
187   [ lapply (ldrop_fwd_length_le4 … HLK1) -HLK1
188     lapply (ldrop_fwd_length_le4 … HLK2) -HLK2
189     #HKL2 #HKL1 #HK12 @lleq_free // /2 width=3 by transitive_le/ (**) (* full auto too slow *)
190   | lapply (ldrop_fwd_length … HLK1) -HLK1 #H >H in HL1; -H
191     lapply (ldrop_fwd_length … HLK2) -HLK2 #H >H in HL2; -H
192     /3 width=1 by lleq_free, le_plus_to_minus_r/
193   ]
194 | #L1 #L2 #d0 #p #HL12 #K1 #K2 #d #e #HLK1 #HLK2 #X #H #_ >(lift_inv_gref2 … H) -X
195   lapply (ldrop_fwd_length_eq1 … HLK1 HLK2 HL12) -L1 -L2 -d
196   /2 width=1 by lleq_gref/
197 | #a #I #L1 #L2 #W #U #d0 #_ #_ #IHW #IHU #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hded0 elim (lift_inv_bind2 … H) -H
198   #V #T #HVW #HTU #H destruct
199   elim (le_inv_plus_l … Hded0) #_ #Hed0
200   @lleq_bind [ /2 width=5 by/ ] -IHW (**) (* explicit constructor *)
201   >plus_minus /3 width=5 by ldrop_skip, le_minus_to_plus/
202 | #I #L1 #L2 #W #U #d0 #_ #_ #IHW #IHU #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hded0 elim (lift_inv_flat2 … H) -H
203   #V #T #HVW #HTU #H destruct /3 width=5 by lleq_flat/
204 ]
205 qed-.
206
207 lemma lleq_inv_lift_be: ∀L1,L2,U,d0. L1 ⋕[d0, U] L2 →
208                         ∀K1,K2,d,e. ⇩[d, e] L1 ≡ K1 → ⇩[d, e] L2 ≡ K2 →
209                         ∀T. ⇧[d, e] T ≡ U → d ≤ d0 → d0 ≤ d + e → K1 ⋕[d, T] K2.
210 #L1 #L2 #U #d0 #H elim H -L1 -L2 -U -d0
211 [ #L1 #L2 #d0 #k #HL12 #K1 #K2 #d #e #HLK1 #HLK2 #X #H #_ #_ >(lift_inv_sort2 … H) -X
212   lapply (ldrop_fwd_length_eq1 … HLK1 HLK2 HL12) -L1 -L2 -d0 -e
213   /2 width=1 by lleq_sort/
214 | #I1 #I2 #L1 #L2 #K11 #K22 #W1 #W2 #d0 #i #Hid0 #HLK11 #HLK22 #_ #_ #IHW1 #IHW2 #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hd0 #Hde elim (lift_inv_lref2 … H) -H
215   * #Hid #H destruct
216   [ elim (ldrop_conf_lt … HLK1 … HLK11) // -L1
217     elim (ldrop_conf_lt … HLK2 … HLK22) // -L2 -Hid0
218     #L2 #V2 #HKL2 #HKL22 #HVW2 #L1 #V1 #HKL1 #HKL11 #HVW1
219     @(lleq_skip … HKL1 HKL2) -HKL1 -HKL2 //
220     /3 width=6 by arith_k_dx, monotonic_le_minus_l2/ (**) (* full auto fails *)
221   | -I1 -I2 -L1 -L2 -K11 -K22 -W1 -W2 -Hd0 elim (lt_refl_false i)
222     /3 width=3 by lt_to_le_to_lt, transitive_le/ (**) (* slow *) 
223   ]
224 | #I #L1 #L2 #K11 #K22 #W #d0 #i #Hid0 #HLK11 #HLK22 #HW #_ #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hd0 #Hde elim (lift_inv_lref2 … H) -H
225   * #Hid #H destruct
226   [ -I -L1 -L2 -K11 -K22 -W -Hde elim (lt_refl_false i)
227     /3 width=3 by lt_to_le_to_lt, transitive_le/ (**) (* slow *)
228   | lapply (ldrop_conf_ge … HLK1 … HLK11 ?) // -L1
229     lapply (ldrop_conf_ge … HLK2 … HLK22 ?) // -L2 -Hid0 -Hd0 -Hde
230     elim (le_inv_plus_l … Hid) -Hid /2 width=7 by lleq_lref/
231   ]
232 | #L1 #L2 #d0 #i #HL1 #HL2 #HL12 #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hd0 #Hde elim (lift_inv_lref2 … H) -H
233   * #_ #H destruct
234   lapply (ldrop_fwd_length_eq1 … HLK1 HLK2 HL12)
235   [ lapply (ldrop_fwd_length_le4 … HLK1) -HLK1
236     lapply (ldrop_fwd_length_le4 … HLK2) -HLK2
237     #HKL2 #HKL1 #HK12 @lleq_free // /2 width=3 by transitive_le/ (**) (* full auto too slow *)
238   | lapply (ldrop_fwd_length … HLK1) -HLK1 #H >H in HL1; -H
239     lapply (ldrop_fwd_length … HLK2) -HLK2 #H >H in HL2; -H
240     /3 width=1 by lleq_free, le_plus_to_minus_r/
241   ]
242 | #L1 #L2 #d0 #p #HL12 #K1 #K2 #d #e #HLK1 #HLK2 #X #H #_ #_ >(lift_inv_gref2 … H) -X
243   lapply (ldrop_fwd_length_eq1 … HLK1 HLK2 HL12) -L1 -L2 -d0 -e
244   /2 width=1 by lleq_gref/
245 | #a #I #L1 #L2 #W #U #d0 #_ #_ #IHW #IHU #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hd0 #Hde elim (lift_inv_bind2 … H) -H
246   #V #T #HVW #HTU #H destruct
247   @lleq_bind [ /2 width=5 by/ ] -IHW
248   @(IHU … HTU) -IHU -HTU /2 width=1 by ldrop_skip, le_S_S/ (**) (* full auto too slow *)
249 | #I #L1 #L2 #W #U #d0 #_ #_ #IHW #IHU #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hd0 #Hde elim (lift_inv_flat2 … H) -H
250   #V #T #HVW #HTU #H destruct /3 width=6 by lleq_flat/
251 ]
252 qed-.
253
254 (* Advanced properties ******************************************************)
255
256 lemma lleq_lift_le: ∀K1,K2,T,d0. K1 ⋕[d0, T] K2 →
257                     ∀L1,L2,d,e. ⇩[d, e] L1 ≡ K1 → ⇩[d, e] L2 ≡ K2 →
258                     ∀U. ⇧[d, e] T ≡ U → d0 ≤ d → L1 ⋕[d0, U] L2.
259 #K1 #K2 #T #d0 #H elim H -K1 -K2 -T -d0
260 [ #K1 #K2 #d0 #k #HK12 #L1 #L2 #d #e #HLK1 #HLK2 #X #H #_ >(lift_inv_sort1 … H) -X
261   lapply (ldrop_fwd_length_eq2 … HLK1 HLK2 HK12) -K1 -K2 -d
262   /2 width=1 by lleq_sort/
263 | #I1 #I2 #K1 #K2 #K11 #K22 #V1 #V2 #d0 #i #Hid0 #HK11 #HK22 #_ #_ #IHV1 #IHV2 #L1 #L2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_lref1 … H) -H
264   * #Hdi #H destruct
265   [ elim (ldrop_trans_lt … HLK1 … HK11) // -K1
266     elim (ldrop_trans_lt … HLK2 … HK22) // -K2
267     #K2 #W2 #HLK2 #HK22 #HVW2 #K1 #W1 #HLK1 #HK11 #HVW1 -Hdi
268     @(lleq_skip … HLK1 HLK2) // /3 width=6 by monotonic_le_minus_l2/ (**) (* full auto fails *)
269   | elim (lt_refl_false i) -I1 -I2 -L1 -L2 -K1 -K2 -K11 -K22 -V1 -V2 -e
270     /3 width=3 by lt_to_le_to_lt, transitive_le/ (**) (* slow *)
271   ]
272 | #I #K1 #K2 #K11 #K22 #V #d0 #i #Hid0 #HK11 #HK22 #HV #IHV #L1 #L2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_lref1 … H) -H
273   * #Hdi #H destruct [ -HV | -IHV ]
274   [ elim (ldrop_trans_lt … HLK1 … HK11) // -K1 #K1 #W #HLK1 #HK11 #HVW
275     elim (ldrop_trans_lt … HLK2 … HK22) // -Hdi -K2 #K2 #W2 #HLK2 #HK22 #HVW2
276     lapply (lift_mono … HVW2 … HVW) -HVW2 #H destruct /3 width=12 by lleq_lref/
277   | lapply (ldrop_trans_ge … HLK1 … HK11 ?) // -K1
278     lapply (ldrop_trans_ge … HLK2 … HK22 ?) // -Hdi -K2
279     /3 width=7 by lleq_lref, transitive_le/
280   ]
281 | #K1 #K2 #d0 #i #HK1 #HK2 #HK12 #L1 #L2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_lref1 … H) -H
282   * #Hid #H destruct
283   lapply (ldrop_fwd_length_eq2 … HLK1 HLK2 HK12) -HK12
284   [ /3 width=6 by lleq_free, ldrop_fwd_be/
285   | lapply (ldrop_fwd_length … HLK1) -HLK1 #HLK1
286     lapply (ldrop_fwd_length … HLK2) -HLK2 #HLK2
287     @lleq_free [ >HLK1 | >HLK2 ] -Hid -HLK1 -HLK2 /2 width=1 by monotonic_le_plus_r/ (**) (* explicit constructor *)
288   ]
289 | #K1 #K2 #d0 #p #HK12 #L1 #L2 #d #e #HLK1 #HLK2 #X #H #_ >(lift_inv_gref1 … H) -X
290   lapply (ldrop_fwd_length_eq2 … HLK1 HLK2 HK12) -K1 -K2 -d -e
291   /2 width=1 by lleq_gref/
292 | #a #I #K1 #K2 #V #T #d0 #_ #_ #IHV #IHT #L1 #L2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_bind1 … H) -H
293   #W #U #HVW #HTU #H destruct /4 width=6 by lleq_bind, ldrop_skip, le_S_S/
294 | #I #K1 #K2 #V #T #d0 #_ #_ #IHV #IHT #L1 #L2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_flat1 … H) -H
295   #W #U #HVW #HTU #H destruct /3 width=6 by lleq_flat/
296 ]
297 qed-.
298
299 lemma lleq_lift_ge: ∀K1,K2,T,d0. K1 ⋕[d0, T] K2 →
300                     ∀L1,L2,d,e. ⇩[d, e] L1 ≡ K1 → ⇩[d, e] L2 ≡ K2 →
301                     ∀U. ⇧[d, e] T ≡ U → d ≤ d0 → L1 ⋕[d0+e, U] L2.
302 #K1 #K2 #T #d0 #H elim H -K1 -K2 -T -d0
303 [ #K1 #K2 #d0 #k #HK12 #L1 #L2 #d #e #HLK1 #HLK2 #X #H #_ >(lift_inv_sort1 … H) -X
304   lapply (ldrop_fwd_length_eq2 … HLK1 HLK2 HK12) -K1 -K2 -d
305   /2 width=1 by lleq_sort/
306 | #I1 #I2 #K1 #K2 #K11 #K22 #V1 #V2 #d0 #i #hid0 #HK11 #HK22 #HV1 #HV2 #IHV1 #IHV2 #L1 #L2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_lref1 … H) -H
307   * #Hdi #H destruct [ -HV1 -HV2 | -IHV1 -IHV2 ]
308   [ elim (ldrop_trans_lt … HLK1 … HK11) // -K1 #K1 #W1 #HLK1 #HK11 #HVW1
309     elim (ldrop_trans_lt … HLK2 … HK22) // -K2 #K2 #W2 #HLK2 #HK22 #HVW2
310     @(lleq_skip … HLK1 HLK2) -HLK1 -HLK2 (**) (* explicit constructor *)
311     [ /2 width=3 by lt_to_le_to_lt/ ]
312     >arith_i /3 width=5 by monotonic_le_minus_l2/
313   | lapply (ldrop_trans_ge_comm … HLK1 … HK11 ?) // -K1
314     lapply (ldrop_trans_ge_comm … HLK2 … HK22 ?) // -K2
315     /4 width=10 by lleq_skip, monotonic_lt_plus_l/
316   ]
317 | #I #K1 #K2 #K11 #K22 #V #d0 #i #Hid0 #HK11 #HK22 #HV #_ #L1 #L2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_lref1 … H) -H
318   * #Hid #H destruct
319   [ elim (lt_refl_false i) -I -L1 -L2 -K1 -K2 -K11 -K22 -V -e
320     /3 width=3 by lt_to_le_to_lt, transitive_le/ (**) (* slow *)
321   | lapply (ldrop_trans_ge … HLK1 … HK11 ?) // -K1
322     lapply (ldrop_trans_ge … HLK2 … HK22 ?) // -Hid -K2
323     /3 width=7 by lleq_lref, monotonic_le_plus_l/
324   ]
325 | #K1 #K2 #d0 #i #HK1 #HK2 #HK12 #L1 #L2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_lref1 … H) -H
326   * #Hid #H destruct
327   lapply (ldrop_fwd_length_eq2 … HLK1 HLK2 HK12) -HK12
328   [ /3 width=6 by lleq_free, ldrop_fwd_be/
329   | lapply (ldrop_fwd_length … HLK1) -HLK1 #HLK1
330     lapply (ldrop_fwd_length … HLK2) -HLK2 #HLK2
331     @lleq_free [ >HLK1 | >HLK2 ] -Hid -HLK1 -HLK2 /2 width=1 by monotonic_le_plus_r/ (**) (* explicit constructor *)
332   ]
333 | #K1 #K2 #d0 #p #HK12 #L1 #L2 #d #e #HLK1 #HLK2 #X #H #_ >(lift_inv_gref1 … H) -X
334   lapply (ldrop_fwd_length_eq2 … HLK1 HLK2 HK12) -K1 -K2 -d
335   /2 width=1 by lleq_gref/
336 | #a #I #K1 #K2 #V #T #d0 #_ #_ #IHV #IHT #L1 #L2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_bind1 … H) -H
337   #W #U #HVW #HTU #H destruct /4 width=5 by lleq_bind, ldrop_skip, le_minus_to_plus/
338 | #I #K1 #K2 #V #T #d0 #_ #_ #IHV #IHT #L1 #L2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_flat1 … H) -H
339   #W #U #HVW #HTU #H destruct /3 width=5 by lleq_flat/
340 ]
341 qed-.
342
343 lemma lleq_be: ∀L1,L2,U,d0. L1 ⋕[d0, U] L2 →
344                ∀K1,K2,d,e. ⇩[d, e] L1 ≡ K1 → ⇩[d, e] L2 ≡ K2 →
345                ∀T. ⇧[d, e] T ≡ U → d ≤ d0 → d0 ≤ d + e → L1 ⋕[d, U] L2.
346 #L1 #L2 #U #d0 #H elim H -L1 -L2 -U -d0
347 /2 width=1 by lleq_sort, lleq_free, lleq_gref/
348 [ #I1 #I2 #L1 #L2 #K11 #K22 #W1 #W2 #d0 #i #Hid0 #HLK11 #HLK22 #_ #_ #IHW1 #IHW2 #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hd0 #Hd0de elim (lift_inv_lref2 … H) -H
349   * #Hid #H destruct [ -Hid0 | -Hd0 ]
350   [ elim (ldrop_conf_lt … HLK1 … HLK11) // -HLK1
351     elim (ldrop_conf_lt … HLK2 … HLK22) // -HLK2
352     #L2 #V2 #_ #HKL22 #HVW2 #L1 #V1 #_ #HKL21 #HVW1
353     @(lleq_skip … HLK11 HLK22) -HLK11 -HLK22 //
354     /3 width=8 by arith_k_dx, monotonic_le_minus_l2/ (**) (* full auto fails *)
355   | -I1 -I2 -K11 -K22 -K1 -K2 -W1 -W2 elim (lt_refl_false … i) -L1 -L2
356     @(lt_to_le_to_lt … Hid0) -Hid0 /2 width=3 by transitive_le/ (**) (* full auto too slow *)
357   ]
358 | #I #L1 #L2 #K11 #K22 #W #d0 #i #Hid0 #HLK11 #HLK22 #HW #_ #K1 #K2 #d #e #_ #_ #X #H #Hd0 #_ elim (lift_inv_lref2 … H) -H
359   * #Hid #H destruct
360   [ -I -K1 -K2 -K11 -K22 -W elim (lt_refl_false i)
361     @(lt_to_le_to_lt … Hid) -Hid /2 width=3 by transitive_le/ (**) (* full auto too slow *)
362   | -d0 /3 width=7 by lleq_lref, le_plus_b/
363   ]
364 | #a #I #L1 #L2 #W #U #d0 #_ #_ #IHW #IHU #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hd0 #Hde elim (lift_inv_bind2 … H) -H
365   #V #T #HVW #HTU #H destruct
366   @lleq_bind [ /2 width=8 by/ ] -IHW
367   @(IHU … HTU) -IHU -HTU /2 width=2 by ldrop_skip, le_S_S/ (**) (* full auto too slow *)
368 | #I #L1 #L2 #W #U #d0 #_ #_ #IHW #IHU #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hd0 #Hde elim (lift_inv_flat2 … H) -H
369   #V #T #HVW #HTU #H destruct /3 width=8 by lleq_flat/
370 ]
371 qed-.
372
373 axiom- lleq_dec: ∀T,L1,L2,d. Decidable (L1 ⋕[d, T] L2).
374 (*
375 #T #L1 @(f2_ind … rfw … L1 T) -L1 -T
376 #n #IH #L1 * *
377 [ #k #Hn #L2 elim (eq_nat_dec (|L1|) (|L2|)) /3 width=1 by or_introl, lleq_sort/
378 | #i #H1 #L2 elim (eq_nat_dec (|L1|) (|L2|))
379   [ #HL12 #d elim (lt_or_ge i d) /3 width=1 by lleq_skip, or_introl/
380     #Hdi elim (lt_or_ge i (|L1|))
381     #HiL1 elim (lt_or_ge i (|L2|)) /3 width=1 by or_introl, lleq_free/
382     #HiL2 elim (ldrop_O1_lt … HiL2)
383     #I2 #K2 #V2 #HLK2 elim (ldrop_O1_lt … HiL1)
384     #I1 #K1 #V1 #HLK1 elim (eq_bind2_dec I2 I1)
385     [ #H2 elim (eq_term_dec V2 V1)
386       [ #H3 elim (IH K1 V1 … K2 0) destruct
387         /3 width=7 by lleq_lref, ldrop_fwd_rfw, or_introl/
388       ]
389     ]
390     -IH #H3 @or_intror
391     #H elim (lleq_inv_lref … H) -H [1,3,4,6,7,9: * ]
392     [1,3,5,7,8,9: /3 width=4 by lt_to_le_to_lt, lt_refl_false/ ]
393     #I0 #X1 #X2 #V0 #HLX1 #HLX2 #HX12
394     lapply (ldrop_mono … HLX1 … HLK1) -HLX1 -HLK1
395     lapply (ldrop_mono … HLX2 … HLK2) -HLX2 -HLK2
396     #H #H0 destruct /2 width=1 by/
397   ]
398 | #p #Hn #L2 elim (eq_nat_dec (|L1|) (|L2|)) /3 width=1 by or_introl, lleq_gref/
399 | #a #I #V #T #Hn #L2 #d destruct
400   elim (IH L1 V … L2 d) /2 width=1 by/
401   elim (IH (L1.ⓑ{I}V) T … (L2.ⓑ{I}V) (d+1)) -IH /3 width=1 by or_introl, lleq_bind/
402   #H1 #H2 @or_intror
403   #H elim (lleq_inv_bind … H) -H /2 width=1 by/
404 | #I #V #T #Hn #L2 #d destruct
405   elim (IH L1 V … L2 d) /2 width=1 by/
406   elim (IH L1 T … L2 d) -IH /3 width=1 by or_introl, lleq_flat/
407   #H1 #H2 @or_intror
408   #H elim (lleq_inv_flat … H) -H /2 width=1 by/
409 ]
410 -n /4 width=3 by lleq_fwd_length, or_intror/
411 qed-.
412 *)
413 (* Main properties **********************************************************)
414
415 axiom- lleq_trans: ∀d,T. Transitive … (lleq d T).
416 (*
417 #d #T #L1 #L #H elim H -d -T -L1 -L
418 /4 width=5 by lleq_fwd_length, lleq_gref, lleq_sort, trans_eq/
419 [ #L1 #L #d #i #Hid #HL1 #L2 #H lapply (lleq_fwd_length … H)
420   #HL2 elim (lleq_inv_lref … H) -H /2 width=1 by lleq_skip/
421 | #I #L1 #L #K1 #K #V #d #i #Hdi #HLK1 #HLK #_ #IHK1 #L2 #H elim (lleq_inv_lref … H) -H
422   [ -HLK1 -IHK1 * #HLi #_ elim (lt_refl_false i)
423     /3 width=5 by ldrop_fwd_length_lt2, lt_to_le_to_lt/ (**) (* slow *)
424   | -K1 -K #Hid elim (lt_refl_false i) /2 width=3 by lt_to_le_to_lt/
425   | * #I0 #K0 #K2 #V0 #HLK0 #HLK2 #HK12 lapply (ldrop_mono … HLK0 … HLK) -L
426     #H destruct /3 width=7 by lleq_lref/
427   ]
428 | #L1 #L #d #i #HL1i #HLi #HL #L2 #H lapply (lleq_fwd_length … H)
429   #HL2 elim (lleq_inv_lref … H) -H /2 width=1 by lleq_free/
430 | #a #I #L1 #L #V #T #d #_ #_ #IHV #IHT #L2 #H elim (lleq_inv_bind … H) -H
431   /3 width=1 by lleq_bind/
432 | #I #L1 #L #V #T #d #_ #_ #IHV #IHT #L2 #H elim (lleq_inv_flat … H) -H
433   /3 width=1 by lleq_flat/
434 ]
435 qed-.
436 *)
437 theorem lleq_canc_sn: ∀L,L1,L2,T,d. L ⋕[d, T] L1→ L ⋕[d, T] L2 → L1 ⋕[d, T] L2.
438 /3 width=3 by lleq_trans, lleq_sym/ qed-.
439
440 theorem lleq_canc_dx: ∀L1,L2,L,T,d. L1 ⋕[d, T] L → L2 ⋕[d, T] L → L1 ⋕[d, T] L2.
441 /3 width=3 by lleq_trans, lleq_sym/ qed-.