]> matita.cs.unibo.it Git - helm.git/blobdiff - matita/matita/lib/binding/ln_concrete.ma
backport of WIP on \lambda\delta to matita 0.99.3
[helm.git] / matita / matita / lib / binding / ln_concrete.ma
diff --git a/matita/matita/lib/binding/ln_concrete.ma b/matita/matita/lib/binding/ln_concrete.ma
deleted file mode 100644 (file)
index bdafdb1..0000000
+++ /dev/null
@@ -1,683 +0,0 @@
-(**************************************************************************)
-(*       ___                                                              *)
-(*      ||M||                                                             *)
-(*      ||A||       A project by Andrea Asperti                           *)
-(*      ||T||                                                             *)
-(*      ||I||       Developers:                                           *)
-(*      ||T||         The HELM team.                                      *)
-(*      ||A||         http://helm.cs.unibo.it                             *)
-(*      \   /                                                             *)
-(*       \ /        This file is distributed under the terms of the       *)
-(*        v         GNU General Public License Version 2                  *)
-(*                                                                        *)
-(**************************************************************************)
-
-include "basics/lists/list.ma".
-include "basics/deqsets.ma".
-include "binding/names.ma".
-include "binding/fp.ma".
-
-definition alpha : Nset β‰ X. check alpha
-notation "𝔸" non associative with precedence 90 for @{'alphabet}.
-interpretation "set of names" 'alphabet = alpha.
-
-inductive tp : Type[0] β‰ 
-| top : tp
-| arr : tp β†’ tp β†’ tp.
-inductive pretm : Type[0] β‰ 
-| var : nat β†’ pretm
-| par :  π”Έ β†’ pretm
-| abs : tp β†’ pretm β†’ pretm
-| app : pretm β†’ pretm β†’ pretm.
-
-let rec Nth T n (l:list T) on n β‰ 
-  match l with 
-  [ nil β‡’ None ?
-  | cons hd tl β‡’ match n with
-    [ O β‡’ Some ? hd
-    | S n0 β‡’ Nth T n0 tl ] ].
-
-let rec vclose_tm_aux u x k β‰ match u with
-  [ var n β‡’ if (leb k n) then var (S n) else u
-  | par x0 β‡’ if (x0 == x) then (var k) else u
-  | app v1 v2 β‡’ app (vclose_tm_aux v1 x k) (vclose_tm_aux v2 x k)
-  | abs s v β‡’ abs s (vclose_tm_aux v x (S k)) ].
-definition vclose_tm β‰ Ξ»u,x.vclose_tm_aux u x O.  
-
-definition vopen_var β‰ Ξ»n,x,k.match eqb n k with
- [ true β‡’ par x
- | false β‡’ match leb n k with
-   [ true β‡’ var n
-   | false β‡’ var (pred n) ] ].
-
-let rec vopen_tm_aux u x k β‰ match u with
-  [ var n β‡’ vopen_var n x k
-  | par x0 β‡’ u
-  | app v1 v2 β‡’ app (vopen_tm_aux v1 x k) (vopen_tm_aux v2 x k)
-  | abs s v β‡’ abs s (vopen_tm_aux v x (S k)) ].
-definition vopen_tm β‰ Ξ»u,x.vopen_tm_aux u x O.
-
-let rec FV u β‰ match u with 
-  [ par x β‡’ [x]
-  | app v1 v2 β‡’ FV v1@FV v2
-  | abs s v β‡’ FV v
-  | _ β‡’ [ ] ].  
-
-definition lam β‰ Ξ»x,s,u.abs s (vclose_tm u x).
-
-let rec Pi_map_tm p u on u β‰ match u with
-[ par x β‡’ par (p x)
-| var _ β‡’ u
-| app v1 v2 β‡’ app (Pi_map_tm p v1) (Pi_map_tm p v2)
-| abs s v β‡’ abs s (Pi_map_tm p v) ].
-
-interpretation "permutation of tm" 'middot p x = (Pi_map_tm p x).
-
-notation "hvbox(u⌈xβŒ‰)"
-  with precedence 45
-  for @{ 'open $u $x }.
-
-(*
-notation "hvbox(u⌈xβŒ‰)"
-  with precedence 45
-  for @{ 'open $u $x }.
-notation "❴ u β΅ x" non associative with precedence 90 for @{ 'open $u $x }.
-*)
-interpretation "ln term variable open" 'open u x = (vopen_tm u x).
-notation < "hvbox(Ξ½ x break . u)"
- with precedence 20
-for @{'nu $x $u }.
-notation > "Ξ½ list1 x sep , . term 19 u" with precedence 20
-  for ${ fold right @{$u} rec acc @{'nu $x $acc)} }.
-interpretation "ln term variable close" 'nu x u = (vclose_tm u x).
-
-let rec tm_height u β‰ match u with
-[ app v1 v2 β‡’ S (max (tm_height v1) (tm_height v2))
-| abs s v β‡’ S (tm_height v) 
-| _ β‡’ O ].
-
-theorem le_n_O_rect_Type0 : βˆ€n:nat. n β‰€ O β†’ βˆ€P: nat β†’Type[0]. P O β†’ P n.
-#n (cases n) // #a #abs cases (?:False) /2/ qed. 
-
-theorem nat_rect_Type0_1 : βˆ€n:nat.βˆ€P:nat β†’ Type[0]. 
-(βˆ€m.(βˆ€p. p < m β†’ P p) β†’ P m) β†’ P n.
-#n #P #H 
-cut (βˆ€q:nat. q β‰€ n β†’ P q) /2/
-(elim n) 
- [#q #HleO (* applica male *) 
-    @(le_n_O_rect_Type0 ? HleO)
-    @H #p #ltpO cases (?:False) /2/ (* 3 *)
- |#p #Hind #q #HleS 
-    @H #a #lta @Hind @le_S_S_to_le /2/
- ]
-qed.
-
-lemma leb_false_to_lt : βˆ€n,m. leb n m = false β†’ m < n.
-#n elim n
-[ #m normalize #H destruct(H)
-| #n0 #IH * // #m normalize #H @le_S_S @IH // ]
-qed.
-
-lemma nominal_eta_aux : βˆ€x,u.x βˆ‰ FV u β†’ βˆ€k.vclose_tm_aux (vopen_tm_aux u x k) x k = u.
-#x #u elim u
-[ #n #_ #k normalize cases (decidable_eq_nat n k) #Hnk
-  [ >Hnk >eqb_n_n whd in βŠ’ (??%?); >(\b ?) //
-  | >(not_eq_to_eqb_false β€¦ Hnk) normalize cases (true_or_false (leb n k)) #Hleb
-    [ >Hleb normalize >(?:leb k n = false) //
-      @lt_to_leb_false @not_eq_to_le_to_lt /2/
-    | >Hleb normalize >(?:leb k (pred n) = true) normalize
-      [ cases (leb_false_to_lt β€¦ Hleb) //
-      | @le_to_leb_true cases (leb_false_to_lt β€¦ Hleb) normalize /2/ ] ] ]
-| #y normalize in βŠ’ (%β†’?β†’?); #Hy whd in βŠ’ (?β†’??%?); >(\bf ?) // @(not_to_not β€¦ Hy) //
-| #s #v #IH normalize #Hv #k >IH // @Hv
-| #v1 #v2 #IH1 #IH2 normalize #Hv1v2 #k 
-  >IH1 [ >IH2 // | @(not_to_not β€¦ Hv1v2) @in_list_to_in_list_append_l ]
-  @(not_to_not β€¦ Hv1v2) @in_list_to_in_list_append_r ]
-qed.
-
-corollary nominal_eta : βˆ€x,u.x βˆ‰ FV u β†’ (Ξ½x.u⌈xβŒ‰) = u.
-#x #u #Hu @nominal_eta_aux //
-qed.
-
-lemma eq_height_vopen_aux : βˆ€v,x,k.tm_height (vopen_tm_aux v x k) = tm_height v.
-#v #x elim v
-[ #n #k normalize cases (eqb n k) // cases (leb n k) //
-| #u #k %
-| #s #u #IH #k normalize >IH %
-| #u1 #u2 #IH1 #IH2 #k normalize >IH1 >IH2 % ]
-qed.
-
-corollary eq_height_vopen : βˆ€v,x.tm_height (v⌈xβŒ‰) = tm_height v.
-#v #x @eq_height_vopen_aux
-qed.
-
-theorem pretm_ind_plus_aux : 
- βˆ€P:pretm β†’ Type[0].
-   (βˆ€x:𝔸.P (par x)) β†’ 
-   (βˆ€n:β„•.P (var n)) β†’ 
-   (βˆ€v1,v2. P v1 β†’ P v2 β†’ P (app v1 v2)) β†’ 
-   βˆ€C:list π”Έ.
-   (βˆ€x,s,v.x βˆ‰ FV v β†’ x βˆ‰ C β†’ P (v⌈xβŒ‰) β†’ P (lam x s (v⌈xβŒ‰))) β†’
- βˆ€n,u.tm_height u β‰€ n β†’ P u.
-#P #Hpar #Hvar #Happ #C #Hlam #n change with ((Ξ»n.?) n); @(nat_rect_Type0_1 n ??)
-#m cases m
-[ #_ * /2/
-  [ normalize #s #v #Hfalse cases (?:False) cases (not_le_Sn_O (tm_height v)) /2/
-  | #v1 #v2 whd in βŠ’ (?%?β†’?); #Hfalse cases (?:False) cases (not_le_Sn_O (S (max ??))) /2/ ] ]
--m #m #IH * /2/
-[ #s #v whd in βŠ’ (?%?β†’?); #Hv
-  lapply (p_fresh β€¦ (C@FV v)) letin y β‰ (N_fresh β€¦ (C@FV v)) #Hy
-  >(?:abs s v = lam y s (v⌈yβŒ‰))
-  [| whd in βŠ’ (???%); >nominal_eta // @(not_to_not β€¦ Hy) @in_list_to_in_list_append_r ] 
-  @Hlam
-  [ @(not_to_not β€¦ Hy) @in_list_to_in_list_append_r
-  | @(not_to_not β€¦ Hy) @in_list_to_in_list_append_l ]
-  @IH [| @Hv | >eq_height_vopen % ]
-| #v1 #v2 whd in βŠ’ (?%?β†’?); #Hv @Happ
-  [ @IH [| @Hv | // ] | @IH [| @Hv | // ] ] ]
-qed.
-
-corollary pretm_ind_plus :
- βˆ€P:pretm β†’ Type[0].
-   (βˆ€x:𝔸.P (par x)) β†’ 
-   (βˆ€n:β„•.P (var n)) β†’ 
-   (βˆ€v1,v2. P v1 β†’ P v2 β†’ P (app v1 v2)) β†’ 
-   βˆ€C:list π”Έ.
-   (βˆ€x,s,v.x βˆ‰ FV v β†’ x βˆ‰ C β†’ P (v⌈xβŒ‰) β†’ P (lam x s (v⌈xβŒ‰))) β†’
- βˆ€u.P u.
-#P #Hpar #Hvar #Happ #C #Hlam #u @pretm_ind_plus_aux /2/
-qed.
-
-(* maps a permutation to a list of terms *)
-definition Pi_map_list : (𝔸 β†’ π”Έ) β†’ list π”Έ β†’ list π”Έ β‰ map π”Έ π”Έ .
-
-(* interpretation "permutation of name list" 'middot p x = (Pi_map_list p x).*)
-
-(*
-inductive tm : pretm β†’ Prop β‰ 
-| tm_par : βˆ€x:𝔸.tm (par x)
-| tm_app : βˆ€u,v.tm u β†’ tm v β†’ tm (app u v)
-| tm_lam : βˆ€x,s,u.tm u β†’ tm (lam x s u).
-
-inductive ctx_aux : nat β†’ pretm β†’ Prop β‰ 
-| ctx_var : βˆ€n,k.n < k β†’ ctx_aux k (var n)
-| ctx_par : βˆ€x,k.ctx_aux k (par x)
-| ctx_app : βˆ€u,v,k.ctx_aux k u β†’ ctx_aux k v β†’ ctx_aux k (app u v)
-(* Γ¨ sostituibile da ctx_lam ? *)
-| ctx_abs : βˆ€s,u.ctx_aux (S k) u β†’ ctx_aux k (abs s u).
-*)
-
-inductive tm_or_ctx (k:nat) : pretm β†’ Type[0] β‰ 
-| toc_var : βˆ€n.n < k β†’ tm_or_ctx k (var n)
-| toc_par : βˆ€x.tm_or_ctx k (par x)
-| toc_app : βˆ€u,v.tm_or_ctx k u β†’ tm_or_ctx k v β†’ tm_or_ctx k (app u v)
-| toc_lam : βˆ€x,s,u.tm_or_ctx k u β†’ tm_or_ctx k (lam x s u).
-
-definition tm β‰ Ξ»t.tm_or_ctx O t.
-definition ctx β‰ Ξ»t.tm_or_ctx 1 t.
-
-record TM : Type[0] β‰ {
-  pretm_of_TM :> pretm;
-  tm_of_TM : tm pretm_of_TM
-}.
-
-record CTX : Type[0] β‰ {
-  pretm_of_CTX :> pretm;
-  ctx_of_CTX : ctx pretm_of_CTX
-}.
-
-inductive tm2 : pretm β†’ Type[0] β‰ 
-| tm_par : βˆ€x.tm2 (par x)
-| tm_app : βˆ€u,v.tm2 u β†’ tm2 v β†’ tm2 (app u v)
-| tm_lam : βˆ€x,s,u.x βˆ‰ FV u β†’ (βˆ€y.y βˆ‰ FV u β†’ tm2 (u⌈yβŒ‰)) β†’ tm2 (lam x s (u⌈xβŒ‰)).
-
-(*
-inductive tm' : pretm β†’ Prop β‰ 
-| tm_par : βˆ€x.tm' (par x)
-| tm_app : βˆ€u,v.tm' u β†’ tm' v β†’ tm' (app u v)
-| tm_lam : βˆ€x,s,u,C.x βˆ‰ FV u β†’ x βˆ‰ C β†’ (βˆ€y.y βˆ‰ FV u β†’ tm' (❴u❡y)) β†’ tm' (lam x s (❴u❡x)).
-*)
-
-axiom swap_inj : βˆ€N.βˆ€z1,z2,x,y.swap N z1 z2 x = swap N z1 z2 y β†’ x = y.
-
-lemma pi_vclose_tm : 
-  βˆ€z1,z2,x,u.swap π”Έ z1 z2Β·(Ξ½x.u) = (Ξ½ swap ? z1 z2 x.swap π”Έ z1 z2 Β· u).
-#z1 #z2 #x #u
-change with (vclose_tm_aux ???) in match (vclose_tm ??);
-change with (vclose_tm_aux ???) in βŠ’ (???%); lapply O elim u
-[3:whd in βŠ’ (?β†’?β†’(?β†’ ??%%)β†’?β†’??%%); //
-|4:whd in βŠ’ (?β†’?β†’(?β†’??%%)β†’(?β†’??%%)β†’?β†’??%%); //
-| #n #k whd in βŠ’ (??(??%)%); cases (leb k n) normalize %
-| #x0 #k cases (true_or_false (x0==z1)) #H1 >H1 whd in βŠ’ (??%%);
-  [ cases (true_or_false (x0==x)) #H2 >H2 whd in βŠ’ (??(??%)%);
-    [ <(\P H2) >H1 whd in βŠ’ (??(??%)%); >(\b ?) // >(\b ?) //
-    | >H2 whd in match (swap ????); >H1
-      whd in match (if false then var k else ?);
-      whd in match (if true then z2 else ?); >(\bf ?)
-      [ >(\P H1) >swap_left %
-      | <(swap_inv ? z1 z2 z2) in βŠ’ (?(??%?)); % #H3
-        lapply (swap_inj β€¦ H3) >swap_right #H4 <H4 in H2; >H1 #H destruct (H) ]
-    ]
-  | >(?:(swap ? z1 z2 x0 == swap ? z1 z2 x) = (x0 == x))
-    [| cases (true_or_false (x0==x)) #H2 >H2
-      [ >(\P H2) @(\b ?) %
-      | @(\bf ?) % #H >(swap_inj β€¦ H) in H2; >(\b ?) // #H0 destruct (H0) ] ]
-    cases (true_or_false (x0==x)) #H2 >H2 whd in βŠ’ (??(??%)%); 
-    [ <(\P H2) >H1 >(\b (refl ??)) %
-    | >H1 >H2 % ]
-    ]
-  ]
-qed.
-
-lemma pi_vopen_tm : 
-  βˆ€z1,z2,x,u.swap π”Έ z1 z2Β·(u⌈xβŒ‰) = (swap π”Έ z1 z2 Β· u⌈swap π”Έ z1 z2 xβŒ‰).
-#z1 #z2 #x #u
-change with (vopen_tm_aux ???) in match (vopen_tm ??);
-change with (vopen_tm_aux ???) in βŠ’ (???%); lapply O elim u //
-[2: #s #v whd in βŠ’ ((?β†’??%%)β†’?β†’??%%); //
-|3: #v1 #v2 whd in βŠ’ ((?β†’??%%)β†’(?β†’??%%)β†’?β†’??%%); /2/ ]
-#n #k whd in βŠ’ (??(??%)%); cases (true_or_false (eqb n k)) #H1 >H1 //
-cases (true_or_false (leb n k)) #H2 >H2 normalize //
-qed.
-
-lemma pi_lam : 
-  βˆ€z1,z2,x,s,u.swap π”Έ z1 z2 Β· lam x s u = lam (swap π”Έ z1 z2 x) s (swap π”Έ z1 z2 Β· u).
-#z1 #z2 #x #s #u whd in βŠ’ (???%); <(pi_vclose_tm β€¦) %
-qed.
-
-lemma eqv_FV : βˆ€z1,z2,u.FV (swap π”Έ z1 z2 Β· u) = Pi_map_list (swap π”Έ z1 z2) (FV u).
-#z1 #z2 #u elim u //
-[ #s #v #H @H
-| #v1 #v2 whd in βŠ’ (??%%β†’??%%β†’??%%); #H1 #H2 >H1 >H2
-  whd in βŠ’ (???(????%)); /2/ ]
-qed.
-
-lemma swap_inv_tm : βˆ€z1,z2,u.swap π”Έ z1 z2 Β· (swap π”Έ z1 z2 Β· u) = u.
-#z1 #z2 #u elim u 
-[1: #n %
-|3: #s #v whd in βŠ’ (?β†’??%%); //
-|4: #v1 #v2 #Hv1 #Hv2 whd in βŠ’ (??%%); // ]
-#x whd in βŠ’ (??%?); >swap_inv %
-qed.
-
-lemma eqv_in_list : βˆ€x,l,z1,z2.x βˆˆ l β†’ swap π”Έ z1 z2 x βˆˆ Pi_map_list (swap π”Έ z1 z2) l.
-#x #l #z1 #z2 #Hin elim Hin
-[ #x0 #l0 %
-| #x1 #x2 #l0 #Hin #IH %2 @IH ]
-qed.
-
-lemma eqv_tm2 : βˆ€u.tm2 u β†’ βˆ€z1,z2.tm2 ((swap ? z1 z2)Β·u).
-#u #Hu #z1 #z2 letin p β‰ (swap ? z1 z2) elim Hu /2/
-#x #s #v #Hx #Hv #IH >pi_lam >pi_vopen_tm %3
-[ @(not_to_not β€¦ Hx) -Hx #Hx
-  <(swap_inv ? z1 z2 x) <(swap_inv_tm z1 z2 v) >eqv_FV @eqv_in_list //
-| #y #Hy <(swap_inv ? z1 z2 y)
-  <pi_vopen_tm @IH @(not_to_not β€¦ Hy) -Hy #Hy <(swap_inv ? z1 z2 y)
-  >eqv_FV @eqv_in_list //
-]
-qed.
-
-lemma vclose_vopen_aux : βˆ€x,u,k.vopen_tm_aux (vclose_tm_aux u x k) x k = u.
-#x #u elim u [1,3,4:normalize //]
-[ #n #k cases (true_or_false (leb k n)) #H >H whd in βŠ’ (??%?);
-  [ cases (true_or_false (eqb (S n) k)) #H1 >H1
-    [ <(eqb_true_to_eq β€¦ H1) in H; #H lapply (leb_true_to_le β€¦ H) -H #H
-      cases (le_to_not_lt β€¦ H) -H #H cases (H ?) %
-    | whd in βŠ’ (??%?); >lt_to_leb_false // @le_S_S /2/ ]
-  | cases (true_or_false (eqb n k)) #H1 >H1 normalize
-    [ >(eqb_true_to_eq β€¦ H1) in H; #H lapply (leb_false_to_not_le β€¦ H) -H
-      * #H cases (H ?) %
-    | >le_to_leb_true // @not_lt_to_le % #H2 >le_to_leb_true in H;
-      [ #H destruct (H) | /2/ ]
-    ]
-  ]
-| #x0 #k whd in βŠ’ (??(?%??)?); cases (true_or_false (x0==x)) 
-  #H1 >H1 normalize // >(\P H1) >eqb_n_n % ]
-qed.      
-
-lemma vclose_vopen : βˆ€x,u.((Ξ½x.u)⌈xβŒ‰) = u. #x #u @vclose_vopen_aux
-qed.
-
-(*
-theorem tm_to_tm : βˆ€t.tm' t β†’ tm t.
-#t #H elim H
-*)
-
-lemma in_list_singleton : βˆ€T.βˆ€t1,t2:T.t1 βˆˆ [t2] β†’ t1 = t2.
-#T #t1 #t2 #H @(in_list_inv_ind ??? H) /2/
-qed.
-
-lemma fresh_vclose_tm_aux : βˆ€u,x,k.x βˆ‰ FV (vclose_tm_aux u x k).
-#u #x elim u //
-[ #n #k normalize cases (leb k n) normalize //
-| #x0 #k whd in βŠ’ (?(???(?%))); cases (true_or_false (x0==x)) #H >H normalize //
-  lapply (\Pf H) @not_to_not #Hin >(in_list_singleton ??? Hin) %
-| #v1 #v2 #IH1 #IH2 #k normalize % #Hin cases (in_list_append_to_or_in_list ???? Hin) -Hin #Hin
-  [ cases (IH1 k) -IH1 #IH1 @IH1 @Hin | cases (IH2 k) -IH2 #IH2 @IH2 @Hin ]
-qed.
-
-lemma fresh_vclose_tm : βˆ€u,x.x βˆ‰ FV (Ξ½x.u). //
-qed.
-
-lemma fresh_swap_tm : βˆ€z1,z2,u.z1 βˆ‰ FV u β†’ z2 βˆ‰ FV u β†’ swap π”Έ z1 z2 Β· u = u.
-#z1 #z2 #u elim u
-[2: normalize in βŠ’ (?β†’%β†’%β†’?); #x #Hz1 #Hz2 whd in βŠ’ (??%?); >swap_other //
-  [ @(not_to_not β€¦ Hz2) | @(not_to_not β€¦ Hz1) ] //
-|1: //
-| #s #v #IH normalize #Hz1 #Hz2 >IH // [@Hz2|@Hz1]
-| #v1 #v2 #IH1 #IH2 normalize #Hz1 #Hz2
-  >IH1 [| @(not_to_not β€¦ Hz2) @in_list_to_in_list_append_l | @(not_to_not β€¦ Hz1) @in_list_to_in_list_append_l ]
-  >IH2 // [@(not_to_not β€¦ Hz2) @in_list_to_in_list_append_r | @(not_to_not β€¦ Hz1) @in_list_to_in_list_append_r ]
-]
-qed.
-
-theorem tm_to_tm2 : βˆ€u.tm u β†’ tm2 u.
-#t #Ht elim Ht
-[ #n #Hn cases (not_le_Sn_O n) #Hfalse cases (Hfalse Hn)
-| @tm_par
-| #u #v #Hu #Hv @tm_app
-| #x #s #u #Hu #IHu <(vclose_vopen x u) @tm_lam
-  [ @fresh_vclose_tm
-  | #y #Hy <(fresh_swap_tm x y (Ξ½x.u)) /2/ @fresh_vclose_tm ]
-]
-qed.
-
-theorem tm2_to_tm : βˆ€u.tm2 u β†’ tm u.
-#u #pu elim pu /2/ #x #s #v #Hx #Hv #IH %4 @IH //
-qed.
-
-definition PAR β‰ Ξ»x.mk_TM (par x) ?. // qed.
-definition APP β‰ Ξ»u,v:TM.mk_TM (app u v) ?./2/ qed.
-definition LAM β‰ Ξ»x,s.Ξ»u:TM.mk_TM (lam x s u) ?./2/ qed.
-
-axiom vopen_tm_down : βˆ€u,x,k.tm_or_ctx (S k) u β†’ tm_or_ctx k (u⌈xβŒ‰).
-(* needs true_plus_false
-
-#u #x #k #Hu elim Hu
-[ #n #Hn normalize cases (true_or_false (eqb n O)) #H >H [%2]
-  normalize >(?: leb n O = false) [|cases n in H; // >eqb_n_n #H destruct (H) ]
-  normalize lapply Hn cases n in H; normalize [ #Hfalse destruct (Hfalse) ]
-  #n0 #_ #Hn0 % @le_S_S_to_le //
-| #x0 %2
-| #v1 #v2 #Hv1 #Hv2 #IH1 #IH2 %3 //
-| #x0 #s #v #Hv #IH normalize @daemon
-]
-qed.
-*)
-
-definition vopen_TM β‰ Ξ»u:CTX.Ξ»x.mk_TM (u⌈xβŒ‰) (vopen_tm_down β€¦). @ctx_of_CTX qed.
-
-axiom vclose_tm_up : βˆ€u,x,k.tm_or_ctx k u β†’ tm_or_ctx (S k) (Ξ½x.u).
-
-definition vclose_TM β‰ Ξ»u:TM.Ξ»x.mk_CTX (Ξ½x.u) (vclose_tm_up β€¦). @tm_of_TM qed.
-
-interpretation "ln wf term variable open" 'open u x = (vopen_TM u x).
-interpretation "ln wf term variable close" 'nu x u = (vclose_TM u x).
-
-theorem tm_alpha : βˆ€x,y,s,u.x βˆ‰ FV u β†’ y βˆ‰ FV u β†’ lam x s (u⌈xβŒ‰) = lam y s (u⌈yβŒ‰).
-#x #y #s #u #Hx #Hy whd in βŠ’ (??%%); @eq_f >nominal_eta // >nominal_eta //
-qed.
-
-theorem TM_ind_plus : 
-(* non si puΓ² dare il principio in modo dipendente (almeno utilizzando tm2)
-   la "prova" purtroppo Γ¨ in Type e non si puΓ² garantire che sia esattamente
-   quella che ci aspetteremmo
- *)
- βˆ€P:pretm β†’ Type[0].
-   (βˆ€x:𝔸.P (PAR x)) β†’ 
-   (βˆ€v1,v2:TM.P v1 β†’ P v2 β†’ P (APP v1 v2)) β†’ 
-   βˆ€C:list π”Έ.
-   (βˆ€x,s.βˆ€v:CTX.x βˆ‰ FV v β†’ x βˆ‰ C β†’ 
-     (βˆ€y.y βˆ‰ FV v β†’ P (v⌈yβŒ‰)) β†’ P (LAM x s (v⌈xβŒ‰))) β†’
- βˆ€u:TM.P u.
-#P #Hpar #Happ #C #Hlam * #u #pu elim (tm_to_tm2 u pu) //
-[ #v1 #v2 #pv1 #pv2 #IH1 #IH2 @(Happ (mk_TM β€¦) (mk_TM β€¦)) /2/
-| #x #s #v #Hx #pv #IH
-  lapply (p_fresh β€¦ (C@FV v)) letin x0 β‰ (N_fresh β€¦ (C@FV v)) #Hx0
-  >(?:lam x s (v⌈xβŒ‰) = lam x0 s (v⌈x0βŒ‰))
-  [|@tm_alpha // @(not_to_not β€¦ Hx0) @in_list_to_in_list_append_r ]
-  @(Hlam x0 s (mk_CTX v ?) ??)
-  [ <(nominal_eta β€¦ Hx) @vclose_tm_up @tm2_to_tm @pv //
-  | @(not_to_not β€¦ Hx0) @in_list_to_in_list_append_r
-  | @(not_to_not β€¦ Hx0) @in_list_to_in_list_append_l
-  | @IH ]
-]
-qed.
-
-notation 
-"hvbox('nominal' u 'return' out 'with' 
-       [ 'xpar' ident x β‡’ f1 
-       | 'xapp' ident v1 ident v2 ident recv1 ident recv2 β‡’ f2 
-       | 'xlam' β¨ident y # C❩ ident s ident w ident py1 ident py2 ident recw β‡’ f3 ])"
-with precedence 48 
-for @{ TM_ind_plus $out (Ξ»${ident x}:?.$f1)
-       (Ξ»${ident v1}:?.Ξ»${ident v2}:?.Ξ»${ident recv1}:?.Ξ»${ident recv2}:?.$f2)
-       $C (Ξ»${ident y}:?.Ξ»${ident s}:?.Ξ»${ident w}:?.Ξ»${ident py1}:?.Ξ»${ident py2}:?.Ξ»${ident recw}:?.$f3)
-       $u }.
-       
-(* include "basics/jmeq.ma".*)
-
-definition subst β‰ (Ξ»u:TM.Ξ»x,v.
-  nominal u return (Ξ»_.TM) with 
-  [ xpar x0 β‡’ match x == x0 with [ true β‡’ v | false β‡’ u ]
-  | xapp v1 v2 recv1 recv2 β‡’ APP recv1 recv2
-  | xlam β¨y # x::FV v❩ s w py1 py2 recw β‡’ LAM y s (recw y py1) ]).
-
-lemma fasfd : βˆ€s,v. pretm_of_TM (subst (LAM O s (PAR 1)) O v) = pretm_of_TM (LAM O s (PAR 1)).
-#s #v normalize in βŠ’ (??%?);
-
-
-theorem tm2_ind_plus : 
-(* non si puΓ² dare il principio in modo dipendente (almeno utilizzando tm2) *)
- βˆ€P:pretm β†’ Type[0].
-   (βˆ€x:𝔸.P (par x)) β†’ 
-   (βˆ€v1,v2.tm2 v1 β†’ tm2 v2 β†’ P v1 β†’ P v2 β†’ P (app v1 v2)) β†’ 
-   βˆ€C:list π”Έ.
-   (βˆ€x,s,v.x βˆ‰ FV v β†’ x βˆ‰ C β†’ (βˆ€y.y βˆ‰ FV v β†’ tm2 (v⌈yβŒ‰)) β†’ 
-     (βˆ€y.y βˆ‰ FV v β†’ P (v⌈yβŒ‰)) β†’ P (lam x s (v⌈xβŒ‰))) β†’
- βˆ€u.tm2 u β†’ P u.
-#P #Hpar #Happ #C #Hlam #u #pu elim pu /2/
-#x #s #v #px #pv #IH 
-lapply (p_fresh β€¦ (C@FV v)) letin y β‰ (N_fresh β€¦ (C@FV v)) #Hy
->(?:lam x s (v⌈xβŒ‰) = lam y s (v⌈yβŒ‰)) [| @tm_alpha // @(not_to_not β€¦ Hy) @in_list_to_in_list_append_r ]
-@Hlam /2/ lapply Hy -Hy @not_to_not #Hy
-[ @in_list_to_in_list_append_r @Hy | @in_list_to_in_list_append_l @Hy ]
-qed.
-
-definition check_tm β‰ 
-  Ξ»u.pretm_ind_plus ? (Ξ»_.true) (Ξ»_.false) 
-    (Ξ»v1,v2,r1,r2.r1 βˆ§ r2) [ ] (Ξ»x,s,v,pv1,pv2,rv.rv) u.
-
-(*
-lemma check_tm_complete : βˆ€u.tm u β†’ check_tm u = true.
-#u #pu @(tm2_ind_plus β€¦ [ ] β€¦ (tm_to_tm2 ? pu)) //
-[ #v1 #v2 #pv1 #pv2 #IH1 #IH2
-| #x #s #v #Hx1 #Hx2 #Hv #IH
-*)
-
-notation 
-"hvbox('nominal' u 'return' out 'with' 
-       [ 'xpar' ident x β‡’ f1 
-       | 'xapp' ident v1 ident v2 ident pv1 ident pv2 ident recv1 ident recv2 β‡’ f2 
-       | 'xlam' β¨ident y # C❩ ident s ident w ident py1 ident py2 ident pw ident recw β‡’ f3 ])"
-with precedence 48 
-for @{ tm2_ind_plus $out (Ξ»${ident x}:?.$f1)
-       (Ξ»${ident v1}:?.Ξ»${ident v2}:?.Ξ»${ident pv1}:?.Ξ»${ident pv2}:?.Ξ»${ident recv1}:?.Ξ»${ident recv2}:?.$f2)
-       $C (Ξ»${ident y}:?.Ξ»${ident s}:?.Ξ»${ident w}:?.Ξ»${ident py1}:?.Ξ»${ident py2}:?.Ξ»${ident pw}:?.Ξ»${ident recw}:?.$f3)
-       ? (tm_to_tm2 ? $u) }.
-(* notation 
-"hvbox('nominal' u 'with' 
-       [ 'xlam' ident x # C ident s ident w β‡’ f3 ])"
-with precedence 48 
-for @{ tm2_ind_plus ???
- $C (Ξ»${ident x}:?.Ξ»${ident s}:?.Ξ»${ident w}:?.Ξ»${ident py1}:?.Ξ»${ident py2}:?.
-     Ξ»${ident pw}:?.Ξ»${ident recw}:?.$f3) $u (tm_to_tm2 ??) }.
-*)
-
-
-definition subst β‰ (Ξ»u.Ξ»pu:tm u.Ξ»x,v.
-  nominal pu return (Ξ»_.pretm) with 
-  [ xpar x0 β‡’ match x == x0 with [ true β‡’ v | false β‡’ u ]
-  | xapp v1 v2 pv1 pv2 recv1 recv2 β‡’ app recv1 recv2
-  | xlam β¨y # x::FV v❩ s w py1 py2 pw recw β‡’ lam y s (recw y py1) ]).
-  
-lemma fasfd : βˆ€x,s,u,p1,v. subst (lam x s u) p1 x v = lam x s u.
-#x #s #u #p1 #v
-
-
-definition subst β‰ Ξ»u.Ξ»pu:tm u.Ξ»x,y.
-  tm2_ind_plus ?
-  (* par x0 *)              (Ξ»x0.match x == x0 with [ true β‡’ v | false β‡’ u ])
-  (* app v1 v2 *)           (Ξ»v1,v2,pv1,pv2,recv1,recv2.app recv1 recv2)
-  (* lam y#(x::FV v) s w *) (x::FV v) (Ξ»y,s,w,py1,py2,pw,recw.lam y s (recw y py1)) 
-  u (tm_to_tm2 β€¦ pu).
-check subst
-definition subst β‰ Ξ»u.Ξ»pu:tm u.Ξ»x,v.
-  nominal u with 
-  [ xlam y # (x::FV v) s w ^ ? ].
-
-(*
-notation > "Ξ› ident x. ident T [ident x] β†¦ P"
-  with precedence 48 for @{'foo (Ξ»${ident x}.Ξ»${ident T}.$P)}.
-
-notation < "Ξ› ident x. ident T [ident x] β†¦ P"
-  with precedence 48 for @{'foo (Ξ»${ident x}:$Q.Ξ»${ident T}:$R.$P)}.
-*)
-
-(*
-notation 
-"hvbox('nominal' u 'with' 
-       [ 'xpar' ident x β‡’ f1 
-       | 'xapp' ident v1 ident v2  β‡’ f2
-       | 'xlam' ident x # C s w β‡’ f3 ])"
-with precedence 48 
-for @{ tm2_ind_plus ? (Ξ»${ident x}:$Tx.$f1) 
- (Ξ»${ident v1}:$Tv1.Ξ»${ident v2}:$Tv2.Ξ»${ident pv1}:$Tpv1.Ξ»${ident pv2}:$Tpv2.Ξ»${ident recv1}:$Trv1.Ξ»${ident recv2}:$Trv2.$f2)
- $C (Ξ»${ident x}:$Tx.Ξ»${ident s}:$Ts.Ξ»${ident w}:$Tw.Ξ»${ident py1}:$Tpy1.Ξ»${ident py2}:$Tpy2.Ξ»${ident pw}:$Tpw.Ξ»${ident recw}:$Trw.$f3) $u (tm_to_tm2 ??) }.
-*)
-
-(*
-notation 
-"hvbox('nominal' u 'with' 
-       [ 'xpar' ident x ^ f1 
-       | 'xapp' ident v1 ident v2 ^ f2 ])"
-(*       | 'xlam' ident x # C s w ^ f3 ]) *)
-with precedence 48 
-for @{ tm2_ind_plus ? (Ξ»${ident x}:$Tx.$f1) 
- (Ξ»${ident v1}:$Tv1.Ξ»${ident v2}:$Tv2.Ξ»${ident pv1}:$Tpv1.Ξ»${ident pv2}:$Tpv2.Ξ»${ident recv1}:$Trv1.Ξ»${ident recv2}:$Trv2.$f2)
- $C (Ξ»${ident x}:$Tx.Ξ»${ident s}:$Ts.Ξ»${ident w}:$Tw.Ξ»${ident py1}:$Tpy1.Ξ»${ident py2}:$Tpy2.Ξ»${ident pw}:$Tpw.Ξ»${ident recw}:$Trw.$f3) $u (tm_to_tm2 ??) }.
-*)
-notation 
-"hvbox('nominal' u 'with' 
-       [ 'xpar' ident x ^ f1 
-       | 'xapp' ident v1 ident v2 ^ f2 ])"
-with precedence 48 
-for @{ tm2_ind_plus ? (Ξ»${ident x}:?.$f1) 
- (Ξ»${ident v1}:$Tv1.Ξ»${ident v2}:$Tv2.Ξ»${ident pv1}:$Tpv1.Ξ»${ident pv2}:$Tpv2.Ξ»${ident recv1}:$Trv1.Ξ»${ident recv2}:$Trv2.$f2)
- $C (Ξ»${ident x}:?.Ξ»${ident s}:$Ts.Ξ»${ident w}:$Tw.Ξ»${ident py1}:$Tpy1.Ξ»${ident py2}:$Tpy2.Ξ»${ident pw}:$Tpw.Ξ»${ident recw}:$Trw.$f3) $u (tm_to_tm2 ??) }.
-
-
-definition subst β‰ Ξ»u.Ξ»pu:tm u.Ξ»x,v.
-  nominal u with 
-  [ xpar x0 ^ match x == x0 with [ true β‡’ v | false β‡’ u ]
-  | xapp v1 v2 ^ ? ].
-  | xlam y # (x::FV v) s w ^ ? ].
-  
-  
-  (* par x0 *)              (Ξ»x0.match x == x0 with [ true β‡’ v | false β‡’ u ])
-  (* app v1 v2 *)           (Ξ»v1,v2,pv1,pv2,recv1,recv2.app recv1 recv2)
-  (* lam y#(x::FV v) s w *) (x::FV v) (Ξ»y,s,w,py1,py2,pw,recw.lam y s (recw y py1)) 
-  u (tm_to_tm2 β€¦ pu).
-*)
-definition subst β‰ Ξ»u.Ξ»pu:tm u.Ξ»x,v.
-  tm2_ind_plus ?
-  (* par x0 *)              (Ξ»x0.match x == x0 with [ true β‡’ v | false β‡’ u ])
-  (* app v1 v2 *)           (Ξ»v1,v2,pv1,pv2,recv1,recv2.app recv1 recv2)
-  (* lam y#(x::FV v) s w *) (x::FV v) (Ξ»y,s,w,py1,py2,pw,recw.lam y s (recw y py1)) 
-  u (tm_to_tm2 β€¦ pu).
-
-check subst
-
-axiom in_Env : π”Έ Γ— tp β†’ Env β†’ Prop.
-notation "X β—ƒ G" non associative with precedence 45 for @{'lefttriangle $X $G}.
-interpretation "Env membership" 'lefttriangle x l = (in_Env x l).
-
-
-
-inductive judg : list tp β†’ tm β†’ tp β†’ Prop β‰ 
-| t_var : βˆ€g,n,t.Nth ? n g = Some ? t β†’ judg g (var n) t
-| t_app : βˆ€g,m,n,t,u.judg g m (arr t u) β†’ judg g n t β†’ judg g (app m n) u
-| t_abs : βˆ€g,t,m,u.judg (t::g) m u β†’ judg g (abs t m) (arr t u).
-
-definition Env := list (𝔸 Γ— tp).
-
-axiom vclose_env : Env β†’ list tp.
-axiom vclose_tm : Env β†’ tm β†’ tm.
-axiom Lam : π”Έ β†’ tp β†’ tm β†’ tm.
-definition Judg β‰ Ξ»G,M,T.judg (vclose_env G) (vclose_tm G M) T.
-definition dom β‰ Ξ»G:Env.map ?? (fst ??) G.
-
-definition sctx β‰ π”Έ Γ— tm.
-axiom swap_tm : π”Έ β†’ π”Έ β†’ tm β†’ tm.
-definition sctx_app : sctx β†’ π”Έ β†’ tm β‰ Ξ»M0,Y.let βŒ©X,MβŒͺ β‰ M0 in swap_tm X Y M.
-
-axiom in_list : βˆ€A:Type[0].A β†’ list A β†’ Prop.
-interpretation "list membership" 'mem x l = (in_list ? x l).
-interpretation "list non-membership" 'notmem x l = (Not (in_list ? x l)).
-
-axiom in_Env : π”Έ Γ— tp β†’ Env β†’ Prop.
-notation "X β—ƒ G" non associative with precedence 45 for @{'lefttriangle $X $G}.
-interpretation "Env membership" 'lefttriangle x l = (in_Env x l).
-
-let rec FV M β‰ match M with 
-  [ par X β‡’ [X]
-  | app M1 M2 β‡’ FV M1@FV M2
-  | abs T M0 β‡’ FV M0
-  | _ β‡’ [ ] ].
-
-(* axiom Lookup : π”Έ β†’ Env β†’ option tp. *)
-
-(* forma alto livello del judgment
-   t_abs* : βˆ€G,T,X,M,U.
-            (βˆ€Y βˆ‰ supp(M).Judg (〈Y,TβŒͺ::G) (M[Y]) U) β†’ 
-            Judg G (Lam X T (M[X])) (arr T U) *)
-
-(* prima dimostrare, poi perfezionare gli assiomi, poi dimostrarli *)
-
-axiom Judg_ind : βˆ€P:Env β†’ tm β†’ tp β†’ Prop.
-  (βˆ€X,G,T.〈X,TβŒͺ β—ƒ G β†’ P G (par X) T) β†’ 
-  (βˆ€G,M,N,T,U.
-    Judg G M (arr T U) β†’ Judg G N T β†’ 
-    P G M (arr T U) β†’ P G N T β†’ P G (app M N) U) β†’ 
-  (βˆ€G,T1,T2,X,M1.
-    (βˆ€Y.Y βˆ‰ (FV (Lam X T1 (sctx_app M1 X))) β†’ Judg (〈Y,T1βŒͺ::G) (sctx_app M1 Y) T2) β†’
-    (βˆ€Y.Y βˆ‰ (FV (Lam X T1 (sctx_app M1 X))) β†’ P (〈Y,T1βŒͺ::G) (sctx_app M1 Y) T2) β†’ 
-    P G (Lam X T1 (sctx_app M1 X)) (arr T1 T2)) β†’ 
-  βˆ€G,M,T.Judg G M T β†’ P G M T.
-
-axiom t_par : βˆ€X,G,T.〈X,TβŒͺ β—ƒ G β†’ Judg G (par X) T.
-axiom t_app2 : βˆ€G,M,N,T,U.Judg G M (arr T U) β†’ Judg G N T β†’ Judg G (app M N) U.
-axiom t_Lam : βˆ€G,X,M,T,U.Judg (〈X,TβŒͺ::G) M U β†’ Judg G (Lam X T M) (arr T U).
-
-definition subenv β‰ Ξ»G1,G2.βˆ€x.x β—ƒ G1 β†’ x β—ƒ G2.
-interpretation "subenv" 'subseteq G1 G2 = (subenv G1 G2).
-
-axiom daemon : βˆ€P:Prop.P.
-
-theorem weakening : βˆ€G1,G2,M,T.G1 βŠ† G2 β†’ Judg G1 M T β†’ Judg G2 M T.
-#G1 #G2 #M #T #Hsub #HJ lapply Hsub lapply G2 -G2 change with (βˆ€G2.?)
-@(Judg_ind β€¦ HJ)
-[ #X #G #T0 #Hin #G2 #Hsub @t_par @Hsub //
-| #G #M0 #N #T0 #U #HM0 #HN #IH1 #IH2 #G2 #Hsub @t_app2
-  [| @IH1 // | @IH2 // ]
-| #G #T1 #T2 #X #M1 #HM1 #IH #G2 #Hsub @t_Lam @IH 
-  [ (* trivial property of Lam *) @daemon 
-  | (* trivial property of subenv *) @daemon ]
-]
-qed.
-
-(* Serve un tipo Tm per i termini localmente chiusi e i suoi principi di induzione e
-   ricorsione *)
\ No newline at end of file