2 ||M|| This file is part of HELM, an Hypertextual, Electronic
3 ||A|| Library of Mathematics, developed at the Computer Science
4 ||T|| Department of the University of Bologna, Italy.
7 ||A|| This file is distributed under the terms of the
8 \ / GNU General Public License Version 2
10 V_______________________________________________________________ *)
12 include "basics/finset.ma".
13 include "basics/star.ma".
16 inductive FType (O:Type[0]): Type[0] ≝
18 | arrow : FType O → FType O → FType O.
20 inductive T (O:Type[0]) (D:O → FinSet): Type[0] ≝
21 | Val: ∀o:O.carr (D o) → T O D (* a value in a finset *)
22 | Rel: nat → T O D (* DB index, base is 0 *)
23 | App: T O D → T O D → T O D (* function, argument *)
24 | Lambda: FType O → T O D → T O D (* type, body *)
25 | Vec: FType O → list (T O D) → T O D (* type, body *)
28 let rec FinSet_of_FType O (D:O→FinSet) (ty:FType O) on ty : FinSet ≝
31 |arrow ty1 ty2 ⇒ FinFun (FinSet_of_FType O D ty1) (FinSet_of_FType O D ty2)
36 let rec size O D (M:T O D) on M ≝
40 |App P Q ⇒ size O D P + size O D Q + 1
41 |Lambda Ty P ⇒ size O D P + 1
42 |Vec Ty v ⇒ foldr ?? (λx,a. size O D x + a) 0 v +1
46 (* axiom pos_size: ∀M. 1 ≤ size M. *)
48 theorem Telim_size: ∀O,D.∀P: T O D → Prop.
49 (∀M. (∀N. size O D N < size O D M → P N) → P M) → ∀M. P M.
50 #O #D #P #H #M (cut (∀p,N. size O D N = p → P N))
52 #p @(nat_elim1 p) #m #H1 #N #sizeN @H #N0 #Hlt @(H1 (size O D N0)) //
56 ∀O: Type[0].∀D:O→FinSet.∀P:T O D→Prop.
57 (∀o:O.∀x:D o.P (Val O D o x)) →
59 (∀m,n:T O D.P m→P n→P (App O D m n)) →
60 (∀Ty:FType O.∀m:T O D.P m→P(Lambda O D Ty m)) →
61 (∀Ty:FType O.∀v:list (T O D).
62 (∀x:T O D. mem ? x v → P x) → P(Vec O D Ty v)) →
64 #O #D #P #Hval #Hrel #Happ #Hlam #Hvec @Telim_size #x cases x //
65 [ (* app *) #m #n #Hind @Happ @Hind // /2 by le_minus_to_plus/
66 | (* lam *) #ty #m #Hind @Hlam @Hind normalize //
67 | (* vec *) #ty #v #Hind @Hvec #x lapply Hind elim v
69 |#hd #tl #Hind1 #Hind2 *
70 [#Hx >Hx @Hind2 normalize //
71 |@Hind1 #N #H @Hind2 @(lt_to_le_to_lt … H) normalize //
78 (* arguments: k is the nesting depth (starts from 0), p is the lift *)
79 let rec lift O D t k p on t ≝
81 [ Val o a ⇒ Val O D o a
82 | Rel n ⇒ if (leb k n) then Rel O D (n+p) else Rel O D n
83 | App m n ⇒ App O D (lift O D m k p) (lift O D n k p)
84 | Lambda Ty n ⇒ Lambda O D Ty (lift O D n (S k) p)
85 | Vec Ty v ⇒ Vec O D Ty (map ?? (λx. lift O D x k p) v)
88 notation "↑ ^ n ( M )" non associative with precedence 40 for @{'Lift 0 $n $M}.
89 notation "↑ _ k ^ n ( M )" non associative with precedence 40 for @{'Lift $n $k $M}.
91 interpretation "Lift" 'Lift n k M = (lift ?? M k n).
93 let rec subst O D t k s on t ≝
95 [ Val o a ⇒ Val O D o a
96 | Rel n ⇒ if (leb k n) then
97 (if (eqb k n) then lift O D s 0 n else Rel O D (n-1))
99 | App m n ⇒ App O D (subst O D m k s) (subst O D n k s)
100 | Lambda T n ⇒ Lambda O D T (subst O D n (S k) s)
101 | Vec T v ⇒ Vec O D T (map ?? (λx. subst O D x k s) v)
104 (* notation "hvbox(M break [ k ≝ N ])"
105 non associative with precedence 90
106 for @{'Subst1 $M $k $N}. *)
108 interpretation "Subst" 'Subst1 M k N = (subst M k N).
111 let rec closed_k O D (t: T O D) k on t ≝
115 | App m n ⇒ (closed_k O D m k) ∧ (closed_k O D n k)
116 | Lambda T n ⇒ closed_k O D n (k+1)
117 | Vec T v ⇒ closed_list O D v k
120 and closed_list O D (l: list (T O D)) k on l ≝
123 | cons hd tl ⇒ closed_k O D hd k ∧ closed_list O D tl k
127 inductive is_closed (O:Type[0]) (D:O→FinSet): nat → T O D → Prop ≝
128 | cval : ∀k,o,a.is_closed O D k (Val O D o a)
129 | cval : ∀k,n. n < k → is_closed O D k (Rel O D n)
130 | capp : ∀k,n,m. is_closed O D k m → is_closed O D k n →
131 is_closed O D k (App O D m n)
132 | clam : ∀T,k,m. is_closed O D (k+1) m → is_closed O D k (Lambda O D T m)
133 | cvec: ∀T,k,v. (∀m. mem ? m v → is_closed O D k m) →
134 is_closed O D k (Vec O D T v).
136 lemma is_closed_rel: ∀O,D,n,k.
137 is_closed O D k (Rel O D n) → n < k.
138 #O #D #n #k #H inversion H
139 [#k0 #o #a #eqk #H destruct
140 |#k0 #n0 #ltn0 #eqk #H destruct //
141 |#k0 #M #N #_ #_ #_ #H destruct
142 |#T #k0 #M #_ #_ #H destruct
143 |#T #k0 #v #_ #_ #H destruct
148 (*** properties of lift and subst ***)
150 lemma lift_0: ∀O,D.∀t:T O D.∀k. lift O D t k 0 = t.
151 #O #D #t @(T_elim … t) normalize //
152 [#n #k cases (leb k n) normalize //
153 |#o #v #Hind #k @eq_f lapply Hind -Hind elim v //
154 #hd #tl #Hind #Hind1 normalize @eq_f2
155 [@Hind1 %1 //|@Hind #x #Hx @Hind1 %2 //]
159 axiom lift_closed: ∀O,D.∀t:T O D.∀k,p.
160 is_closed O D 0 t → lift O D t k p = t.
162 #O #D #t @(T_elim … t) normalize //
164 |#o #v #Hind #k @eq_f lapply Hind -Hind elim v //
165 #hd #tl #Hind #Hind1 normalize @eq_f2
166 [@Hind1 %1 //|@Hind #x #Hx @Hind1 %2 //]
170 let rec to_T O D ty on ty: FinSet_of_FType O D ty → T O D ≝
171 match ty return (λty.FinSet_of_FType O D ty → T O D) with
172 [atom o ⇒ λa.Val O D o a
173 |arrow ty1 ty2 ⇒ λa:FinFun ??.Vec O D ty1
174 (map ((FinSet_of_FType O D ty1)×(FinSet_of_FType O D ty2))
175 (T O D) (λp.to_T O D ty2 (snd … p)) (pi1 … a))
179 axiom inj_to_T: ∀O,D,ty,a1,a2. to_T O D ty a1 = to_T O D ty a2 → a1 = a2.
181 let rec assoc (A:FinSet) (B:Type[0]) (a:A) l1 l2 on l1 : option B ≝
184 | cons hd1 tl1 ⇒ match l2 with
186 | cons hd2 tl2 ⇒ if a==hd1 then Some ? hd2 else assoc A B a tl1 tl2
190 lemma same_assoc: ∀A,B,a,l1,v1,v2,N,N1.
191 assoc A B a l1 (v1@N::v2) = Some ? N ∧ assoc A B a l1 (v1@N1::v2) = Some ? N1
192 ∨ assoc A B a l1 (v1@N::v2) = assoc A B a l1 (v1@N1::v2).
193 #A #B #a #l1 #v1 #v2 #N #N1 lapply v1 -v1 elim l1
194 [#v1 %2 // |#hd #tl #Hind * normalize cases (a==hd) normalize /3/]
197 lemma assoc_to_mem: ∀A,B,a,l1,l2,b.
198 assoc A B a l1 l2 = Some ? b → mem ? b l2.
200 [#l2 #b normalize #H destruct
202 [#b normalize #H destruct
203 |#hd2 #tl2 #b normalize cases (a==hd1) normalize
204 [#H %1 destruct //|#H %2 @Hind @H]
209 inductive red (O:Type[0]) (D:O→FinSet) : T O D →T O D → Prop ≝
210 | rbeta: ∀P,M,N. red O D (App O D (Lambda O D P M) N) (subst O D M 0 N)
212 assoc (FinSet_of_FType O D ty) ? a (enum (FinSet_of_FType O D ty)) v = Some ? M →
213 red O D (App O D (Vec O D ty v) (to_T O D ty a)) M
214 | rappl: ∀M,M1,N. red O D M M1 → red O D (App O D M N) (App O D M1 N)
215 | rappr: ∀M,N,N1. red O D N N1 → red O D (App O D M N) (App O D M N1)
216 | rmem: ∀ty,M. red O D (Lambda O D ty M)
217 (Vec O D ty (map ?? (λa. subst O D M 0 (to_T O D ty a))
218 (enum (FinSet_of_FType O D ty))))
219 | rvec: ∀ty,N,N1,v,v1. red O D N N1 →
220 red O D (Vec O D ty (v@N::v1)) (Vec O D ty (v@N1::v1)).
222 (* some inversion cases *)
223 lemma red_vec: ∀O,D,ty,v,M.
224 red O D (Vec O D ty v) M → ∃N,N1,v1,v2.
225 red O D N N1 ∧ v = v1@N::v2 ∧ M = Vec O D ty (v1@N1::v2).
226 #O #D #ty #v #M #Hred inversion Hred
227 [#ty1 #M0 #N #H destruct
228 |#ty1 #v1 #a #M0 #_ #H destruct
229 |#M0 #M1 #N #_ #_ #H destruct
230 |#M0 #M1 #N #_ #_ #H destruct
231 |#ty1 #M0 #H destruct
232 |#ty1 #N #N1 #v1 #v2 #Hred1 #_ #H destruct #_ %{N} %{N1} %{v1} %{v2} /3/
236 lemma red_lambda: ∀O,D,ty,M,N.
237 red O D (Lambda O D ty M) N →
238 N = Vec O D ty (map ?? (λa. subst O D M 0 (to_T O D ty a))
239 (enum (FinSet_of_FType O D ty))).
240 #O #D #ty #M #N #Hred inversion Hred
241 [#ty1 #M0 #N #H destruct
242 |#ty1 #v1 #a #M0 #_ #H destruct
243 |#M0 #M1 #N #_ #_ #H destruct
244 |#M0 #M1 #N #_ #_ #H destruct
245 |#ty1 #M0 #H destruct #_ //
246 |#ty1 #N #N1 #v1 #v2 #Hred1 #_ #H destruct
250 lemma red_val: ∀O,D,ty,a,N.
251 red O D (Val O D ty a) N → False.
252 #O #D #ty #M #N #Hred inversion Hred
253 [#ty1 #M0 #N #H destruct
254 |#ty1 #v1 #a #M0 #_ #H destruct
255 |#M0 #M1 #N #_ #_ #H destruct
256 |#M0 #M1 #N #_ #_ #H destruct
257 |#ty1 #M0 #H destruct #_
258 |#ty1 #N #N1 #v1 #v2 #Hred1 #_ #H destruct
262 lemma red_rel: ∀O,D,n,N.
263 red O D (Rel O D n) N → False.
264 #O #D #n #N #Hred inversion Hred
265 [#ty1 #M0 #N #H destruct
266 |#ty1 #v1 #a #M0 #_ #H destruct
267 |#M0 #M1 #N #_ #_ #H destruct
268 |#M0 #M1 #N #_ #_ #H destruct
269 |#ty1 #M0 #H destruct #_
270 |#ty1 #N #N1 #v1 #v2 #Hred1 #_ #H destruct
274 lemma star_red_appl: ∀O,D,M,M1,N. star ? (red O D) M M1 →
275 star ? (red O D) (App O D M N) (App O D M1 N).
276 #O #D #M #N #N1 #H elim H //
277 #P #Q #Hind #HPQ #Happ %1[|@Happ] @rappl @HPQ
280 lemma star_red_appr: ∀O,D,M,N,N1. star ? (red O D) N N1 →
281 star ? (red O D) (App O D M N) (App O D M N1).
282 #O #D #M #N #N1 #H elim H //
283 #P #Q #Hind #HPQ #Happ %1[|@Happ] @rappr @HPQ
286 lemma star_red_vec: ∀O,D,ty,N,N1,v1,v2. star ? (red O D) N N1 →
287 star ? (red O D) (Vec O D ty (v1@N::v2)) (Vec O D ty (v1@N1::v2)).
288 #O #D #ty #N #N1 #v1 #v2 #H elim H //
289 #P #Q #Hind #HPQ #Hvec %1[|@Hvec] @rvec @HPQ
292 axiom red_subst : ∀O,D,M,N,N1,i.
293 red O D N N1 → red O D (subst O D M i N) (subst O D M i N1).
295 axiom red_star_subst : ∀O,D,M,N,N1,i.
296 star ? (red O D) N N1 → star ? (red O D) (subst O D M i N) (subst O D M i N1).
298 axiom canonical_to_T: ∀O,D.∀M:T O D.∀ty.(* type_of M ty → *)
299 ∃a:FinSet_of_FType O D ty. star ? (red O D) M (to_T O D ty a).
301 axiom normal_to_T: ∀O,D,M,ty,a. red O D (to_T O D ty a) M → False.
303 lemma critical: ∀O,D,ty,M,N.
305 .star (T O D) (red O D) (subst O D M 0 N) M3
306 ∧star (T O D) (red O D)
309 (map (FinSet_of_FType O D ty) (T O D)
310 (λa0:FinSet_of_FType O D ty.subst O D M 0 (to_T O D ty a0))
311 (enum (FinSet_of_FType O D ty)))) N) M3.
313 lapply (canonical_to_T O D N ty) * #a #Ha
314 %{(subst O D M 0 (to_T O D ty a))} (* CR-term *)
315 %[@red_star_subst @Ha
316 |@trans_star [|@(star_red_appr … Ha)] @R_to_star @riota
317 lapply (enum_complete (FinSet_of_FType O D ty) a)
318 elim (enum (FinSet_of_FType O D ty))
319 [normalize #H1 destruct (H1)
320 |#hd #tl #Hind #H cases (orb_true_l … H) -H #Hcase
321 [normalize >Hcase >(\P Hcase) //
322 |normalize cases (true_or_false (a==hd)) #Hcase1
323 [normalize >Hcase1 >(\P Hcase1) // |>Hcase1 @Hind @Hcase]
329 lemma critical2: ∀O,D,ty,a,M,M1,M2,v.
330 red O D (Vec O D ty v) M →
331 red O D (App O D (Vec O D ty v) (to_T O D ty a)) M1 →
332 assoc (FinSet_of_FType O D ty) (T O D) a (enum (FinSet_of_FType O D ty)) v
335 .star (T O D) (red O D) M2 M3
336 ∧star (T O D) (red O D) (App O D M (to_T O D ty a)) M3.
337 #O #D #ty #a #M #M1 #M2 #v #redM #redM1 #Ha lapply (red_vec … redM) -redM
338 * #N * #N1 * #v1 * #v2 * * #Hred1 #Hv #HM0 >HM0 -HM0 >Hv in Ha; #Ha
339 cases (same_assoc … a (enum (FinSet_of_FType O D ty)) v1 v2 N N1)
340 [* >Ha -Ha #H1 destruct (H1) #Ha
341 %{N1} (* CR-term *) % [@R_to_star //|@R_to_star @(riota … Ha)]
342 |#Ha1 %{M2} (* CR-term *) % [// | @R_to_star @riota <Ha1 @Ha]
346 (* we need to proceed by structural induction on the term and then
347 by inversion on the two redexes. The problem are the moves in a
348 same subterm, since we need an induction hypothesis, there *)
350 lemma local_confluence: ∀O,D,M,M1,M2. red O D M M1 → red O D M M2 →
351 ∃M3. star ? (red O D) M1 M3 ∧ star ? (red O D) M2 M3.
352 #O #D #M @(T_elim … M)
353 [#o #a #M1 #M2 #H elim(red_val ????? H)
354 |#n #M1 #M2 #H elim(red_rel ???? H)
355 |(* app : this is the interesting case *)
357 #M1 #M2 #H1 inversion H1 -H1
358 [(* right redex is beta *)
359 #ty #Q #N #HM >HM -HM #HM1 >HM1 - HM1 #Hl inversion Hl
360 [#P1 #M1 #N1 #H1 destruct (H1) #H_ %{(subst O D M1 0 N1)} (* CR-term *) /2/
361 |#ty #v #a #M0 #_ #H1 destruct (H1) (* vacuous *)
362 |#M0 #M10 #N0 #redM0 #_ #H1 destruct (H1) #_ inversion redM0
363 [#P0 #M0 #N #H destruct
364 |#ty #v #a #M0 #_ #H1 destruct (H1)
365 |#M0 #M1 #N #_ #_ #H1 destruct (H1)
366 |#M0 #M1 #N #_ #_ #H1 destruct (H1)
367 |#ty1 #M0 #H1 destruct (H1) #HM1 @critical
368 |#ty #N #N1 #v #v1 #_ #_ #H1 destruct (H1)
370 |#M0 #N0 #N1 #redN0N1 #_ #H1 destruct (H1) #HM2
371 %{(subst O D Q 0 N1)} (* CR-term *)
372 %[@red_star_subst @R_to_star //|@R_to_star @rbeta]
373 |#ty1 #M0 #H1 destruct (H1) (* vacuous *)
374 |#ty1 #N0 #N1 #v #v1 #_ #_ #H1 destruct (H1) (* vacuous *)
376 |(* right redex is iota *)#ty #v #a #M3 #Ha #_ #_ #Hl inversion Hl
377 [#P1 #M1 #N1 #H1 destruct (H1) (* vacuous *)
378 |#ty1 #v1 #a1 #M4 #Ha1 #H1 destruct (H1) -H1 #HM4 >(inj_to_T … e0) in Ha;
379 >Ha1 #H1 destruct (H1) %{M3} (* CR-term *) /2/
380 |#M0 #M10 #N0 #redM0 #_ #H1 destruct (H1) #HM2 @(critical2 … redM0 Hl Ha)
381 |#M0 #N0 #N1 #redN0N1 #_ #H1 destruct (H1) elim (normal_to_T … redN0N1)
382 |#ty1 #M0 #H1 destruct (H1) (* vacuous *)
383 |#ty1 #N0 #N1 #v #v1 #_ #_ #H1 destruct (H1) (* vacuous *)
385 |(* right redex is appl *)#M3 #M4 #N #redM3M4 #_ #H1 destruct (H1) #_
387 [#ty1 #M1 #N1 #H1 destruct (H1) #HM2 lapply (red_lambda … redM3M4)
388 #H >H -H lapply (critical O D ty1 M1 N1) * #M3 * #H1 #H2
390 |#ty1 #v1 #a1 #M4 #Ha1 #H1 #H2 destruct
391 lapply (critical2 … redM3M4 Hl Ha1) * #M3 * #H1 #H2 %{M3} /2/
392 |#M0 #M10 #N0 #redM0 #_ #H1 destruct (H1) #HM2
393 lapply (HindP … redM0 redM3M4) * #M3 * #H1 #H2
394 %{(App O D M3 N0)} (* CR-term *) % [@star_red_appl //|@star_red_appl //]
395 |#M0 #N0 #N1 #redN0N1 #_ #H1 destruct (H1) #_
396 %{(App O D M4 N1)} % @R_to_star [@rappr //|@rappl //]
397 |#ty1 #M0 #H1 destruct (H1) (* vacuous *)
398 |#ty1 #N0 #N1 #v #v1 #_ #_ #H1 destruct (H1) (* vacuous *)
400 |(* right redex is appr *)#M3 #N #N1 #redN #_ #H1 destruct (H1) #_
402 [#ty1 #M0 #N0 #H1 destruct (H1) #HM2
403 %{(subst O D M0 0 N1)} (* CR-term *) %
404 [@R_to_star @rbeta | @red_star_subst @R_to_star //]
405 |#ty1 #v1 #a1 #M4 #Ha1 #H1 #H2 destruct (H1) elim (normal_to_T … redN)
406 |#M0 #M10 #N0 #redM0 #_ #H1 destruct (H1) #HM2
407 %{(App O D M10 N1)} (* CR-term *) % @R_to_star [@rappl //|@rappr //]
408 |#M0 #N0 #N10 #redN0 #_ #H1 destruct (H1) #_
409 lapply (HindQ … redN0 redN) * #M3 * #H1 #H2
410 %{(App O D M0 M3)} (* CR-term *) % [@star_red_appr //|@star_red_appr //]
411 |#ty1 #M0 #H1 destruct (H1) (* vacuous *)
412 |#ty1 #N0 #N1 #v #v1 #_ #_ #H1 destruct (H1) (* vacuous *)
414 |(* right redex is rmem *) #ty #M0 #H1 destruct (H1) (* vacuous *)
415 |(* right redex is vec *) #ty #N #N1 #v #v1 #_ #_
416 #H1 destruct (H1) (* vacuous *)
418 |#ty #M1 #Hind #M2 #M3 #H1 #H2
419 lapply (red_lambda … H1) #HM2 lapply (red_lambda … H2) #HM3
420 %{M2} (* CR-term *) % //
421 |#ty #v1 #Hind #M1 #M2 #H1 #H2
422 lapply (red_vec … H1) * #N11 * #N12 * #v11 * #v12 * * #redN11 #Hv1 #HM1
423 lapply (red_vec … H2) * #N21* #N22 * #v21 * #v22 * * #redN21 #Hv2 #HM2
424 >Hv1 in Hv2; #Hvv lapply (compare_append … Hvv) -Hvv *
425 (* we must proceed by cases on the list *) * normalize
427 [>append_nil * #Hl1 #Hl2 destruct lapply(Hind N11 … redN11 redN21)
428 [@mem_append_l2 %1 //]
430 %{(Vec O D ty (v21@M3::v12))} (* CR-term *)
431 % [@star_red_vec //|@star_red_vec //]
432 |>append_nil * #Hl1 #Hl2 destruct lapply(Hind N21 … redN21 redN11)
433 [@mem_append_l2 %1 //]
435 %{(Vec O D ty (v11@M3::v22))} (* CR-term *)
436 % [@star_red_vec //|@star_red_vec //]
438 |(* N11 ≠ N21 *) -Hind #P #l *
439 [* #Hv11 #Hv22 destruct
440 %{((Vec O D ty ((v21@N22::l)@N12::v12)))} (* CR-term *) % @R_to_star
441 [>associative_append >associative_append normalize @rvec //
442 |>append_cons <associative_append <append_cons in ⊢ (???%?); @rvec //
444 |* #Hv11 #Hv22 destruct
445 %{((Vec O D ty ((v11@N12::l)@N22::v22)))} (* CR-term *) % @R_to_star
446 [>append_cons <associative_append <append_cons in ⊢ (???%?); @rvec //
447 |>associative_append >associative_append normalize @rvec //