+++ /dev/null
-(*
- ||M|| This file is part of HELM, an Hypertextual, Electronic
- ||A|| Library of Mathematics, developed at the Computer Science
- ||T|| Department of the University of Bologna, Italy.
- ||I||
- ||T||
- ||A|| This file is distributed under the terms of the
- \ / GNU General Public License Version 2
- \ /
- V_______________________________________________________________ *)
-
-include "basics/finset.ma".
-include "basics/star.ma".
-
-
-inductive FType (O:Type[0]): Type[0] ≝
- | atom : O → FType O
- | arrow : FType O → FType O → FType O.
-
-inductive T (O:Type[0]) (D:O → FinSet): Type[0] ≝
- | Val: ∀o:O.carr (D o) → T O D (* a value in a finset *)
- | Rel: nat → T O D (* DB index, base is 0 *)
- | App: T O D → T O D → T O D (* function, argument *)
- | Lambda: FType O → T O D → T O D (* type, body *)
- | Vec: FType O → list (T O D) → T O D (* type, body *)
-.
-
-let rec FinSet_of_FType O (D:O→FinSet) (ty:FType O) on ty : FinSet ≝
- match ty with
- [atom o ⇒ D o
- |arrow ty1 ty2 ⇒ FinFun (FinSet_of_FType O D ty1) (FinSet_of_FType O D ty2)
- ].
-
-(* size *)
-
-let rec size O D (M:T O D) on M ≝
-match M with
- [Val o a ⇒ 1
- |Rel n ⇒ 1
- |App P Q ⇒ size O D P + size O D Q + 1
- |Lambda Ty P ⇒ size O D P + 1
- |Vec Ty v ⇒ foldr ?? (λx,a. size O D x + a) 0 v +1
- ]
-.
-
-(* axiom pos_size: ∀M. 1 ≤ size M. *)
-
-theorem Telim_size: ∀O,D.∀P: T O D → Prop.
- (∀M. (∀N. size O D N < size O D M → P N) → P M) → ∀M. P M.
-#O #D #P #H #M (cut (∀p,N. size O D N = p → P N))
- [2: /2/]
-#p @(nat_elim1 p) #m #H1 #N #sizeN @H #N0 #Hlt @(H1 (size O D N0)) //
-qed.
-
-lemma T_elim:
- ∀O: Type[0].∀D:O→FinSet.∀P:T O D→Prop.
- (∀o:O.∀x:D o.P (Val O D o x)) →
- (∀n:ℕ.P(Rel O D n)) →
- (∀m,n:T O D.P m→P n→P (App O D m n)) →
- (∀Ty:FType O.∀m:T O D.P m→P(Lambda O D Ty m)) →
- (∀Ty:FType O.∀v:list (T O D).
- (∀x:T O D. mem ? x v → P x) → P(Vec O D Ty v)) →
- ∀x:T O D.P x.
-#O #D #P #Hval #Hrel #Happ #Hlam #Hvec @Telim_size #x cases x //
- [ (* app *) #m #n #Hind @Happ @Hind // /2 by le_minus_to_plus/
- | (* lam *) #ty #m #Hind @Hlam @Hind normalize //
- | (* vec *) #ty #v #Hind @Hvec #x lapply Hind elim v
- [#Hind normalize *
- |#hd #tl #Hind1 #Hind2 *
- [#Hx >Hx @Hind2 normalize //
- |@Hind1 #N #H @Hind2 @(lt_to_le_to_lt … H) normalize //
- ]
- ]
- ]
-qed.
-
-(* since we only consider beta reduction with closed arguments we could avoid
-lifting. We define it for the sake of generality *)
-
-(* arguments: k is the nesting depth (starts from 0), p is the lift
-let rec lift O D t k p on t ≝
- match t with
- [ Val o a ⇒ Val O D o a
- | Rel n ⇒ if (leb k n) then Rel O D (n+p) else Rel O D n
- | App m n ⇒ App O D (lift O D m k p) (lift O D n k p)
- | Lambda Ty n ⇒ Lambda O D Ty (lift O D n (S k) p)
- | Vec Ty v ⇒ Vec O D Ty (map ?? (λx. lift O D x k p) v)
- ].
-
-notation "↑ ^ n ( M )" non associative with precedence 40 for @{'Lift 0 $n $M}.
-notation "↑ _ k ^ n ( M )" non associative with precedence 40 for @{'Lift $n $k $M}.
-
-interpretation "Lift" 'Lift n k M = (lift ?? M k n).
-
-let rec subst O D t k s on t ≝
- match t with
- [ Val o a ⇒ Val O D o a
- | Rel n ⇒ if (leb k n) then
- (if (eqb k n) then lift O D s 0 n else Rel O D (n-1))
- else(Rel O D n)
- | App m n ⇒ App O D (subst O D m k s) (subst O D n k s)
- | Lambda T n ⇒ Lambda O D T (subst O D n (S k) s)
- | Vec T v ⇒ Vec O D T (map ?? (λx. subst O D x k s) v)
- ].
-*)
-
-(* simplified version of subst, assuming the argument s is closed *)
-
-let rec subst O D t k s on t ≝
- match t with
- [ Val o a ⇒ Val O D o a
- | Rel n ⇒ if (leb k n) then
- (if (eqb k n) then (* lift O D s 0 n*) s else Rel O D (n-1))
- else(Rel O D n)
- | App m n ⇒ App O D (subst O D m k s) (subst O D n k s)
- | Lambda T n ⇒ Lambda O D T (subst O D n (S k) s)
- | Vec T v ⇒ Vec O D T (map ?? (λx. subst O D x k s) v)
- ].
-(* notation "hvbox(M break [ k ≝ N ])"
- non associative with precedence 90
- for @{'Subst1 $M $k $N}. *)
-
-interpretation "Subst" 'Subst1 M k N = (subst M k N).
-
-(*
-lemma subst_rel1: ∀O,D,A.∀k,i. i < k →
- (Rel O D i) [k ≝ A] = Rel O D i.
-#A #k #i normalize #ltik >(lt_to_leb_false … ltik) //
-qed.
-
-lemma subst_rel2: ∀O,D, A.∀k.
- (Rel k) [k ≝ A] = lift A 0 k.
-#A #k normalize >(le_to_leb_true k k) // >(eq_to_eqb_true … (refl …)) //
-qed.
-
-lemma subst_rel3: ∀A.∀k,i. k < i →
- (Rel i) [k ≝ A] = Rel (i-1).
-#A #k #i normalize #ltik >(le_to_leb_true k i) /2/
->(not_eq_to_eqb_false k i) // @lt_to_not_eq //
-qed. *)
-
-
-(* closed terms ????
-let rec closed_k O D (t: T O D) k on t ≝
- match t with
- [ Val o a ⇒ True
- | Rel n ⇒ n < k
- | App m n ⇒ (closed_k O D m k) ∧ (closed_k O D n k)
- | Lambda T n ⇒ closed_k O D n (k+1)
- | Vec T v ⇒ closed_list O D v k
- ]
-
-and closed_list O D (l: list (T O D)) k on l ≝
- match l with
- [ nil ⇒ True
- | cons hd tl ⇒ closed_k O D hd k ∧ closed_list O D tl k
- ]
-. *)
-
-inductive is_closed (O:Type[0]) (D:O→FinSet): nat → T O D → Prop ≝
-| cval : ∀k,o,a.is_closed O D k (Val O D o a)
-| crel : ∀k,n. n < k → is_closed O D k (Rel O D n)
-| capp : ∀k,m,n. is_closed O D k m → is_closed O D k n →
- is_closed O D k (App O D m n)
-| clam : ∀T,k,m. is_closed O D (S k) m → is_closed O D k (Lambda O D T m)
-| cvec: ∀T,k,v. (∀m. mem ? m v → is_closed O D k m) →
- is_closed O D k (Vec O D T v).
-
-lemma is_closed_rel: ∀O,D,n,k.
- is_closed O D k (Rel O D n) → n < k.
-#O #D #n #k #H inversion H
- [#k0 #o #a #eqk #H destruct
- |#k0 #n0 #ltn0 #eqk #H destruct //
- |#k0 #M #N #_ #_ #_ #_ #_ #H destruct
- |#T #k0 #M #_ #_ #_ #H destruct
- |#T #k0 #v #_ #_ #_ #H destruct
- ]
-qed.
-
-lemma is_closed_app: ∀O,D,k,M, N.
- is_closed O D k (App O D M N) → is_closed O D k M ∧ is_closed O D k N.
-#O #D #k #M #N #H inversion H
- [#k0 #o #a #eqk #H destruct
- |#k0 #n0 #ltn0 #eqk #H destruct
- |#k0 #M1 #N1 #HM #HN #_ #_ #_ #H1 destruct % //
- |#T #k0 #M #_ #_ #_ #H destruct
- |#T #k0 #v #_ #_ #_ #H destruct
- ]
-qed.
-
-lemma is_closed_lam: ∀O,D,k,ty,M.
- is_closed O D k (Lambda O D ty M) → is_closed O D (S k) M.
-#O #D #k #ty #M #H inversion H
- [#k0 #o #a #eqk #H destruct
- |#k0 #n0 #ltn0 #eqk #H destruct
- |#k0 #M1 #N1 #HM #HN #_ #_ #_ #H1 destruct
- |#T #k0 #M1 #HM1 #_ #_ #H1 destruct //
- |#T #k0 #v #_ #_ #_ #H destruct
- ]
-qed.
-
-lemma is_closed_vec: ∀O,D,k,ty,v.
- is_closed O D k (Vec O D ty v) → ∀m. mem ? m v → is_closed O D k m.
-#O #D #k #ty #M #H inversion H
- [#k0 #o #a #eqk #H destruct
- |#k0 #n0 #ltn0 #eqk #H destruct
- |#k0 #M1 #N1 #HM #HN #_ #_ #_ #H1 destruct
- |#T #k0 #M1 #HM1 #_ #_ #H1 destruct
- |#T #k0 #v #Hv #_ #_ #H1 destruct @Hv
- ]
-qed.
-
-lemma is_closed_S: ∀O,D,M,m.
- is_closed O D m M → is_closed O D (S m) M.
-#O #D #M #m #H elim H //
- [#k #n0 #Hlt @crel @le_S //
- |#k #P #Q #HP #HC #H1 #H2 @capp //
- |#ty #k #P #HP #H1 @clam //
- |#ty #k #v #Hind #Hv @cvec @Hv
- ]
-qed.
-
-lemma is_closed_mono: ∀O,D,M,m,n. m ≤ n →
- is_closed O D m M → is_closed O D n M.
-#O #D #M #m #n #lemn elim lemn // #i #j #H #H1 @is_closed_S @H @H1
-qed.
-
-
-(*** properties of lift and subst ***)
-
-(*
-lemma lift_0: ∀O,D.∀t:T O D.∀k. lift O D t k 0 = t.
-#O #D #t @(T_elim … t) normalize //
- [#n #k cases (leb k n) normalize //
- |#o #v #Hind #k @eq_f lapply Hind -Hind elim v //
- #hd #tl #Hind #Hind1 normalize @eq_f2
- [@Hind1 %1 //|@Hind #x #Hx @Hind1 %2 //]
- ]
-qed.
-
-lemma lift_closed: ∀O,D.∀t:T O D.∀k,p.
- is_closed O D k t → lift O D t k p = t.
-#O #D #t @(T_elim … t) normalize //
- [#n #k #p #H >(not_le_to_leb_false … (lt_to_not_le … (is_closed_rel … H))) //
- |#M #N #HindM #HindN #k #p #H lapply (is_closed_app … H) * #HcM #HcN
- >(HindM … HcM) >(HindN … HcN) //
- |#ty #M #HindM #k #p #H lapply (is_closed_lam … H) -H #H >(HindM … H) //
- |#ty #v #HindM #k #p #H lapply (is_closed_vec … H) -H #H @eq_f
- cut (∀m. mem ? m v → lift O D m k p = m)
- [#m #Hmem @HindM [@Hmem | @H @Hmem]] -HindM
- elim v // #a #tl #Hind #H1 normalize @eq_f2
- [@H1 %1 //|@Hind #m #Hmem @H1 %2 @Hmem]
- ]
-qed.
-
-*)
-
-lemma subst_closed: ∀O,D,M,N,k,i. k ≤ i →
- is_closed O D k M → subst O D M i N = M.
-#O #D #M @(T_elim … M)
- [#o #a normalize //
- |#n #N #k #j #Hlt #Hc lapply (is_closed_rel … Hc) #Hnk normalize
- >not_le_to_leb_false [2:@lt_to_not_le @(lt_to_le_to_lt … Hnk Hlt)] //
- |#P #Q #HindP #HindQ #N #k #i #ltki #Hc lapply (is_closed_app … Hc) *
- #HcP #HcQ normalize >(HindP … ltki HcP) >(HindQ … ltki HcQ) //
- |#ty #P #HindP #N #k #i #ltki #Hc lapply (is_closed_lam … Hc)
- #HcP normalize >(HindP … HcP) // @le_S_S @ltki
- |#ty #v #Hindv #N #k #i #ltki #Hc lapply (is_closed_vec … Hc)
- #Hcv normalize @eq_f
- cut (∀m:T O D.mem (T O D) m v→ subst O D m i N=m)
- [#m #Hmem @(Hindv … Hmem N … ltki) @Hcv @Hmem]
- elim v // #a #tl #Hind #H normalize @eq_f2
- [@H %1 //| @Hind #Hmem #Htl @H %2 @Htl]
- ]
-qed.
-
-lemma subst_lemma: ∀O,D,A,B,C,k,i. is_closed O D k B → is_closed O D i C →
- subst O D (subst O D A i B) (k+i) C =
- subst O D (subst O D A (k+S i) C) i B.
-#O #D #A #B #C #k @(T_elim … A) normalize
- [//
- |#n #i #HBc #HCc @(leb_elim i n) #Hle
- [@(eqb_elim i n) #eqni
- [<eqni >(lt_to_leb_false (k+(S i)) i) // normalize
- >(subst_closed … HBc) // >le_to_leb_true // >eq_to_eqb_true //
- |(cut (i < n))
- [cases (le_to_or_lt_eq … Hle) // #eqin @False_ind /2/] #ltin
- (cut (0 < n)) [@(le_to_lt_to_lt … ltin) //] #posn
- normalize @(leb_elim (k+i) (n-1)) #nk
- [@(eqb_elim (k+i) (n-1)) #H normalize
- [cut (k+(S i) = n); [/2 by S_pred/] #H1
- >(le_to_leb_true (k+(S i)) n) /2/
- >(eq_to_eqb_true … H1) normalize >(subst_closed … HCc) //
- |(cut (k+i < n-1)) [@not_eq_to_le_to_lt; //] #Hlt
- >(le_to_leb_true (k+(S i)) n) normalize
- [>(not_eq_to_eqb_false (k+(S i)) n) normalize
- [>le_to_leb_true [2:@lt_to_le @(le_to_lt_to_lt … Hlt) //]
- >not_eq_to_eqb_false // @lt_to_not_eq @(le_to_lt_to_lt … Hlt) //
- |@(not_to_not … H) #Hn /2 by plus_minus/
- ]
- |<plus_n_Sm @(lt_to_le_to_lt … Hlt) //
- ]
- ]
- |>(not_le_to_leb_false (k+(S i)) n) normalize
- [>(le_to_leb_true … Hle) >(not_eq_to_eqb_false … eqni) //
- |@(not_to_not … nk) #H @le_plus_to_minus_r //
- ]
- ]
- ]
- |(cut (n < k+i)) [@(lt_to_le_to_lt ? i) /2 by not_le_to_lt/] #ltn
- >not_le_to_leb_false [2: @lt_to_not_le @(transitive_lt …ltn) //] normalize
- >not_le_to_leb_false [2: @lt_to_not_le //] normalize
- >(not_le_to_leb_false … Hle) //
- ]
- |#M #N #HindM #HindN #i #HBC #HCc @eq_f2 [@HindM // |@HindN //]
- |#ty #M #HindM #i #HBC #HCc @eq_f >plus_n_Sm >plus_n_Sm @HindM //
- @is_closed_S //
- |#ty #v #Hindv #i #HBC #HCc @eq_f
- cut (∀m.mem ? m v → subst O D (subst O D m i B) (k+i) C =
- subst O D (subst O D m (k+S i) C) i B)
- [#m #Hmem @Hindv //] -Hindv elim v normalize [//]
- #a #tl #Hind #H @eq_f2 [@H %1 // | @Hind #m #Hmem @H %2 //]
- ]
-qed.
-
-