]> matita.cs.unibo.it Git - helm.git/blob - matita/matita/lib/lambda/terms/relocation.ma
3d42e8a5c7006555befa4cd55751b4c93b369b34
[helm.git] / matita / matita / lib / lambda / terms / relocation.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 "lambda/terms/term.ma".
16
17 (* RELOCATION ***************************************************************)
18
19 (* Policy: level metavariables : d, e
20            height metavariables: h, k
21 *)
22 (* Note: indexes start at zero *)
23 let rec lift h d M on M ≝ match M with
24 [ VRef i   ⇒ #(tri … i d i (i + h) (i + h))
25 | Abst A   ⇒ 𝛌. (lift h (d+1) A)
26 | Appl B A ⇒ @(lift h d B). (lift h d A)
27 ].
28
29 interpretation "relocation" 'Lift h d M = (lift h d M).
30
31 lemma lift_vref_lt: ∀d,h,i. i < d → ↑[d, h] #i = #i.
32 normalize /3 width=1/
33 qed.
34
35 lemma lift_vref_ge: ∀d,h,i. d ≤ i → ↑[d, h] #i = #(i+h).
36 #d #h #i #H elim (le_to_or_lt_eq … H) -H
37 normalize // /3 width=1/
38 qed.
39
40 lemma lift_id: ∀M,d. ↑[d, 0] M = M.
41 #M elim M -M
42 [ #i #d elim (lt_or_ge i d) /2 width=1/
43 | /3 width=1/
44 | /3 width=1/
45 ]
46 qed.
47
48 lemma lift_inv_vref_lt: ∀j,d. j < d → ∀h,M. ↑[d, h] M = #j → M = #j.
49 #j #d #Hjd #h * normalize
50 [ #i elim (lt_or_eq_or_gt i d) #Hid
51   [ >(tri_lt ???? … Hid) -Hid -Hjd //
52   | #H destruct >tri_eq in Hjd; #H
53     elim (plus_lt_false … H)
54   | >(tri_gt ???? … Hid)
55     lapply (transitive_lt … Hjd Hid) -d #H #H0 destruct
56     elim (plus_lt_false … H)
57   ]
58 | #A #H destruct
59 | #B #A #H destruct
60 ]
61 qed.
62
63 lemma lift_inv_vref_ge: ∀j,d. d ≤ j → ∀h,M. ↑[d, h] M = #j →
64                         d + h ≤ j ∧ M = #(j-h).
65 #j #d #Hdj #h * normalize
66 [ #i elim (lt_or_eq_or_gt i d) #Hid
67   [ >(tri_lt ???? … Hid) #H destruct
68     lapply (le_to_lt_to_lt … Hdj Hid) -Hdj -Hid #H
69     elim (lt_refl_false … H)
70   | #H -Hdj destruct /2 width=1/
71   | >(tri_gt ???? … Hid) #H -Hdj destruct /4 width=1/
72   ]
73 | #A #H destruct
74 | #B #A #H destruct
75 ]
76 qed-.
77
78 lemma lift_inv_vref_be: ∀j,d,h. d ≤ j → j < d + h → ∀M. ↑[d, h] M = #j → ⊥.
79 #j #d #h #Hdj #Hjdh #M #H elim (lift_inv_vref_ge … H) -H // -Hdj #Hdhj #_ -M
80 lapply (lt_to_le_to_lt … Hjdh Hdhj) -d -h #H
81 elim (lt_refl_false … H)
82 qed-.
83
84 lemma lift_inv_vref_ge_plus: ∀j,d,h. d + h ≤ j →
85                              ∀M. ↑[d, h] M = #j → M = #(j-h).
86 #j #d #h #Hdhj #M #H elim (lift_inv_vref_ge … H) -H // -M /2 width=2/
87 qed.
88
89 lemma lift_inv_abst: ∀C,d,h,M. ↑[d, h] M = 𝛌.C →
90                      ∃∃A. ↑[d+1, h] A = C & M = 𝛌.A.
91 #C #d #h * normalize
92 [ #i #H destruct
93 | #A #H destruct /2 width=3/
94 | #B #A #H destruct
95 ]
96 qed-.
97
98 lemma lift_inv_appl: ∀D,C,d,h,M. ↑[d, h] M = @D.C →
99                      ∃∃B,A. ↑[d, h] B = D & ↑[d, h] A = C & M = @B.A.
100 #D #C #d #h * normalize
101 [ #i #H destruct
102 | #A #H destruct
103 | #B #A #H destruct /2 width=5/
104 ]
105 qed-.
106
107 theorem lift_lift_le: ∀h1,h2,M,d1,d2. d2 ≤ d1 →
108                       ↑[d2, h2] ↑[d1, h1] M = ↑[d1 + h2, h1] ↑[d2, h2] M.
109 #h1 #h2 #M elim M -M
110 [ #i #d1 #d2 #Hd21 elim (lt_or_ge i d2) #Hid2
111   [ lapply (lt_to_le_to_lt … Hid2 Hd21) -Hd21 #Hid1
112     >(lift_vref_lt … Hid1) >(lift_vref_lt … Hid2)
113     >lift_vref_lt // /2 width=1/
114   | >(lift_vref_ge … Hid2) elim (lt_or_ge i d1) #Hid1
115     [ >(lift_vref_lt … Hid1) >(lift_vref_ge … Hid2)
116       >lift_vref_lt // -d2 /2 width=1/
117     | >(lift_vref_ge … Hid1) >lift_vref_ge /2 width=1/
118       >lift_vref_ge // /2 width=1/
119     ]
120   ]
121 | normalize #A #IHA #d1 #d2 #Hd21 >IHA // /2 width=1/
122 | normalize #B #A #IHB #IHA #d1 #d2 #Hd21 >IHB >IHA //
123 ]
124 qed.
125
126 theorem lift_lift_be: ∀h1,h2,M,d1,d2. d1 ≤ d2 → d2 ≤ d1 + h1 →
127                       ↑[d2, h2] ↑[d1, h1] M = ↑[d1, h1 + h2] M.
128 #h1 #h2 #M elim M -M
129 [ #i #d1 #d2 #Hd12 #Hd21 elim (lt_or_ge i d1) #Hid1
130   [ lapply (lt_to_le_to_lt … Hid1 Hd12) -Hd12 -Hd21 #Hid2
131     >(lift_vref_lt … Hid1) >(lift_vref_lt … Hid1) /2 width=1/
132   | lapply (transitive_le … (i+h1) Hd21 ?) -Hd21 -Hd12 /2 width=1/ #Hd2
133     >(lift_vref_ge … Hid1) >(lift_vref_ge … Hid1) /2 width=1/
134   ]
135 | normalize #A #IHA #d1 #d2 #Hd12 #Hd21 >IHA // /2 width=1/
136 | normalize #B #A #IHB #IHA #d1 #d2 #Hd12 #Hd21 >IHB >IHA //
137 ]
138 qed.
139
140 theorem lift_lift_ge: ∀h1,h2,M,d1,d2. d1 + h1 ≤ d2 →
141                       ↑[d2, h2] ↑[d1, h1] M = ↑[d1, h1] ↑[d2 - h1, h2] M.
142 #h1 #h2 #M #d1 #d2 #Hd12
143 >(lift_lift_le h2 h1) /2 width=1/ <plus_minus_m_m // /2 width=2/
144 qed.
145
146 (* Note: this is "∀h,d. injective … (lift h d)" *)
147 theorem lift_inj: ∀h,M1,M2,d. ↑[d, h] M2 = ↑[d, h] M1 → M2 = M1.
148 #h #M1 elim M1 -M1
149 [ #i #M2 #d #H elim (lt_or_ge i d) #Hid
150   [ >(lift_vref_lt … Hid) in H; #H
151     >(lift_inv_vref_lt … Hid … H) -M2 -d -h //
152   | >(lift_vref_ge … Hid) in H; #H
153     >(lift_inv_vref_ge_plus … H) -M2 // /2 width=1/
154   ]
155 | normalize #A1 #IHA1 #M2 #d #H
156   elim (lift_inv_abst … H) -H #A2 #HA12 #H destruct
157   >(IHA1 … HA12) -IHA1 -A2 //
158 | normalize #B1 #A1 #IHB1 #IHA1 #M2 #d #H
159   elim (lift_inv_appl … H) -H #B2 #A2 #HB12 #HA12 #H destruct
160   >(IHB1 … HB12) -IHB1 -B2 >(IHA1 … HA12) -IHA1 -A2 //
161 ]
162 qed-.
163
164 theorem lift_inv_lift_le: ∀h1,h2,M1,M2,d1,d2. d2 ≤ d1 →
165                           ↑[d2, h2] M2 = ↑[d1 + h2, h1] M1 →
166                           ∃∃M. ↑[d1, h1] M = M2 & ↑[d2, h2] M = M1.
167 #h1 #h2 #M1 elim M1 -M1
168 [ #i #M2 #d1 #d2 #Hd21 elim (lt_or_ge i (d1+h2)) #Hid1
169   [ >(lift_vref_lt … Hid1) elim (lt_or_ge i d2) #Hid2 #H
170     [ lapply (lt_to_le_to_lt … Hid2 Hd21) -Hd21 -Hid1 #Hid1
171       >(lift_inv_vref_lt … Hid2 … H) -M2 /3 width=3/
172     | elim (lift_inv_vref_ge … H) -H -Hd21 // -Hid2 #Hdh2i #H destruct
173       elim (le_inv_plus_l … Hdh2i) -Hdh2i #Hd2i #Hh2i
174       @(ex2_intro … (#(i-h2))) [ /4 width=1/ ] -Hid1
175       >lift_vref_ge // -Hd2i /3 width=1/ (**) (* auto: needs some help here *)
176     ]
177   | elim (le_inv_plus_l … Hid1) #Hd1i #Hh2i
178     lapply (transitive_le (d2+h2) … Hid1) /2 width=1/ -Hd21 #Hdh2i
179     elim (le_inv_plus_l … Hdh2i) #Hd2i #_
180     >(lift_vref_ge … Hid1) #H -Hid1
181     >(lift_inv_vref_ge_plus … H) -H /2 width=3/ -Hdh2i
182     @(ex2_intro … (#(i-h2))) (**) (* auto: needs some help here *)
183     [ >lift_vref_ge // -Hd1i /3 width=1/
184     | >lift_vref_ge // -Hd2i -Hd1i /3 width=1/
185     ]
186   ]
187 | normalize #A1 #IHA1 #M2 #d1 #d2 #Hd21 #H
188   elim (lift_inv_abst … H) -H >plus_plus_comm_23 #A2 #HA12 #H destruct
189   elim (IHA1 … HA12) -IHA1 -HA12 /2 width=1/ -Hd21 #A #HA2 #HA1
190   @(ex2_intro … (𝛌.A)) normalize //
191 | normalize #B1 #A1 #IHB1 #IHA1 #M2 #d1 #d2 #Hd21 #H
192   elim (lift_inv_appl … H) -H #B2 #A2 #HB12 #HA12 #H destruct
193   elim (IHB1 … HB12) -IHB1 -HB12 // #B #HB2 #HB1
194   elim (IHA1 … HA12) -IHA1 -HA12 // -Hd21 #A #HA2 #HA1
195   @(ex2_intro … (@B.A)) normalize //
196 ]
197 qed-.
198
199 theorem lift_inv_lift_be: ∀h1,h2,M1,M2,d1,d2. d1 ≤ d2 → d2 ≤ d1 + h1 →
200                           ↑[d2, h2] M2 = ↑[d1, h1 + h2] M1 → ↑[d1, h1] M1 = M2.
201 #h1 #h2 #M1 elim M1 -M1
202 [ #i #M2 #d1 #d2 #Hd12 #Hd21 elim (lt_or_ge i d1) #Hid1
203   [ lapply (lt_to_le_to_lt … Hid1 Hd12) -Hd12 -Hd21 #Hid2
204     >(lift_vref_lt … Hid1) #H >(lift_inv_vref_lt … Hid2 … H) -h2 -M2 -d2 /2 width=1/
205   | lapply (transitive_le … (i+h1) Hd21 ?) -Hd12 -Hd21 /2 width=1/ #Hd2
206     >(lift_vref_ge … Hid1) #H >(lift_inv_vref_ge_plus … H) -M2 /2 width=1/
207   ]
208 | normalize #A1 #IHA1 #M2 #d1 #d2 #Hd12 #Hd21 #H
209   elim (lift_inv_abst … H) -H #A #HA12 #H destruct
210   >(IHA1 … HA12) -IHA1 -HA12 // /2 width=1/
211 | normalize #B1 #A1 #IHB1 #IHA1 #M2 #d1 #d2 #Hd12 #Hd21 #H
212   elim (lift_inv_appl … H) -H #B #A #HB12 #HA12 #H destruct
213   >(IHB1 … HB12) -IHB1 -HB12 // >(IHA1 … HA12) -IHA1 -HA12 //
214 ]
215 qed-.
216
217 theorem lift_inv_lift_ge: ∀h1,h2,M1,M2,d1,d2. d1 + h1 ≤ d2 →
218                           ↑[d2, h2] M2 = ↑[d1, h1] M1 →
219                           ∃∃M. ↑[d1, h1] M = M2 & ↑[d2 - h1, h2] M = M1.
220 #h1 #h2 #M1 #M2 #d1 #d2 #Hd12 #H
221 elim (le_inv_plus_l … Hd12) -Hd12 #Hd12 #Hh1d2
222 lapply (sym_eq term … H) -H >(plus_minus_m_m … Hh1d2) in ⊢ (???%→?); -Hh1d2 #H
223 elim (lift_inv_lift_le … Hd12 … H) -H -Hd12 /2 width=3/
224 qed-.
225
226 definition liftable: predicate (relation term) ≝ λR.
227                      ∀h,M1,M2. R M1 M2 → ∀d. R (↑[d, h] M1) (↑[d, h] M2).
228
229 definition deliftable_sn: predicate (relation term) ≝ λR.
230                           ∀h,N1,N2. R N1 N2 → ∀d,M1. ↑[d, h] M1 = N1 →
231                           ∃∃M2. R M1 M2 & ↑[d, h] M2 = N2.
232
233 lemma star_liftable: ∀R. liftable R → liftable (star … R).
234 #R #HR #h #M1 #M2 #H elim H -M2 // /3 width=3/
235 qed.
236
237 lemma star_deliftable_sn: ∀R. deliftable_sn R → deliftable_sn (star … R).
238 #R #HR #h #N1 #N2 #H elim H -N2 /2 width=3/
239 #N #N2 #_ #HN2 #IHN1 #d #M1 #HMN1
240 elim (IHN1 … HMN1) -N1 #M #HM1 #HMN
241 elim (HR … HN2 … HMN) -N /3 width=3/
242 qed-.
243
244 lemma lstar_liftable: ∀S,R. (∀a. liftable (R a)) →
245                       ∀l. liftable (lstar S … R l).
246 #S #R #HR #l #h #M1 #M2 #H
247 @(lstar_ind_l … l M1 H) -l -M1 // /3 width=3/
248 qed.
249
250 lemma lstar_deliftable_sn: ∀S,R. (∀a. deliftable_sn (R a)) →
251                            ∀l. deliftable_sn (lstar S … R l).
252 #S #R #HR #l #h #N1 #N2 #H
253 @(lstar_ind_l … l N1 H) -l -N1 /2 width=3/
254 #a #l #N1 #N #HN1 #_ #IHN2 #d #M1 #HMN1
255 elim (HR … HN1 … HMN1) -N1 #M #HM1 #HMN
256 elim (IHN2 … HMN) -N /3 width=3/
257 qed-.