1 (**************************************************************************)
4 (* ||A|| A project by Andrea Asperti *)
6 (* ||I|| Developers: *)
7 (* ||T|| The HELM team. *)
8 (* ||A|| http://helm.cs.unibo.it *)
10 (* \ / This file is distributed under the terms of the *)
11 (* v GNU General Public License Version 2 *)
13 (**************************************************************************)
15 include "basic_2/relocation/ldrop_ldrop.ma".
16 include "basic_2/relocation/lleq.ma".
18 (* LAZY EQUIVALENCE FOR LOCAL ENVIRONMENTS **********************************)
20 (* Advanced inversion lemmas ************************************************)
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 &
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/
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 &
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/
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/
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/
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 →
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
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/
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/
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 →
100 /2 width=6 by lleq_inv_S_aux/ qed-.
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/
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 *)
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/
135 | #L1 #L2 #d0 #i #HL1 #HL2 #HL12 #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_lref2 … H) -H
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/
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/
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 //
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
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/
184 | #L1 #L2 #d0 #i #HL1 #HL2 #HL12 #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hded0 elim (lift_inv_lref2 … H) -H
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/
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/
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
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 *)
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
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/
232 | #L1 #L2 #d0 #i #HL1 #HL2 #HL12 #K1 #K2 #d #e #HLK1 #HLK2 #X #H #Hd0 #Hde elim (lift_inv_lref2 … H) -H
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/
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/
254 (* Advanced properties ******************************************************)
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
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 *)
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/
281 | #K1 #K2 #d0 #i #HK1 #HK2 #HK12 #L1 #L2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_lref1 … H) -H
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 *)
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/
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/
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
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/
325 | #K1 #K2 #d0 #i #HK1 #HK2 #HK12 #L1 #L2 #d #e #HLK1 #HLK2 #X #H #Hd0 elim (lift_inv_lref1 … H) -H
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 *)
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/
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 *)
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
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/
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/
373 axiom- lleq_dec: ∀T,L1,L2,d. Decidable (L1 ⋕[d, T] L2).
375 #T #L1 @(f2_ind … rfw … L1 T) -L1 -T
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/
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/
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/
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/
408 #H elim (lleq_inv_flat … H) -H /2 width=1 by/
410 -n /4 width=3 by lleq_fwd_length, or_intror/
413 (* Main properties **********************************************************)
415 axiom- lleq_trans: ∀d,T. Transitive … (lleq d T).
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/
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/
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-.
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-.