]> matita.cs.unibo.it Git - helm.git/commitdiff
More improvements.
authorWilmer Ricciotti <ricciott@cs.unibo.it>
Fri, 19 Jun 2009 14:53:57 +0000 (14:53 +0000)
committerWilmer Ricciotti <ricciott@cs.unibo.it>
Fri, 19 Jun 2009 14:53:57 +0000 (14:53 +0000)
helm/software/matita/contribs/POPLmark/Fsub/adeq.ma
helm/software/matita/contribs/POPLmark/Fsub/defn.ma
helm/software/matita/contribs/POPLmark/Fsub/part1a.ma
helm/software/matita/contribs/POPLmark/Fsub/util.ma

index 056a5105b8d6cca87edfa2a88bb346e751c71b97..d4fdeca8193a1ffef50cb709d56821ed0cbd0c35 100644 (file)
@@ -1,4 +1,3 @@
-
 (**************************************************************************)
 (*       ___                                                              *)
 (*      ||M||                                                             *)
@@ -27,58 +26,15 @@ record nbound : Set \def {
                            nbtype : NTyp
                          }.
 
-inductive option (A:Type) : Set \def
-| Some : A \to option A
-| None : option A.
-
-definition swap : nat → nat → nat → nat ≝
-  λu,v,x.match (eqb x u) with
-    [true ⇒ v
-    |false ⇒ match (eqb x v) with
-       [true ⇒ u
-       |false ⇒ x]].
-       
-lemma swap_left : ∀x,y.(swap x y x) = y.
-intros;unfold swap;rewrite > eqb_n_n;simplify;reflexivity;
-qed.
-
-lemma swap_right : ∀x,y.(swap x y y) = x.
-intros;unfold swap;rewrite > eqb_n_n;apply (eqb_elim y x);intro;autobatch;
-qed.
-
-lemma swap_other : \forall x,y,z.(z \neq x) \to (z \neq y) \to (swap x y z) = z.
-intros;unfold swap;apply (eqb_elim z x);intro;simplify
-  [elim H;assumption
-  |rewrite > not_eq_to_eqb_false;autobatch]
-qed.
-
-lemma swap_inv : \forall u,v,x.(swap u v (swap u v x)) = x.
-intros;unfold in match (swap u v x);apply (eqb_elim x u);intro;simplify
-  [autobatch paramodulation
-  |apply (eqb_elim x v);intro;simplify
-     [autobatch paramodulation
-     |apply swap_other;assumption]]
-qed.
-
-lemma swap_inj : ∀u,v,x,y.swap u v x = swap u v y → x = y.
-intros 4;unfold swap;apply (eqb_elim x u);simplify;intro
-  [apply (eqb_elim y u);simplify;intro
-     [intro;autobatch paramodulation
-     |apply (eqb_elim y v);simplify;intros
-        [autobatch paramodulation
-        |elim H2;symmetry;assumption]]
-  |apply (eqb_elim y u);simplify;intro
-     [apply (eqb_elim x v);simplify;intros;
-        [autobatch paramodulation
-        |elim H2;assumption]
-     |apply (eqb_elim x v);simplify;intro
-        [apply (eqb_elim y v);simplify;intros
-           [autobatch paramodulation
-           |elim H1;symmetry;assumption]
-        |apply (eqb_elim y v);simplify;intros
-           [elim H;assumption
-           |assumption]]]]
-qed.
+let rec encodetype T vars on T ≝
+  match T with
+  [ (TName n) ⇒ match (lookup n vars) with
+    [ true ⇒ (TVar (posn vars n))
+    | false ⇒ (TFree n)]
+  | NTop ⇒ Top
+  | (NArrow T1 T2) ⇒ Arrow (encodetype T1 vars) (encodetype T2 vars)
+  | (NForall n2 T1 T2) ⇒ Forall (encodetype T1 vars) 
+                                (encodetype T2 (n2::vars))].
 
 let rec swap_NTyp u v T on T ≝
   match T with
@@ -96,9 +52,6 @@ let rec swap_Typ u v T on T \def
      |(Arrow T1 T2) ⇒ (Arrow (swap_Typ u v T1) (swap_Typ u v T2))
      |(Forall T1 T2) ⇒ (Forall (swap_Typ u v T1) (swap_Typ u v T2))].
                   
-definition swap_list : nat \to nat \to (list nat) \to (list nat) ≝
-  \lambda u,v,l.(map ? ? (swap u v) l). 
 let rec var_NTyp (T:NTyp):list nat\def 
   match T with 
   [TName x ⇒ [x]
@@ -106,84 +59,6 @@ let rec var_NTyp (T:NTyp):list nat\def
   |NArrow U V ⇒ (var_NTyp U)@(var_NTyp V)
   |NForall X U V ⇒ X::(var_NTyp U)@(var_NTyp V)].
 
-inductive alpha_eq : NTyp \to NTyp \to Prop \def
-| A_refl : \forall T.(alpha_eq T T)
-| A_arrow : \forall T1,T2,U1,U2.(alpha_eq T1 U1) \to (alpha_eq T2 U2) \to
-                                (alpha_eq (NArrow T1 T2) (NArrow U1 U2))
-| A_forall : \forall T1,T2,U1,U2,X,Y.
-             (alpha_eq T1 U1) \to 
-             (\forall Z.
-                 \lnot (in_list nat Z (X::Y::((var_NTyp T2)@(var_NTyp U2))))
-                 \to (alpha_eq (swap_NTyp Z X T2) (swap_NTyp Z Y U2))) \to
-             (alpha_eq (NForall X T1 T2) (NForall Y U1 U2)).
-
-let rec posn l x on l ≝
-  match l with
-  [ nil ⇒ O
-  | (cons (y:nat) l2) ⇒
-      match (eqb x y) with
-            [ true ⇒ O
-            | false ⇒ S (posn l2 x)]].
-            
-let rec length A l on l ≝
-  match l with
-    [ nil ⇒ O
-    | (cons (y:A) l2) ⇒ S (length A l2)].
-    
-let rec lookup n l on l ≝
-  match l with
-    [ nil ⇒ false
-    | cons (x:nat) l1 ⇒ match (eqb n x) with
-              [true ⇒ true
-              |false ⇒ (lookup n l1)]]. 
-                             
-let rec encodetype T vars on T ≝
-  match T with
-  [ (TName n) ⇒ match (lookup n vars) with
-    [ true ⇒ (TVar (posn vars n))
-    | false ⇒ (TFree n)]
-  | NTop ⇒ Top
-  | (NArrow T1 T2) ⇒ Arrow (encodetype T1 vars) (encodetype T2 vars)
-  | (NForall n2 T1 T2) ⇒ Forall (encodetype T1 vars) 
-                                (encodetype T2 (n2::vars))].
-
-let rec head (A:Type) l on l ≝
-  match l with
-  [ nil ⇒ None A
-  | (cons (x:A) l2) ⇒ Some A x].
-
-let rec nth n l on n ≝
-  match n with
-  [ O ⇒ match l with
-    [ nil ⇒ O
-    | (cons x l2) ⇒ x]
-  | (S n2) ⇒ (nth n2 (tail ? l))]. 
-
-definition max_list : (list nat) \to nat \def
-  \lambda l.let rec aux l0 m on l0 \def
-    match l0 with
-      [ nil ⇒ m
-      | (cons n l2) ⇒ (aux l2 (max m n))]
-    in aux l O.
-
-let rec decodetype T vars C on T \def
-  match T with
-  [ TVar n ⇒ TName (nth n vars)
-  | TFree x  ⇒ TName x
-  | Top ⇒ NTop
-  | Arrow T1 T2 ⇒ NArrow (decodetype T1 vars C) (decodetype T2 vars C)
-  | Forall T1 T2 ⇒ NForall (S (max_list (vars@C))) (decodetype T1 vars C) 
-       (decodetype T2 ((S (max_list (vars@C)))::vars) C)].
-       
-definition sublist: \forall A:Type.(list A) \to (list A) \to Prop \def
-  \lambda A,l1,l2.\forall x.(in_list ? x l1) \to (in_list ? x l2).
-  
-let rec remove_nat (x:nat) (l:list nat) on l \def
-  match l with
-  [ nil ⇒ (nil nat) 
-  | (cons y l2) ⇒ match (eqb x y) with
-                  [ true ⇒ (remove_nat x l2)
-                  | false ⇒ (y :: (remove_nat x l2)) ]].
 
 let rec fv_NTyp (T:NTyp):list nat\def 
   match T with 
@@ -205,56 +80,55 @@ let rec subst_NTyp_var T X Y \def
                    | false ⇒ (NForall Z (subst_NTyp_var U X Y) 
                                         (subst_NTyp_var V X Y))]].
 
+definition filter_ntypes : list nbound → list nbound ≝
+  λG.(filter ? G (λB.match B with [mk_nbound B X T ⇒ B])).
+
 definition fv_Nenv : list nbound → list nat ≝
-  map nbound nat
+  λG.map nbound nat
     (λb.match b with 
-      [mk_nbound (B:bool) (X:nat) (T:NTyp) ⇒ X]).
+      [mk_nbound (B:bool) (X:nat) (T:NTyp) ⇒ X]) (filter_ntypes G).
           
 inductive NWFType : (list nbound) → NTyp → Prop ≝
-  | NWFT_TName : ∀X,G.(in_list ? X (fv_Nenv G))
+  | NWFT_TName : ∀X,G.(X ∈ (fv_Nenv G))
                 → (NWFType G (TName X))
   | NWFT_Top : ∀G.(NWFType G NTop)
   | NWFT_Arrow : ∀G,T,U.(NWFType G T) → (NWFType G U) →
                 (NWFType G (NArrow T U))
   | NWFT_Forall : ∀G,X,T,U.(NWFType G T) →
-                  (∀Y.¬(in_list ? Y (fv_Nenv G)) →
-                       (Y = X ∨ ¬(in_list ? Y (fv_NTyp U))) → 
+                  (∀Y.Y ∉ (fv_Nenv G) →
+                       (Y = X ∨ Y ∉ (fv_NTyp U)) → 
                     (NWFType ((mk_nbound true Y T) :: G) (swap_NTyp Y X U))) →
                  (NWFType G (NForall X T U)).
 
 inductive NWFEnv : (list nbound) → Prop ≝
   | NWFE_Empty : (NWFEnv (nil ?))
   | NWFE_cons : ∀B,X,T,G.(NWFEnv G) →
-                  ¬(in_list ? X (fv_Nenv G)) → 
+                  X ∉ (fv_Nenv G) → 
                   (NWFType G T) → (NWFEnv ((mk_nbound B X T) :: G)).
           
 inductive NJSubtype : (list nbound) → NTyp → NTyp → Prop ≝
   | NSA_Top : ∀G,T.(NWFEnv G) → (NWFType G T) → (NJSubtype G T NTop)
   | NSA_Refl_TVar : ∀G,X.(NWFEnv G)
-                   → (in_list ? X (fv_Nenv G))
+                   → X ∈ (fv_Nenv G)
                    → (NJSubtype G (TName X) (TName X))
   | NSA_Trans_TVar : ∀G,X,T,U.
-                     (in_list ? (mk_nbound true X U) G) →
+                     (mk_nbound true X U) ∈ G →
                      (NJSubtype G U T) → (NJSubtype G (TName X) T)
   | NSA_Arrow : ∀G,S1,S2,T1,T2.
                (NJSubtype G T1 S1) → (NJSubtype G S2 T2) →
                (NJSubtype G (NArrow S1 S2) (NArrow T1 T2))
   | NSA_All : ∀G,X,Y,S1,S2,T1,T2.
-              (NWFType G (NForall X S1 S2)) \to
-              (NWFType G (NForall Y T1 T2)) \to
+              (NWFType G (NForall X S1 S2)) 
+              (NWFType G (NForall Y T1 T2)) 
               (NJSubtype G T1 S1) →
-              (∀Z.¬(in_list ? Z (fv_Nenv G)) →
-                  (Z = X \lor \lnot in_list ? Z (fv_NTyp S2)) \to
-                  (Z = Y \lor \lnot in_list ? Z (fv_NTyp T2)) \to
+              (∀Z.Z ∉ (fv_Nenv G) →
+                  (Z = X ∨ Z ∉ (fv_NTyp S2)) →
+                  (Z = Y ∨ Z ∉ (fv_NTyp T2)) →
               (NJSubtype ((mk_nbound true Z T1) :: G) 
                     (swap_NTyp Z X S2) (swap_NTyp Z Y T2))) →  
-              (NJSubtype G (NForall X S1 S2) (NForall Y T1 T2))
-  | NSA_alpha : ∀G,T1,T2,U1,U2.(NJSubtype G T1 U1) → 
-                                (alpha_eq T1 T2) →
-                                (alpha_eq U1 U2) →
-                                (NJSubtype G T2 U2).
+              (NJSubtype G (NForall X S1 S2) (NForall Y T1 T2)).
                                 
-let rec nt_len T \def
+let rec nt_len T 
   match T with
   [ TName X ⇒ O
   | NTop ⇒ O
@@ -269,7 +143,7 @@ definition encodeenv : list nbound → list bound ≝
 lemma eq_fv_Nenv_fv_env : ∀G. fv_Nenv G = fv_env (encodeenv G).
 intro;elim G;simplify
   [reflexivity
-  |rewrite < H;elim a;simplify;reflexivity]
+  |elim a;elim b;simplify;rewrite < H;reflexivity]
 qed.
 
 lemma decidable_eq_Typ : ∀T,U:Typ.decidable (T = U).
@@ -313,8 +187,8 @@ intros;cases b;cases c;cases (bool_to_decidable_eq b1 b2)
 |right;intro;destruct H1;elim H;reflexivity]
 qed.
 
-lemma in_Nenv_to_in_env: ∀l,n,n2.in_list ? (mk_nbound true n n2) l → 
-                 in_list ? (mk_bound true n (encodetype n2 [])) (encodeenv l).
+lemma in_Nenv_to_in_env: ∀l,n,n2.(mk_nbound true n n2) ∈ l → 
+                 (mk_bound true n (encodetype n2 [])) ∈ (encodeenv l).
 intros 3;elim l
   [elim (not_in_list_nil ? ? H)
   |inversion H1;intros;destruct;
@@ -322,46 +196,6 @@ intros 3;elim l
      |elim a;simplify;apply in_list_cons;apply H;assumption]]
 qed.
                  
-lemma in_lookup : \forall x,l.(in_list ? x l) \to (lookup x l = true).
-intros;elim H;simplify
-  [rewrite > eqb_n_n;reflexivity
-  |rewrite > H2;elim (eqb a a1);reflexivity]
-qed.
-
-lemma lookup_in : \forall x,l.(lookup x l = true) \to (in_list ? x l).
-intros 2;elim l
-  [simplify in H;destruct H
-  |generalize in match H1;simplify;elim (decidable_eq_nat x a)
-     [applyS in_list_head
-     |apply in_list_cons;apply H;
-      rewrite > (not_eq_to_eqb_false ? ? H2) in H3;simplify in H3;assumption]]
-qed.
-
-lemma posn_length : \forall x,vars.(in_list ? x vars) \to 
-                       (posn vars x) < (length ? vars).
-intros 2;elim vars
-  [elim (not_in_list_nil ? ? H)
-  |inversion H1;intros;destruct;simplify
-     [rewrite > eqb_n_n;simplify;
-      apply lt_O_S
-     |elim (eqb x a);simplify
-        [apply lt_O_S
-        |apply le_S_S;apply H;assumption]]]
-qed.
-
-lemma in_remove : \forall a,b,l.(a \neq b) \to (in_list ? a l) \to
-                                (in_list ? a (remove_nat b l)).
-intros 4;elim l
-  [elim (not_in_list_nil ? ? H1)
-  |inversion H2;intros;destruct;simplify
-     [rewrite > not_eq_to_eqb_false
-        [simplify;apply in_list_head
-        |intro;apply H;symmetry;assumption]
-     |elim (eqb b a1);simplify
-        [apply H1;assumption
-        |apply in_list_cons;apply H1;assumption]]]
-qed.
-
 lemma NTyp_len_ind : \forall P:NTyp \to Prop.
                        (\forall U.(\forall V.((nt_len V) < (nt_len U)) \to (P V))
                            \to (P U))
@@ -424,30 +258,15 @@ intros;elim T;simplify
 |*:autobatch paramodulation]
 qed.
 
-lemma swap_same : \forall x,y.swap x x y = y.
-intros;elim (decidable_eq_nat y x)
-  [autobatch paramodulation
-  |rewrite > swap_other;autobatch]
-qed.
-
-lemma not_nat_in_to_lookup_false : ∀l,X.¬(in_list ? X l) → lookup X l = false.
-intros 2;elim l;simplify
-  [reflexivity
-  |elim (decidable_eq_nat X a)
-     [elim H1;rewrite > H2;apply in_list_head
-     |rewrite > (not_eq_to_eqb_false ? ? H2);simplify;apply H;intro;apply H1;
-      apply (in_list_cons ? ? ? ? H3);]]
-qed.
-
 lemma fv_encode : ∀T,l1,l2.
-                  (∀x.(in_list ? x (fv_NTyp T)) →
+                  (∀x.x ∈ (fv_NTyp T) →
                      (lookup x l1 = lookup x l2 ∧
                      (lookup x l1 = true → posn l1 x = posn l2 x))) →
                   (encodetype T l1 = encodetype T l2).
 intro;elim T
   [simplify in H;elim (H n)
-     [simplify;rewrite < H1;generalize in match H2;elim (lookup n l1);simplify
-        [rewrite > H3;autobatch
+     [simplify;rewrite < H1;elim (lookup n l1) in H2;simplify
+        [rewrite > H2;autobatch
         |reflexivity]
      |apply in_list_head]
   |simplify;reflexivity
@@ -473,64 +292,9 @@ intro;elim T
      |intros;apply H2;simplify;apply in_list_to_in_list_append_l;autobatch]]
 qed.
 
-lemma lookup_swap : ∀a,b,x,vars.
-                    lookup (swap a b x) (swap_list a b vars) =
-                    lookup x vars.
-intros 4;elim vars;simplify
-  [reflexivity
-  |elim (decidable_eq_nat x a1)
-     [rewrite > H1;rewrite > eqb_n_n;rewrite > eqb_n_n;simplify;reflexivity
-     |rewrite > (not_eq_to_eqb_false ? ? H1);elim (decidable_eq_nat x a)
-        [rewrite > H;rewrite > H2;rewrite > swap_left;
-         elim (decidable_eq_nat b a1)
-           [rewrite < H3;rewrite > swap_right;
-            rewrite > (not_eq_to_eqb_false b a)
-              [reflexivity
-              |intro;autobatch]
-           |rewrite > (swap_other a b a1)
-              [rewrite > (not_eq_to_eqb_false ? ? H3);simplify;reflexivity
-              |*:intro;autobatch]]
-        |elim (decidable_eq_nat x b)
-           [rewrite > H;rewrite > H3;rewrite > swap_right;
-            elim (decidable_eq_nat a1 a)
-              [rewrite > H4;rewrite > swap_left;
-               rewrite > (not_eq_to_eqb_false a b)
-                 [reflexivity
-                 |intro;autobatch]
-              |rewrite > (swap_other a b a1)
-                 [rewrite > (not_eq_to_eqb_false a a1)
-                    [reflexivity
-                    |intro;autobatch]
-                 |assumption
-                 |intro;autobatch]]
-           |rewrite > H;rewrite > (swap_other a b x)
-              [elim (decidable_eq_nat a a1)
-                 [rewrite > H4;rewrite > swap_left;
-                  rewrite > (not_eq_to_eqb_false ? ? H3);reflexivity
-                 |elim (decidable_eq_nat b a1)
-                    [rewrite > H5;rewrite > swap_right;
-                     rewrite > (not_eq_to_eqb_false ? ? H2);reflexivity
-                    |rewrite > (swap_other a b a1)
-                       [rewrite > (not_eq_to_eqb_false ? ? H1);reflexivity
-                       |*:intro;autobatch]]]
-              |*:assumption]]]]]
-qed.
-
-lemma posn_swap : ∀a,b,x,vars.
-                  posn vars x = posn (swap_list a b vars) (swap a b x).
-intros 4;elim vars;simplify
-  [reflexivity
-  |rewrite < H;elim (decidable_eq_nat x a1)
-     [rewrite > H1;do 2 rewrite > eqb_n_n;reflexivity
-     |elim (decidable_eq_nat (swap a b x) (swap a b a1))
-        [elim H1;autobatch
-        |rewrite > (not_eq_to_eqb_false ? ? H1);
-         rewrite > (not_eq_to_eqb_false ? ? H2);reflexivity]]]
-qed.
-
 theorem encode_swap : ∀a,x,T,vars.
-                         ((in_list ? a (fv_NTyp T)) → (in_list ? a vars)) →
-                         (in_list ? x vars) →
+                         (a ∈ (fv_NTyp T) → a ∈ vars) →
+                         x ∈ vars →
                       encodetype T vars = 
                       encodetype (swap_NTyp a x T) (swap_list a x vars).
 intros 3;elim T
@@ -605,42 +369,13 @@ intros 3;elim T
 qed.
 
 lemma encode_swap2 : ∀a:nat.∀x:nat.∀T:NTyp.
-  ¬(in_list ? a (fv_NTyp T)) →
-    ∀vars.in_list ? x vars
-       →encodetype T vars=encodetype (swap_NTyp a x T) (swap_list a x vars).
+  a ∉ (fv_NTyp T) →
+    ∀vars.x ∈ vars
+       → encodetype T vars=encodetype (swap_NTyp a x T) (swap_list a x vars).
 intros;apply (encode_swap ? ? ? ? ? H1);intro;elim (H H2);
 qed.
 
-lemma remove_inlist : \forall x,y,l.(in_list ? x (remove_nat y l)) \to
-                      (in_list ? x l) \land x \neq y.
-intros 3;elim l 0;simplify;intro
-  [elim (not_in_list_nil ? ? H)
-  |elim (decidable_eq_nat y a)
-     [rewrite > H in H2;rewrite > eqb_n_n in H2;simplify in H2;
-      rewrite > H in H1;elim (H1 H2);rewrite > H;split
-        [apply in_list_cons;assumption
-        |assumption]
-     |rewrite > (not_eq_to_eqb_false ? ? H) in H2;simplify in H2;
-      inversion H2;intros;destruct;
-        [split;autobatch
-        |elim (H1 H3);split;autobatch]]]
-qed.
-
-lemma inlist_remove : ∀x,y,l.(in_list ? x l → x \neq y → 
-                (in_list ? x (remove_nat y l))).
-intros 3;elim l
-  [elim (not_in_list_nil ? ? H);
-  |simplify;elim (decidable_eq_nat y a)
-     [rewrite > (eq_to_eqb_true ? ? H3);simplify;apply H
-        [inversion H1;intros;destruct;
-           [elim H2;reflexivity
-           |assumption]
-        |assumption]
-     |rewrite > (not_eq_to_eqb_false ? ? H3);simplify;
-      inversion H1;intros;destruct;autobatch]]
-qed.
-
-lemma incl_fv_var : \forall T.(incl ? (fv_NTyp T) (var_NTyp T)).
+lemma incl_fv_var : \forall T.(fv_NTyp T) ⊆ (var_NTyp T).
 intro;elim T;simplify;unfold;intros
   [1,2:assumption
   |elim (in_list_append_to_or_in_list ? ? ? ? H2);autobatch
@@ -653,7 +388,7 @@ intro;elim T;simplify;unfold;intros
 qed.
 
 lemma fv_encode2 : ∀T,l1,l2.
-                      (∀x.(in_list ? x (fv_NTyp T)) →
+                      (∀x.x ∈ (fv_NTyp T) →
                            (lookup x l1 = lookup x l2 ∧
                             posn l1 x = posn l2 x)) →
                       (encodetype T l1 = encodetype T l2).
@@ -661,33 +396,10 @@ intros;apply fv_encode;intros;elim (H ? H1);split
   [assumption|intro;assumption]
 qed.
 
-lemma alpha_sym : \forall S,T.(alpha_eq S T) \to (alpha_eq T S).
-intros;elim H
-  [apply A_refl
-  |apply A_arrow;assumption
-  |apply A_forall
-     [assumption
-     |intros;apply H4;intro;apply H5;elim (decidable_eq_nat Z n5)
-        [rewrite > H7;apply in_list_head
-        |apply in_list_cons;inversion H6;intros;destruct;
-           [apply in_list_head
-           |apply in_list_cons;inversion H8;intros;destruct;
-              [elim H7;reflexivity
-              |elim (in_list_append_to_or_in_list ? ? ? ? H10);autobatch]]]]]
-qed.
-
-(*legacy*)
-lemma nat_in_list_case :∀G,H,n.in_list nat n (H@G) → 
-                         in_list nat n G ∨ in_list nat n H.
-intros;elim (in_list_append_to_or_in_list ???? H1)
-[right;assumption
-|left;assumption]
-qed.
-
 lemma inlist_fv_swap : ∀x,y,b,T.
-                   (¬ in_list ? b (y::var_NTyp T)) →
-                   in_list ? x (fv_NTyp (swap_NTyp b y T)) →
-                   x ≠ y ∧ (x = b ∨ (in_list ? x (fv_NTyp T))).
+                   b ∉ (y::var_NTyp T) →
+                   x ∈ (fv_NTyp (swap_NTyp b y T)) →
+                   x ≠ y ∧ (x = b ∨ x ∈ (fv_NTyp T)).
 intros 4;elim T
 [simplify in H;simplify;simplify in H1;elim (decidable_eq_nat y n)
  [rewrite > H2 in H1;rewrite > swap_right in H1;inversion H1;intros;destruct;
@@ -722,12 +434,9 @@ intros 4;elim T
    |elim H6
     [left;assumption
     |right;apply in_list_to_in_list_append_r;assumption]]
-  |intro;apply H2;elim (nat_in_list_case (var_NTyp n1) [y] ? H5)
-   [apply (in_list_to_in_list_append_r ? ? (y::var_NTyp n) (var_NTyp n1));
-    assumption
-   |inversion H6;intros;destruct;
-    [apply in_list_head
-    |elim (not_in_list_nil ? ? H7)]]
+  |intro;apply H2;elim (in_list_append_to_or_in_list ?? [y] (var_NTyp n1) H5)
+   [lapply (in_list_singleton_to_eq ??? H6);applyS in_list_head
+   |autobatch]
   |assumption]]
 |simplify;simplify in H3;simplify in H2;elim (in_list_append_to_or_in_list ? ? ? ? H3)
  [elim H
@@ -761,10 +470,10 @@ intros 4;elim T
 qed.
 
 lemma inlist_fv_swap_r : ∀x,y,b,T.
-                   (¬(in_list ? b (y::var_NTyp T))) →
-                   ((x = b ∧ (in_list ? y (fv_NTyp T))) ∨
-                    (x \neq y ∧ (in_list ? x (fv_NTyp T)))) →
-                   (in_list ? x (fv_NTyp (swap_NTyp b y T))).
+                   (b ∉ (y::var_NTyp T)) →
+                   ((x = b ∧ y ∈ (fv_NTyp T)) ∨
+                    (x ≠ y ∧ x ∈ (fv_NTyp T))) →
+                   x ∈ (fv_NTyp (swap_NTyp b y T)).
 intros 4;elim T
 [simplify;simplify in H;simplify in H1;cut (b ≠ n)
  [elim H1
@@ -842,90 +551,6 @@ intros 4;elim T
    |change in ⊢ (???%) with ((y::n::var_NTyp n1)@var_NTyp n2);autobatch]]
  |intro;apply H2;inversion H4;simplify;intros;destruct;autobatch depth=4]]
 qed.               
-
-lemma fv_alpha : ∀S,T.alpha_eq S T → incl ? (fv_NTyp S) (fv_NTyp T).
-intros;elim H;simplify;unfold;intros
-  [assumption
-  |elim (in_list_append_to_or_in_list ? ? ? ? H5);autobatch
-  |elim (in_list_append_to_or_in_list ? ? ? ? H5)
-     [autobatch
-     |elim (fresh_name (n4::n5::var_NTyp n1@var_NTyp n3));
-      apply in_list_to_in_list_append_r; 
-      lapply (H4 ? H7);
-      elim (remove_inlist ? ? ? H6);apply inlist_remove
-        [lapply (inlist_fv_swap_r x n4 a n1) 
-           [elim (inlist_fv_swap x n5 a n3)
-              [elim H11
-                 [rewrite < H12 in H7;elim H7;autobatch depth=5;
-                 |assumption]
-              |intro;apply H7;inversion H10;intros;destruct;autobatch depth=4
-              |autobatch]
-           |intro;apply H7;inversion H10;intros;destruct;autobatch depth=4
-           |right;split;assumption]
-        |intros;intro;lapply (inlist_fv_swap_r x n4 a n1)
-           [lapply (Hletin ? Hletin1);elim (inlist_fv_swap x n5 a n3 ? Hletin2)
-              [apply (H11 H10)
-              |intro;apply H7;elim (decidable_eq_nat a n4)
-                 [rewrite > H12;apply in_list_head
-                 |apply in_list_cons;inversion H11;intros;destruct;autobatch]]
-           |intro;apply H7;inversion H11;intros;destruct;autobatch depth=4
-           |right;split;assumption]]]]
-qed.
-
-theorem alpha_to_encode : ∀S,T.alpha_eq S T → 
-                             ∀vars.encodetype S vars = encodetype T vars.
-intros 3;elim H
-[reflexivity
-|simplify;rewrite > H2;rewrite > H4;reflexivity
-|simplify;rewrite > H2;
- cut (encodetype n1 (n4::vars) = encodetype n3 (n5::vars))
- [rewrite > Hcut;reflexivity
- |elim (fresh_name (n4::n5::var_NTyp n1@var_NTyp n3));
-  lapply (encode_swap2 a n4 n1 ? (n4::vars))
-  [intro;apply H5;autobatch depth=5
-  |lapply (encode_swap2 a n5 n3 ? (n5::vars))
-   [intro;autobatch depth=5
-   |rewrite > Hletin;rewrite > Hletin1;simplify;rewrite > swap_right;
-    rewrite > swap_right;rewrite > (H4 a H5 (a::swap_list a n4 vars));
-    rewrite > (fv_encode2 ? ? (a::swap_list a n5 vars))
-    [reflexivity
-    |intros;elim (decidable_eq_nat n4 n5)
-     [autobatch
-     |cut ((x ≠ n4) ∧ (x ≠ n5))
-      [elim Hcut;elim (decidable_eq_nat x a);simplify
-       [rewrite > (eq_to_eqb_true ? ? H10);simplify;autobatch
-       |rewrite > (not_eq_to_eqb_false ? ? H10);simplify;elim vars;simplify
-        [autobatch
-        |elim H11;rewrite < H12;rewrite > H13;elim (decidable_eq_nat a a1)
-         [rewrite > H14;do 2 rewrite > swap_left;
-          rewrite > (not_eq_to_eqb_false ? ? H8);  
-          rewrite > (not_eq_to_eqb_false ? ? H9);simplify;autobatch
-         |elim (decidable_eq_nat n4 a1)
-          [rewrite > H15;rewrite > swap_right;rewrite > (swap_other a n5 a1)
-           [rewrite > (not_eq_to_eqb_false ? ? H10);rewrite < H15;
-            rewrite > (not_eq_to_eqb_false ? ? H8);autobatch
-           |intro;autobatch
-           |intro;autobatch]
-          |rewrite > (swap_other a n4 a1);elim (decidable_eq_nat n5 a1)
-           [rewrite < H16;rewrite > swap_right;
-            rewrite > (not_eq_to_eqb_false ? ? H9);
-            rewrite > (not_eq_to_eqb_false ? ? H10);autobatch
-           |rewrite > (swap_other a n5 a1);try intro;autobatch
-           |*:intro;autobatch]]]]]
-      |split
-       [lapply (H3 ? H5);lapply (alpha_sym ? ? Hletin2);
-        lapply (fv_alpha ? ? Hletin3);lapply (Hletin4 ? H6);
-        elim (inlist_fv_swap ? ? ? ? ? Hletin5)
-        [assumption
-        |intro;apply H5;inversion H8;intros;destruct;autobatch depth=4]
-       |elim (inlist_fv_swap ? ? ? ? ? H6)
-        [assumption
-        |intro;apply H5;elim (decidable_eq_nat a n4)
-         [applyS in_list_head
-         |apply in_list_cons;inversion H8;intros;destruct;autobatch]]]]]]
-   |apply in_list_head]
-  |apply in_list_head]]]
-qed.
                       
 lemma encode_append : ∀T,U,n,l.length ? l ≤ n →
         subst_type_nat (encodetype T l) U n = encodetype T l.
@@ -937,8 +562,8 @@ intros 2;elim T;simplify
         |intro;rewrite > H2 in Hletin1;unfold in Hletin1;autobatch]
      |cut (lookup n l = false)
         [rewrite > Hcut;reflexivity
-        |generalize in match H1;elim (lookup n l);
-           [elim H2;reflexivity|reflexivity]]]
+        |elim (lookup n l) in H1;
+           [elim H1;reflexivity|reflexivity]]]
   |reflexivity
   |autobatch
   |rewrite > (H ? ? H2);rewrite > H1;
@@ -950,30 +575,30 @@ lemma encode_subst_simple : ∀X,T,l.
   encodetype T l = subst_type_nat (encodetype T (l@[X])) (TFree X) (length ? l).
 intros 2;elim T;simplify
 [cut (lookup n l = true → posn l n = posn (l@[X]) n)
- [generalize in match Hcut;elim (bool_to_decidable_eq (lookup n l) true)
+ [elim (bool_to_decidable_eq (lookup n l) true) in Hcut
   [cut (lookup n (l@[X]) = true)
-   [rewrite > H;rewrite > Hcut1;simplify;
+   [rewrite > H;rewrite > Hcut;simplify;
     cut (eqb (posn (l@[X]) n) (length nat l) = false)
-    [rewrite > Hcut2;simplify;rewrite < (H1 H);reflexivity
-    |generalize in match H;elim l 0
-     [simplify;intro;destruct H2
+    [rewrite > Hcut1;simplify;rewrite < (H1 H);reflexivity
+    |elim l in H 0
+     [simplify;intro;destruct
      |intros 2;simplify;elim (eqb n a);simplify
       [reflexivity
-      |simplify in H3;apply (H2 H3)]]]
-   |generalize in match H;elim l
-    [simplify in H2;destruct H2
-    |generalize in match H3;simplify;elim (eqb n a) 0;simplify;intro
+      |simplify in H3;apply (H H2)]]]
+   |elim l in H
+    [simplify in H;destruct
+    |generalize in match H2;simplify;elim (eqb n a) 0;simplify;intro
      [reflexivity
-     |apply (H2 H4)]]]
+     |apply (H H3)]]]
   |cut (lookup n l = false)
    [elim (decidable_eq_nat n X)
-    [rewrite > Hcut1;rewrite > H2;cut (lookup X (l@[X]) = true)
-     [rewrite > Hcut2;simplify;cut (eqb (posn (l@[X]) X) (length nat l) = true)
-      [rewrite > Hcut3;simplify;reflexivity
-      |generalize in match Hcut1;elim l 0
+    [rewrite > Hcut;rewrite > H2;cut (lookup X (l@[X]) = true)
+     [rewrite > Hcut1;simplify;cut (eqb (posn (l@[X]) X) (length nat l) = true)
+      [rewrite > Hcut2;simplify;reflexivity
+      |elim l in Hcut 0
        [intros;simplify;rewrite > eqb_n_n;simplify;reflexivity
        |simplify;intros 2;rewrite > H2;elim (eqb X a);simplify in H4
-        [destruct H4
+        [destruct
         |apply (H3 H4)]]]
      |elim l;simplify
       [rewrite > eqb_n_n;reflexivity
@@ -981,16 +606,16 @@ intros 2;elim T;simplify
        [reflexivity
        |assumption]]]
     |cut (lookup n l = lookup n (l@[X]))
-     [rewrite < Hcut2;rewrite > Hcut1;simplify;reflexivity
+     [rewrite < Hcut1;rewrite > Hcut;simplify;reflexivity
      |elim l;simplify
       [rewrite > (not_eq_to_eqb_false ? ? H2);simplify;reflexivity
       |elim (eqb n a);simplify
        [reflexivity
        |assumption]]]]
-   |generalize in match H;elim (lookup n l);
-    [elim H2;reflexivity|reflexivity]]]
+   |elim (lookup n l) in H
+    [elim H;reflexivity|reflexivity]]]
  |elim l 0
-  [intro;simplify in H;destruct H
+  [intro;simplify in H;destruct
   |simplify;intros 2;elim (eqb n a);simplify
    [reflexivity
    |simplify in H1;rewrite < (H H1);reflexivity]]]
@@ -1000,8 +625,8 @@ intros 2;elim T;simplify
  rewrite < (H1 ([n]@l));reflexivity]
 qed.
 
-lemma encode_subst : ∀T,X,Y,l.¬(in_list ? X l) → ¬(in_list ? Y l) →
-                              (in_list ? X (fv_NTyp T) → X = Y) → 
+lemma encode_subst : ∀T,X,Y,l.X ∉ l → Y ∉ l →
+                              (X ∈ (fv_NTyp T) → X = Y) → 
                               encodetype (swap_NTyp X Y T) l =
                  subst_type_nat (encodetype T (l@[Y])) (TFree X) (length ? l).
 apply NTyp_len_ind;intro;elim U
@@ -1012,11 +637,11 @@ apply NTyp_len_ind;intro;elim U
    [simplify;rewrite > Hcut;rewrite > (not_nat_in_to_lookup_false ? ? H2);
     simplify;cut (posn (l@[Y]) Y = length ? l)
     [rewrite > Hcut1;rewrite > eqb_n_n;reflexivity
-    |generalize in match H2;elim l;simplify
+    |elim l in H2;simplify
      [rewrite > eqb_n_n;reflexivity
      |elim (decidable_eq_nat Y a)
-      [elim H6;rewrite > H7;apply in_list_head
-      |rewrite > (not_eq_to_eqb_false ? ? H7);simplify;rewrite < H5
+      [elim H5;rewrite > H6;apply in_list_head
+      |rewrite > (not_eq_to_eqb_false ? ? H6);simplify;rewrite < H2
        [reflexivity
        |intro;autobatch]]]]
    |elim l;simplify
@@ -1029,11 +654,11 @@ apply NTyp_len_ind;intro;elim U
    cut (lookup Y (l@[Y]) = true)
    [rewrite > Hcut;simplify;cut (posn (l@[Y]) Y = length ? l)
     [rewrite > Hcut1;rewrite > eqb_n_n;reflexivity
-    |generalize in match H2;elim l;simplify
+    |elim l in H2;simplify
      [rewrite > eqb_n_n;reflexivity
      |elim (decidable_eq_nat Y a)
-      [elim H7;rewrite > H8;apply in_list_head
-      |rewrite > (not_eq_to_eqb_false ? ? H8);simplify;rewrite < H6
+      [elim H6;applyS in_list_head
+      |rewrite > (not_eq_to_eqb_false ? ? H7);simplify;rewrite < H2
        [reflexivity
        |intro;autobatch]]]]
    |elim l;simplify
@@ -1042,17 +667,16 @@ apply NTyp_len_ind;intro;elim U
   |simplify;rewrite > (swap_other X Y n)
    [cut (lookup n l = lookup n (l@[Y]) ∧ 
          (lookup n l = true → posn l n = posn (l@[Y]) n))
-    [elim Hcut;rewrite > H6;generalize in match H7;
-     generalize in match H6;elim (lookup n (l@[Y]));simplify;
-     [rewrite < H9;generalize in match H8;elim l
-      [simplify in H10;destruct H10;
+    [elim Hcut;rewrite > H6;elim (lookup n (l@[Y])) in H7 H6;simplify;
+     [rewrite < H7;elim l in H6
+      [simplify in H6;destruct
       |elim (decidable_eq_nat n a);simplify
-       [rewrite > (eq_to_eqb_true ? ? H12);reflexivity
-       |rewrite > (not_eq_to_eqb_false ? ? H12);
-        simplify;generalize in match H10;elim (eqb (posn l1 n) (length nat l1))
-        [simplify in H13;simplify in H11;
-         rewrite > (not_eq_to_eqb_false ? ? H12) in H11;
-         simplify in H11;lapply (H13 H11);destruct Hletin
+       [rewrite > (eq_to_eqb_true ? ? H9);reflexivity
+       |rewrite > (not_eq_to_eqb_false ? ? H9);
+        simplify;elim (eqb (posn l1 n) (length nat l1)) in H6
+        [simplify in H8;simplify in H6;
+         rewrite > (not_eq_to_eqb_false ? ? H9) in H8;
+         simplify in H8;lapply (H6 H8);destruct
         |reflexivity]]
       |*:assumption]
      |reflexivity]
@@ -1076,14 +700,14 @@ apply NTyp_len_ind;intro;elim U
  |intro;apply H5;simplify;autobatch]
 |simplify;rewrite < (H2 n1 ? ? ? ? H3 H4) 
  [cut (l = swap_list X Y l)
-  [|generalize in match H3;generalize in match H4;elim l;simplify
+  [|elim l in H3 H4;simplify
    [reflexivity
    |elim (decidable_eq_nat a X)
-    [elim H8;rewrite > H9;apply in_list_head
+    [elim H4;applyS in_list_head
     |elim (decidable_eq_nat a Y)
-     [elim H7;rewrite > H10;apply in_list_head
+     [elim H6;applyS in_list_head
      |rewrite > (swap_other X Y a)
-      [rewrite < H6
+      [rewrite < H3
        [reflexivity
        |*:intro;autobatch]
       |*:assumption]]]]]
@@ -1153,13 +777,7 @@ apply NTyp_len_ind;intro;elim U
  |intro;apply H5;simplify;autobatch]]
 qed.
 
-lemma swap_case: ∀u,v,x.(swap u v x) = u ∨ (swap u v x) = v ∨ (swap u v x = x).
-intros;unfold in match swap;simplify;elim (eqb x u);simplify
-  [autobatch
-  |elim (eqb x v);simplify;autobatch]
-qed.
-
-lemma in_fvNTyp_in_fvNenv : ∀G,T.(NWFType G T) → (incl ? (fv_NTyp T) (fv_Nenv G)).
+lemma in_fvNTyp_in_fvNenv : ∀G,T.(NWFType G T) → (fv_NTyp T) ⊆ (fv_Nenv G).
 intros;elim H;simplify;unfold;intros;
 [inversion H2;intros;destruct;
  [assumption
@@ -1202,8 +820,14 @@ intros;elim H;simplify;unfold;intros;
         autobatch depth=5
        |apply (in_remove ? ? ? H15 H16)]]
      |simplify;simplify in H13;elim (remove_inlist ? ? ? H13);
-      elim (nat_in_list_case ? ? ? H14);
-      [apply in_list_to_in_list_append_r;apply in_remove;
+      elim (in_list_append_to_or_in_list ???? H14)
+      [apply in_list_to_in_list_append_l;apply H10;
+       [rewrite < (associative_append ? [x] (fv_Nenv l) (var_NTyp n4));
+        intro;apply H12;simplify;
+        rewrite < (associative_append ? [x] (fv_Nenv l) (n3::var_NTyp n4@var_NTyp n5));
+        elim (in_list_append_to_or_in_list ???? H17);autobatch depth=4
+       |autobatch]
+      |apply in_list_to_in_list_append_r;apply in_remove;
        [elim (remove_inlist ? ? ? H16);intro;apply H18;
         elim (swap_case a n n3)
         [elim H20
@@ -1214,14 +838,8 @@ intros;elim H;simplify;unfold;intros;
         [rewrite < (associative_append ? [x] (fv_Nenv l) (var_NTyp n5));
          intro;apply H12;simplify;
          rewrite < (associative_append ? [x] (fv_Nenv l) (n3::var_NTyp n4 @ var_NTyp n5));
-         elim (nat_in_list_case ? ? ? H17);autobatch depth=4
-        |elim (remove_inlist ? ? ? H16);autobatch]]
-      |apply in_list_to_in_list_append_l;apply H10;
-       [rewrite < (associative_append ? [x] (fv_Nenv l) (var_NTyp n4));
-        intro;apply H12;simplify;
-        rewrite < (associative_append ? [x] (fv_Nenv l) (n3::var_NTyp n4@var_NTyp n5));
-        elim (nat_in_list_case ? ? ? H17);autobatch depth=4
-       |autobatch]]]]
+         elim (in_list_append_to_or_in_list ???? H17);autobatch depth=4
+        |elim (remove_inlist ? ? ? H16);autobatch]]]]]
    |split
     [intro;apply H7;rewrite > H8;apply in_list_head
     |elim (remove_inlist ? ? ? H6);assumption]]
@@ -1229,8 +847,8 @@ intros;elim H;simplify;unfold;intros;
   |right;intro;autobatch depth=5]]]
 qed.
 
-lemma fv_NTyp_fv_Typ : ∀T,X,l.(in_list ? X (fv_NTyp T)) → ¬(in_list ? X l) → 
-                          (in_list ? X (fv_type (encodetype T l))).
+lemma fv_NTyp_fv_Typ : ∀T,X,l.X ∈ (fv_NTyp T) → X ∉ l → 
+                          X ∈ (fv_type (encodetype T l)).
 intros 2;elim T;simplify
   [simplify in H;cut (X = n)
      [rewrite < Hcut;generalize in match (lookup_in X l);elim (lookup X l)
@@ -1291,8 +909,8 @@ intros;elim H;simplify
   |*:apply not_in_list_nil]]] 
 qed.
 
-lemma not_in_list_encodetype : \forall T,l,x.in_list ? x l \to
-                      \lnot (in_list ? x (fv_type (encodetype T l))).
+lemma not_in_list_encodetype : \forall T,l,x.x ∈ l \to
+                      \lnot x ∈ (fv_type (encodetype T l)).
 intro;elim T;simplify
   [apply (bool_elim ? (lookup n l));intro;simplify
      [apply not_in_list_nil
@@ -1300,13 +918,13 @@ intro;elim T;simplify
         [rewrite > (in_lookup ? ? H) in H1;destruct H1
         |apply (not_in_list_nil ? ? H3)]]
   |apply not_in_list_nil
-  |intro;elim (nat_in_list_case ? ? ? H3);autobatch
-  |intro;elim (nat_in_list_case ? ? ? H3);
-     [apply (H1 (n::l) x ? H4);apply in_list_cons;assumption
-     |autobatch]]
+  |intro;elim (in_list_append_to_or_in_list ???? H3);autobatch
+  |intro;elim (in_list_append_to_or_in_list ???? H3);
+     [autobatch
+     |apply (H1 (n::l) x ? H4);apply in_list_cons;assumption]]
 qed.
 
-lemma incl_fv_encode_fv : \forall T,l.incl ? (fv_type (encodetype T l)) (fv_NTyp T).
+lemma incl_fv_encode_fv : \forall T,l.(fv_type (encodetype T l)) ⊆ (fv_NTyp T).
 intro;elim T;simplify;unfold;
   [intro;elim (lookup n l);simplify in H
      [elim (not_in_list_nil ? ? H)
@@ -1374,7 +992,7 @@ lemma adeq_WFE : ∀G.NWFEnv G → WFEnv (encodeenv G).
 intros;elim H;simplify;autobatch;
 qed.
 
-lemma NWFT_env_incl : ∀G,T.NWFType G T → ∀H.incl ? (fv_Nenv G) (fv_Nenv H) 
+lemma NWFT_env_incl : ∀G,T.NWFType G T → ∀H.(fv_Nenv G) ⊆ (fv_Nenv H) 
                       → NWFType H T.
 intros 3;elim H
   [4:apply NWFT_Forall
@@ -1382,7 +1000,9 @@ intros 3;elim H
      |intros;apply (H4 ? ? H8);
         [intro;apply H7;apply (H6 ? H9)
         |unfold;intros;simplify;simplify in H9;inversion H9;intros;
-         destruct;autobatch]]
+         destruct;simplify;
+         [autobatch
+         |apply in_list_cons;apply H6;apply H10]]]
   |*:autobatch]
 qed.
 
@@ -1394,13 +1014,11 @@ intros;elim H
         [elim (not_in_list_nil ? ? H1)
         |inversion H6;intros;destruct;
            [simplify;autobatch
-           |elim a;simplify;autobatch]]
+           |elim a;simplify;elim b;simplify;try apply in_list_cons;
+            apply H1;apply H7]]
      |assumption]
   |elim H2;elim H4;split;autobatch
-  |split;assumption
-  |elim H2;split
-     [lapply (adeq_WFT ? ? H5);autobatch;
-     |lapply (adeq_WFT ? ? H6);autobatch]]
+  |split;assumption]
 qed.
 
 theorem adequacy : ∀G,T,U.NJSubtype G T U → 
@@ -1420,25 +1038,21 @@ intros;elim H;simplify
             apply (H6 ? H7)
               [elim (decidable_eq_nat X n)
                  [left;assumption
-                 |right;intro;lapply (in_remove ? ? ? H10 H11);elim H7;
-                  autobatch]
+                 |right;intro;autobatch depth=5]
               |elim (decidable_eq_nat X n1)
                  [left;assumption
-                 |right;intro;lapply (in_remove ? ? ? H10 H11);elim H7;
-                  autobatch]]
-           |2,3:apply not_in_list_nil
+                 |right;intro;autobatch depth=5]]
+           |2,3:autobatch
            |intro;elim (NJSubtype_to_NWFT ? ? ? Hletin);
             lapply (in_fvNTyp_in_fvNenv ? ? H10);simplify in Hletin1;
             elim (decidable_eq_nat X n1)
               [assumption
-              |lapply (in_remove ? ? ? H11 H8);elim H7;autobatch]]
+              |elim H7;autobatch depth=4]]
         |2,3:autobatch
         |intro;elim (NJSubtype_to_NWFT ? ? ? Hletin);lapply (in_fvNTyp_in_fvNenv ? ? H9);
          simplify in Hletin1;elim (decidable_eq_nat X n)
            [assumption
-           |lapply (in_remove ? ? ? H11 H8);elim H7;autobatch]]]
-  |rewrite < (alpha_to_encode ? ? H3);rewrite < (alpha_to_encode ? ? H4);
-   assumption]
+           |elim H7;autobatch depth=4]]]]
 qed.
 
 let rec closed_type T n ≝
@@ -1449,58 +1063,9 @@ let rec closed_type T n ≝
     | Arrow T1 T2 ⇒ closed_type T1 n ∧ closed_type T2 n
     | Forall T1 T2 ⇒  closed_type T1 n ∧ closed_type T2 (S n)].
     
-alias id "nth" = "cic:/matita/list/list/nth.con".
-alias id "length" = "cic:/matita/list/list/length.con".
-definition distinct_list ≝
-λl.∀n,m.n < length ? l → m < length ? l → n ≠ m → nth ? l O n ≠ nth ? l O m.
-
-lemma posn_nth: ∀l,n.distinct_list l → n < length ? l → 
-                    posn l (nth ? l O n) = n.
-intro;elim l
-  [simplify in H1;elim (not_le_Sn_O ? H1)
-  |simplify in H2;generalize in match H2;elim n
-     [simplify;rewrite > eqb_n_n;simplify;reflexivity
-     |simplify;cut (nth ? (a::l1) O (S n1) ≠ nth ? (a::l1) O O)
-        [simplify in Hcut;rewrite > (not_eq_to_eqb_false ? ? Hcut);simplify;
-         rewrite > (H n1)
-           [reflexivity
-           |unfold;intros;unfold in H1;lapply (H1 (S n2) (S m));
-              [simplify in Hletin;assumption
-              |2,3:simplify;autobatch
-              |intro;apply H7;destruct H8;reflexivity]
-           |autobatch]
-        |intro;apply H1;
-           [6:apply H5
-           |skip
-           |skip
-           |(*** *:autobatch; *)
-            apply H4
-           |simplify;autobatch
-           |intro;elim (not_eq_O_S n1);symmetry;assumption]]]]
-qed.
-
-lemma nth_in_list : ∀l,n. n < length ? l → in_list ? (nth ? l O n) l.
-intro;elim l
-  [simplify in H;elim (not_le_Sn_O ? H)
-  |generalize in match H1;elim n;simplify
-     [apply in_list_head
-     |apply in_list_cons;apply H;simplify in H3;apply (le_S_S_to_le ? ? H3)]]
-qed.
-
-lemma lookup_nth : \forall l,n.n < length ? l \to 
-                   lookup (nth nat l O n) l = true.
-intro;elim l
-  [elim (not_le_Sn_O ? H);
-  |generalize in match H1;elim n;simplify
-     [rewrite > eqb_n_n;reflexivity
-     |elim (eqb (nth nat l1 O n1) a);simplify;
-        [reflexivity
-        |apply H;apply le_S_S_to_le;assumption]]]
-qed.
-    
 lemma decoder : ∀T,n.closed_type T n → 
                      ∀l.length ? l = n → distinct_list l →
-                  (\forall x. in_list ? x (fv_type T) \to \lnot in_list ? x l) \to   
+                  (\forall x. x ∈ (fv_type T) \to x ∉ l) \to   
                      ∃U.T = encodetype U l.
 intro;elim T
   [simplify in H;apply (ex_intro ? ? (TName (nth ? l O n)));simplify;
@@ -1581,10 +1146,10 @@ intros 2;elim H 0
      |elim a in H6;simplify in H6;destruct H6;apply NWFE_cons;autobatch]]
 qed.
 
-lemma xxx : \forall b,X,T,l.
+lemma in_list_encodeenv : \forall b,X,T,l.
             in_list ? (mk_bound b X (encodetype T [])) (encodeenv l) \to
             \exists U.encodetype U [] = encodetype T [] \land
-                      in_list ? (mk_nbound b X U) l.
+                      (mk_nbound b X U) ∈ l.
 intros 4;elim l
   [simplify in H;elim (not_in_list_nil ? ? H)
   |simplify in H1;inversion H1;elim a 0;simplify;intros;destruct;
@@ -1593,9 +1158,9 @@ intros 4;elim l
 qed.
 
 lemma eq_swap_NTyp_to_case :
-  \forall X,Y,Z,T.\lnot in_list ? Y (X::var_NTyp T) \to
+  \forall X,Y,Z,T. Y ∉ (X::var_NTyp T) \to
     swap_NTyp Z Y (swap_NTyp Y X T) = swap_NTyp Z X T \to
-      Z = X \lor \lnot in_list ? Z (fv_NTyp T).
+      Z = X \lor Z ∉ (fv_NTyp T).
 intros 4;elim T
   [simplify in H;simplify in H1;elim (decidable_eq_nat X n)
      [rewrite > H2;simplify;elim (decidable_eq_nat Z n)
@@ -1661,10 +1226,9 @@ intros 4;elim H 0
      |rewrite > H3 in H2;rewrite < eq_fv_Nenv_fv_env in H2;assumption]
   |intros;cut (T2 = TName n) 
      [|elim T2 in H5 0;simplify;intros;destruct;reflexivity]
-   rewrite > Hcut;
-   elim (decoder t1 O ? []);
-     [rewrite > H4 in H1;rewrite > H7 in H1;elim (xxx ? ? ? ? H1);elim H8;
-      autobatch
+   rewrite > Hcut;elim (decoder t1 O ? []);
+     [rewrite > H4 in H1;rewrite > H7 in H1;elim (in_list_encodeenv ???? H1);
+      elim H8;autobatch
      |4:unfold;intros;simplify in H7;elim (not_le_Sn_O ? H7)
      |*:autobatch]
   |intros;cut (∃u,u1,u2,u3.T2 = NArrow u u1 ∧ U2 = NArrow u2 u3)
index cd7bbfdfef92913da1205ea914c251e31cf09723..337fe26868c6f5663c82aa943f779aa16060d6a2 100644 (file)
@@ -45,8 +45,11 @@ let rec subst_type_nat T U i ≝
 
 (*** definitions about lists ***)
 
+definition filter_types : list bound → list bound ≝
+  λG.(filter ? G (λB.match B with [mk_bound B X T ⇒ B])).
+
 definition fv_env : list bound → list nat ≝
-  λG.(map ? ? (λb.match b with [mk_bound B X T ⇒ X]) G).
+  λG.(map ? ? (λb.match b with [mk_bound B X T ⇒ X]) (filter_types G)).
 
 let rec fv_type T ≝
   match T with
@@ -92,13 +95,21 @@ inductive JSubtype : list bound → Typ → Typ → Prop ≝
                 (subst_type_nat S2 (TFree X) O) (subst_type_nat T2 (TFree X) O)) →
              JSubtype G (Forall S1 S2) (Forall T1 T2).
 
-notation "hvbox(e ⊢ break ta ⊴  break tb)" 
+notation "mstyle color #007f00 (hvbox(e ⊢ break ta ⊴ break tb))" 
   non associative with precedence 30 for @{ 'subjudg $e $ta $tb }.  
 interpretation "Fsub subtype judgement" 'subjudg e ta tb = (JSubtype e ta tb).
 
-notation > "hvbox(\Forall S.T)" 
+notation "mstyle color #007f00 (hvbox(e ⊢ ♦))" 
+  non associative with precedence 30 for @{ 'wfejudg $e }.  
+interpretation "Fsub WF env judgement" 'wfejudg e = (WFEnv e).
+
+notation "mstyle color #007f00 (hvbox(e ⊢ break t))" 
+  non associative with precedence 30 for @{ 'wftjudg $e $t }.  
+interpretation "Fsub WF type judgement" 'wftjudg e t = (WFType e t).
+
+notation > "\Forall S.T" 
   non associative with precedence 60 for @{ 'forall $S $T}.
-notation < "hvbox('All' \sub S. break T)" 
+notation < "hvbox( \sub S. break T)" 
   non associative with precedence 60 for @{ 'forall $S $T}.
 interpretation "universal type" 'forall S T = (Forall S T).
   
@@ -115,7 +126,7 @@ notation "hvbox(s break ⇛ t)"
   right associative with precedence 55 for @{ 'arrow $s $t }.
 interpretation "arrow type" 'arrow S T = (Arrow S T).
   
-notation "hvbox(S [# n ↦ T])"
+notation "hvbox(S [#n ↦ T])"
   non associative with precedence 80 for @{ 'substvar $S $T $n }.
 interpretation "subst bound var" 'substvar S T n = (subst_type_nat S T n).  
 
@@ -127,37 +138,32 @@ interpretation "subtyping bound" 'subtypebound X T = (mk_bound true X T).
 
 (*** theorems about lists ***)
 
-lemma boundinenv_natinfv : ∀x,G.(∃B,T.in_list ? (mk_bound B x T) G) →
-                              in_list ? x (fv_env G).
+lemma boundinenv_natinfv : ∀x,G.(∃T.!x ⊴ T ∈ G) → x ∈ (fv_env G).
 intros 2;elim G;decompose
-  [elim (not_in_list_nil ? ? H)
-  |elim (in_list_cons_case ? ? ? ? H1)
-     [rewrite < H2;simplify;apply in_list_head
-     |simplify;apply in_list_cons;apply H;autobatch]]
+  [elim (not_in_list_nil ? ? H1)
+  |elim (in_list_cons_case ? ? ? ? H2)
+     [rewrite < H1;simplify;apply in_list_head
+     |elim a;apply (bool_elim ? b);intro;simplify;try apply in_list_cons;
+      apply H;autobatch]]
 qed.
 
-lemma natinfv_boundinenv : ∀x,G.in_list ? x (fv_env G) →
-                              ∃B,T.in_list ? (mk_bound B x T) G.
+lemma natinfv_boundinenv : ∀x,G.x ∈ (fv_env G) → ∃T.!x ⊴ T ∈ G.
 intros 2;elim G 0
   [simplify;intro;lapply (not_in_list_nil ? ? H);elim Hletin
   |intros 3;
-   elim a;simplify in H1;elim (in_list_cons_case ? ? ? ? H1)
+   elim a;simplify in H1;elim b in H1;simplify in H1
+   [elim (in_list_cons_case ? ? ? ? H1)
      [rewrite < H2;autobatch
-     |elim (H H2);elim H3;apply ex_intro[apply a1];autobatch]]
+     |elim (H H2);autobatch]
+   |elim (H H1);autobatch]]
 qed.
 
-lemma incl_bound_fv : ∀l1,l2.incl ? l1 l2 → incl ? (fv_env l1) (fv_env l2).
+lemma incl_bound_fv : ∀l1,l2.l1 ⊆ l2 → (fv_env l1) ⊆ (fv_env l2).
 intros;unfold in H;unfold;intros;apply boundinenv_natinfv;
 lapply (natinfv_boundinenv ? ? H1);decompose;autobatch depth=4;
 qed.
 
-lemma incl_cons : ∀x,l1,l2.incl ? l1 l2 → incl nat (x :: l1) (x :: l2).
-intros.unfold in H.unfold.intros.elim (in_list_cons_case ? ? ? ? H1)
-  [applyS in_list_head|autobatch]
-qed.
-
-lemma WFT_env_incl : ∀G,T.WFType G T → 
-                       ∀H.incl ? (fv_env G) (fv_env H) → WFType H T.
+lemma WFT_env_incl : ∀G,T.(G ⊢ T) → ∀H.fv_env G ⊆ fv_env H → (H ⊢ T).
 intros 3.elim H
   [apply WFT_TFree;unfold in H3;apply (H3 ? H1)
   |apply WFT_Top
@@ -166,19 +172,21 @@ intros 3.elim H
      [apply (H2 ? H6)
      |intros;apply (H4 ? ? H8)
         [unfold;intro;autobatch
-        |simplify;apply (incl_cons ? ? ? H6)]]]
+        |simplify;apply (incl_cons ???? H6)]]]
 qed.
 
-lemma fv_env_extends : ∀H,x,B,C,T,U,G.
-                          fv_env (H @ ((mk_bound B x T) :: G)) = 
-                          fv_env (H @ ((mk_bound C x U) :: G)).
-intros;elim H
-  [reflexivity|elim a;simplify;rewrite > H1;reflexivity]
+lemma fv_env_extends : ∀H,x,T,U,G,B.
+                         fv_env (H @ mk_bound B x T :: G) = 
+                         fv_env (H @ mk_bound B x U :: G).
+intros 5;elim H;elim B
+  [1,2:reflexivity
+  |*:elim a;elim b;simplify;lapply (H1 true);lapply (H1 false);
+   try rewrite > Hletin;try rewrite > Hletin1;reflexivity]
 qed.
 
 lemma lookup_env_extends : ∀G,H,B,C,D,T,U,V,x,y.
-            in_list ? (mk_bound D y V) (H @ ((mk_bound C x U) :: G)) → y ≠ x → 
-            in_list ? (mk_bound D y V) (H @ ((mk_bound B x T) :: G)).
+            mk_bound D y V ∈ H @ mk_bound C x U :: G → y ≠ x → 
+            mk_bound D y V ∈ H @ mk_bound B x T :: G.
 intros 10;elim H
   [simplify in H1;elim (in_list_cons_case ? ? ? ? H1)
      [destruct H3;elim H2;reflexivity
@@ -188,8 +196,7 @@ intros 10;elim H
      |apply (in_list_cons ? ? ? ? (H1 H4 H3))]]
 qed.
 
-lemma in_FV_subst : ∀x,T,U,n.in_list ? x (fv_type T) →
-                                in_list ? x (fv_type (subst_type_nat T U n)).
+lemma in_FV_subst : ∀x,T,U,n.x ∈ fv_type T → x ∈ fv_type (subst_type_nat T U n).
 intros 3;elim T
   [simplify in H;elim (not_in_list_nil ? ? H)
   |2,3:simplify;simplify in H;assumption
@@ -199,7 +206,7 @@ qed.
 
 (*** lemma on fresh names ***)
 
-lemma fresh_name : ∀l:list nat.∃n.¬in_list ? n l.
+lemma fresh_name : ∀l:list nat.∃n.n ∉ l.
 cut (∀l:list nat.∃n.∀m.n ≤ m → ¬ in_list ? m l);intros
   [lapply (Hcut l);elim Hletin;apply ex_intro;autobatch
   |elim l
@@ -215,8 +222,7 @@ qed.
 
 (*** lemmata on well-formedness ***)
 
-lemma fv_WFT : ∀T,x,G.WFType G T → in_list ? x (fv_type T) →
-                    in_list ? x (fv_env G).
+lemma fv_WFT : ∀T,x,G.(G ⊢ T) → x ∈ fv_type T → x ∈ fv_env G.
 intros 4.elim H
   [simplify in H2;elim (in_list_cons_case ? ? ? ? H2)
      [applyS H1|elim (not_in_list_nil ? ? H3)]
@@ -238,11 +244,11 @@ qed.
 
 (*** lemmata relating subtyping and well-formedness ***)
 
-lemma JS_to_WFE : ∀G,T,U.G ⊢ T ⊴ U → WFEnv G.
+lemma JS_to_WFE : ∀G,T,U.G ⊢ T ⊴ U → G ⊢ ♦.
 intros;elim H;assumption.
 qed.
 
-lemma JS_to_WFT : ∀G,T,U.G ⊢ T ⊴ U → WFType G T ∧ WFType G U.
+lemma JS_to_WFT : ∀G,T,U.G ⊢ T ⊴ U → (G ⊢ T) ∧ (G ⊢ U).
 intros;elim H
   [1,2:autobatch
   |split 
@@ -256,18 +262,18 @@ intros;elim H
       apply (WFT_env_incl ? ? H10);simplify;unfold;intros;assumption]]
 qed.
 
-lemma JS_to_WFT1 : ∀G,T,U.G ⊢ T ⊴ U → WFType G T.
+lemma JS_to_WFT1 : ∀G,T,U.G ⊢ T ⊴ U → G ⊢ T.
 intros;elim (JS_to_WFT ? ? ? H);assumption;
 qed.
 
-lemma JS_to_WFT2 : ∀G,T,U.G ⊢ T ⊴ U → WFType G U.
+lemma JS_to_WFT2 : ∀G,T,U.G ⊢ T ⊴ U → G ⊢ U.
 intros;elim (JS_to_WFT ? ? ? H);assumption;
 qed.
 
-lemma WFE_Typ_subst : ∀H,x,B,C,T,U,G.
-                      WFEnv (H @ ((mk_bound B x T) :: G)) → WFType G U →
-                      WFEnv (H @ ((mk_bound C x U) :: G)).
-intros 7;elim H 0
+lemma WFE_Typ_subst : ∀H,x,B,T,U,G.
+                      H @ mk_bound B x T :: G ⊢ ♦ → (G ⊢ U) →
+                      H @ mk_bound B x U :: G ⊢ ♦.
+intros 6;elim H 0
   [simplify;intros;inversion H1;intros
      [elim (nil_cons ? G (mk_bound B x T) H3)
      |destruct H7;autobatch]
@@ -276,15 +282,14 @@ intros 7;elim H 0
      [destruct H5
      |destruct H9;apply WFE_cons
         [apply (H1 H5 H3)
-        |rewrite < (fv_env_extends ? x B C T U); assumption
+        |rewrite < (fv_env_extends ? x T U); assumption
         |apply (WFT_env_incl ? ? H8);
-         rewrite < (fv_env_extends ? x B C T U);unfold;intros;
+         rewrite < (fv_env_extends ? x T U);unfold;intros;
          assumption]]]
 qed.
 
-lemma WFE_bound_bound : ∀B,x,T,U,G.WFEnv G → in_list ? (mk_bound B x T) G →
-                        in_list ? (mk_bound B x U) G → T = U.
-intros 6;elim H
+lemma WFE_bound_bound : ∀x,T,U,G.G ⊢ ♦ → !x ⊴  T ∈ G → !x ⊴ U ∈ G → T = U.
+intros 5;elim H
   [lapply (not_in_list_nil ? ? H1);elim Hletin
   |elim (in_list_cons_case ? ? ? ? H6)
      [destruct H7;destruct;elim (in_list_cons_case ? ? ? ? H5)
@@ -295,9 +300,9 @@ intros 6;elim H
         |apply (H2 H8 H7)]]]
 qed.
 
-lemma WFT_to_incl: ∀G,T,U.(∀X.¬in_list ? X (fv_env G) → ¬in_list ? X (fv_type U) →
-    WFType (mk_bound true X T::G) (subst_type_nat U (TFree X) O))
-  → incl ? (fv_type U) (fv_env G).
+lemma WFT_to_incl: ∀G,T,U.(∀X.X ∉ fv_env G → X ∉ fv_type U →
+    (mk_bound true X T::G ⊢ (subst_type_nat U (TFree X) O))) →
+    fv_type U ⊆ fv_env G.
 intros;elim (fresh_name (fv_type U@fv_env G));lapply(H a)
   [unfold;intros;lapply (fv_WFT ? x ? Hletin)
      [simplify in Hletin1;inversion Hletin1;intros
@@ -308,11 +313,12 @@ intros;elim (fresh_name (fv_type U@fv_env G));lapply(H a)
 qed.
 
 lemma incl_fv_env: ∀X,G,G1,U,P.
-      incl ? (fv_env (G1@(mk_bound true X U::G))) 
-             (fv_env (G1@(mk_bound true X P::G))).
+      fv_env (G1@ !X ⊴ U::G) ⊆ fv_env (G1@ !X ⊴ P::G).
 intros.rewrite < fv_env_extends.apply incl_A_A.
 qed.
 
 lemma fv_append : ∀G,H.fv_env (G @ H) = fv_env G @ fv_env H.
-intro;elim G;simplify;autobatch paramodulation;
+intro;elim G;simplify;
+[reflexivity
+|elim a;simplify;elim b;simplify;lapply (H H1);rewrite > Hletin;reflexivity]
 qed.
\ No newline at end of file
index f38b5b332f682cffd2357e9bbef6a619b05133a4..9e097b279cab5a032eea7735d1b334a5c471ff28 100644 (file)
@@ -15,7 +15,7 @@
 include "Fsub/defn.ma".
 
 (*** Lemma A.1 (Reflexivity) ***)
-theorem JS_Refl : ∀T,G.WFType G T → WFEnv G → G ⊢ T ⊴  T.
+theorem JS_Refl : ∀T,G.(G ⊢ T) → G ⊢ ♦ → G ⊢ T ⊴  T.
 intros 3; elim H;
  [1,2,3: autobatch
  | apply SA_All; [ autobatch | intros;autobatch depth=4 size=10]]
@@ -27,7 +27,7 @@ qed.
  * set inclusion.
  *)
 
-lemma JS_weakening : ∀G,T,U.G ⊢ T ⊴ U → ∀H.WFEnv H → incl ? G H → H ⊢ T ⊴ U.
+lemma JS_weakening : ∀G,T,U.G ⊢ T ⊴ U → ∀H.H ⊢ ♦ → G ⊆ H → H ⊢ T ⊴ U.
 intros 4; elim H;
  [1,2,3,4: autobatch depth=4 size=7
  | apply (SA_All ? ? ? ? ? (H2 ? H6 H7));
@@ -38,14 +38,14 @@ inverter JS_indinv for JSubtype (%?%).
 
 theorem narrowing:∀X,G,G1,U,P,M,N.
   G1 ⊢ P ⊴ U → (∀G2,T.G2@G1 ⊢ U ⊴ T → G2@G1 ⊢ P ⊴ T) → G ⊢ M ⊴ N →
-  ∀l.G=l@(mk_bound true X U::G1) → l@(mk_bound true X P::G1) ⊢ M ⊴ N.
+  ∀l.G=l@ !X ⊴ U::G1 → l@ !X ⊴ P::G1 ⊢ M ⊴ N.
 intros 10.elim H2; destruct;
  [letin x \def fv_env. letin y ≝incl. autobatch depth=4 size=8.
  | autobatch depth=4 size=7;
  | elim (decidable_eq_nat X n)
     [apply (SA_Trans_TVar ? ? ? P); destruct;
       [ autobatch
-      | lapply (WFE_bound_bound true X t1 U ? ? H3); autobatch]
+      | lapply (WFE_bound_bound X t1 U ? ? H3); autobatch]
     | apply (SA_Trans_TVar ? ? ? t1); autobatch]
  | autobatch
  | apply SA_All;
@@ -53,8 +53,8 @@ intros 10.elim H2; destruct;
     | intros; apply (H6 ? ? (mk_bound true X1 t2::l1)); autobatch]]
 qed.
 
-lemma JS_trans_prova: ∀T,G1.WFType G1 T →
-∀G,R,U.incl ? (fv_env G1) (fv_env G) → G ⊢ R ⊴ T → G ⊢ T ⊴ U → G ⊢ R ⊴ U.
+lemma JS_trans_prova: ∀T,G1.(G1 ⊢ T) →
+      ∀G,R,U.fv_env G1 ⊆ fv_env G → G ⊢ R ⊴ T → G ⊢ T ⊴ U → G ⊢ R ⊴ U.
 intros 3;elim H;clear H;
   [elim H3 using JS_indinv;destruct;autobatch
   |inversion H3; intros; destruct; assumption
@@ -71,6 +71,7 @@ intros 3;elim H;clear H;
             [4: apply (narrowing X (mk_bound true X t::G) ? ? ? ? ? H11 ? ? [])
                [intros;apply H2;try unfold;intros;autobatch; 
                |*:autobatch]
+            |3:apply incl_cons;apply H5
             |*:autobatch]]]]]
 qed.
 
@@ -79,8 +80,8 @@ intros 5; apply (JS_trans_prova ? G); autobatch depth=2.
 qed.
 
 theorem JS_narrow : ∀G1,G2,X,P,Q,T,U.
-                       (G2 @ (mk_bound true X Q :: G1)) ⊢ T ⊴ U → G1 ⊢ P ⊴ Q →
-                       (G2 @ (mk_bound true X P :: G1)) ⊢ T ⊴ U.
+                       G2 @ !X ⊴ Q :: G1 ⊢ T ⊴ U → G1 ⊢ P ⊴ Q →
+                       G2 @ !X ⊴ P :: G1 ⊢ T ⊴ U.
 intros;apply (narrowing ? ? ? ? ? ? ? H1 ? H) [|autobatch]
 intros;apply (JS_trans ? ? ? ? ? H2);apply (JS_weakening ? ? ? H1);autobatch.
 qed.
index d3f4dc02322141932af2c684ef8b65b476bfea63..47b95a69e710f5a55570791a6b5af61049912efd 100644 (file)
@@ -43,16 +43,284 @@ apply (leb_elim m n)
   ]
 qed.  
 
-(*
-notation > "hvbox(x ∈ l)"
-  non associative with precedence 30 for @{ 'inlist $x $l }.
-notation < "hvbox(x \nbsp ∈ \nbsp l)"
-  non associative with precedence 30 for @{ 'inlist $x $l }.
-*)  
-interpretation "item in list" 'mem x l = (in_list ? x l).
-
 lemma max_case : \forall m,n.(max m n) = match (leb m n) with
       [ true \Rightarrow n
       | false \Rightarrow m ].
 intros;elim m;simplify;reflexivity;
 qed.
+
+definition swap : nat → nat → nat → nat ≝
+  λu,v,x.match (eqb x u) with
+    [true ⇒ v
+    |false ⇒ match (eqb x v) with
+       [true ⇒ u
+       |false ⇒ x]].
+       
+lemma swap_left : ∀x,y.(swap x y x) = y.
+intros;unfold swap;rewrite > eqb_n_n;simplify;reflexivity;
+qed.
+
+lemma swap_right : ∀x,y.(swap x y y) = x.
+intros;unfold swap;rewrite > eqb_n_n;apply (eqb_elim y x);intro;autobatch;
+qed.
+
+lemma swap_other : \forall x,y,z.(z \neq x) \to (z \neq y) \to (swap x y z) = z.
+intros;unfold swap;apply (eqb_elim z x);intro;simplify
+  [elim H;assumption
+  |rewrite > not_eq_to_eqb_false;autobatch]
+qed.
+
+lemma swap_inv : \forall u,v,x.(swap u v (swap u v x)) = x.
+intros;unfold in match (swap u v x);apply (eqb_elim x u);intro;simplify
+  [autobatch paramodulation
+  |apply (eqb_elim x v);intro;simplify
+     [autobatch paramodulation
+     |apply swap_other;assumption]]
+qed.
+
+lemma swap_inj : ∀u,v,x,y.swap u v x = swap u v y → x = y.
+intros 4;unfold swap;apply (eqb_elim x u);simplify;intro
+  [apply (eqb_elim y u);simplify;intro
+     [intro;autobatch paramodulation
+     |apply (eqb_elim y v);simplify;intros
+        [autobatch paramodulation
+        |elim H2;symmetry;assumption]]
+  |apply (eqb_elim y u);simplify;intro
+     [apply (eqb_elim x v);simplify;intros;
+        [autobatch paramodulation
+        |elim H2;assumption]
+     |apply (eqb_elim x v);simplify;intro
+        [apply (eqb_elim y v);simplify;intros
+           [autobatch paramodulation
+           |elim H1;symmetry;assumption]
+        |apply (eqb_elim y v);simplify;intros
+           [elim H;assumption
+           |assumption]]]]
+qed.
+
+definition swap_list : nat \to nat \to (list nat) \to (list nat) ≝
+  \lambda u,v,l.(map ? ? (swap u v) l). 
+
+let rec posn l x on l ≝
+  match l with
+  [ nil ⇒ O
+  | (cons (y:nat) l2) ⇒
+      match (eqb x y) with
+            [ true ⇒ O
+            | false ⇒ S (posn l2 x)]].
+            
+let rec lookup n l on l ≝
+  match l with
+    [ nil ⇒ false
+    | cons (x:nat) l1 ⇒ match (eqb n x) with
+              [true ⇒ true
+              |false ⇒ (lookup n l1)]]. 
+                             
+let rec head (A:Type) l on l ≝
+  match l with
+  [ nil ⇒ None A
+  | (cons (x:A) l2) ⇒ Some A x].
+
+definition max_list : (list nat) \to nat \def
+  \lambda l.let rec aux l0 m on l0 \def
+    match l0 with
+      [ nil ⇒ m
+      | (cons n l2) ⇒ (aux l2 (max m n))]
+    in aux l O.
+
+let rec remove_nat (x:nat) (l:list nat) on l \def
+  match l with
+  [ nil ⇒ (nil nat) 
+  | (cons y l2) ⇒ match (eqb x y) with
+                  [ true ⇒ (remove_nat x l2)
+                  | false ⇒ (y :: (remove_nat x l2)) ]].
+                  
+lemma in_lookup : \forall x,l.x ∈ l \to (lookup x l = true).
+intros;elim H;simplify
+  [rewrite > eqb_n_n;reflexivity
+  |rewrite > H2;elim (eqb a a1);reflexivity]
+qed.
+
+lemma lookup_in : \forall x,l.(lookup x l = true) \to x ∈ l.
+intros 2;elim l
+  [simplify in H;destruct H
+  |generalize in match H1;simplify;elim (decidable_eq_nat x a)
+     [applyS in_list_head
+     |apply in_list_cons;apply H;
+      rewrite > (not_eq_to_eqb_false ? ? H2) in H3;simplify in H3;assumption]]
+qed.
+
+lemma posn_length : \forall x,vars.x ∈ vars → 
+                       (posn vars x) < (length ? vars).
+intros 2;elim vars
+  [elim (not_in_list_nil ? ? H)
+  |inversion H1;intros;destruct;simplify
+     [rewrite > eqb_n_n;simplify;
+      apply lt_O_S
+     |elim (eqb x a);simplify
+        [apply lt_O_S
+        |apply le_S_S;apply H;assumption]]]
+qed.
+
+lemma in_remove : \forall a,b,l.(a ≠ b) \to a ∈ l \to
+                                a ∈ (remove_nat b l).
+intros 4;elim l
+  [elim (not_in_list_nil ? ? H1)
+  |inversion H2;intros;destruct;simplify
+     [rewrite > not_eq_to_eqb_false
+        [simplify;apply in_list_head
+        |intro;apply H;symmetry;assumption]
+     |elim (eqb b a1);simplify
+        [apply H1;assumption
+        |apply in_list_cons;apply H1;assumption]]]
+qed.
+
+lemma swap_same : \forall x,y.swap x x y = y.
+intros;elim (decidable_eq_nat y x)
+  [autobatch paramodulation
+  |rewrite > swap_other;autobatch]
+qed.
+
+lemma not_nat_in_to_lookup_false : ∀l,X. X ∉ l → lookup X l = false.
+intros 2;elim l;simplify
+  [reflexivity
+  |elim (decidable_eq_nat X a)
+     [elim H1;rewrite > H2;apply in_list_head
+     |rewrite > (not_eq_to_eqb_false ? ? H2);simplify;apply H;intro;apply H1;
+      apply (in_list_cons ? ? ? ? H3);]]
+qed.
+
+lemma lookup_swap : ∀a,b,x,vars.
+                    lookup (swap a b x) (swap_list a b vars) =
+                    lookup x vars.
+intros 4;elim vars;simplify
+  [reflexivity
+  |elim (decidable_eq_nat x a1)
+     [rewrite > H1;rewrite > eqb_n_n;rewrite > eqb_n_n;simplify;reflexivity
+     |rewrite > (not_eq_to_eqb_false ? ? H1);elim (decidable_eq_nat x a)
+        [rewrite > H;rewrite > H2;rewrite > swap_left;
+         elim (decidable_eq_nat b a1)
+           [rewrite < H3;rewrite > swap_right;
+            rewrite > (not_eq_to_eqb_false b a)
+              [reflexivity
+              |intro;autobatch]
+           |rewrite > (swap_other a b a1)
+              [rewrite > (not_eq_to_eqb_false ? ? H3);simplify;reflexivity
+              |*:intro;autobatch]]
+        |elim (decidable_eq_nat x b)
+           [rewrite > H;rewrite > H3;rewrite > swap_right;
+            elim (decidable_eq_nat a1 a)
+              [rewrite > H4;rewrite > swap_left;
+               rewrite > (not_eq_to_eqb_false a b)
+                 [reflexivity
+                 |intro;autobatch]
+              |rewrite > (swap_other a b a1)
+                 [rewrite > (not_eq_to_eqb_false a a1)
+                    [reflexivity
+                    |intro;autobatch]
+                 |assumption
+                 |intro;autobatch]]
+           |rewrite > H;rewrite > (swap_other a b x)
+              [elim (decidable_eq_nat a a1)
+                 [rewrite > H4;rewrite > swap_left;
+                  rewrite > (not_eq_to_eqb_false ? ? H3);reflexivity
+                 |elim (decidable_eq_nat b a1)
+                    [rewrite > H5;rewrite > swap_right;
+                     rewrite > (not_eq_to_eqb_false ? ? H2);reflexivity
+                    |rewrite > (swap_other a b a1)
+                       [rewrite > (not_eq_to_eqb_false ? ? H1);reflexivity
+                       |*:intro;autobatch]]]
+              |*:assumption]]]]]
+qed.
+
+lemma posn_swap : ∀a,b,x,vars.
+                  posn vars x = posn (swap_list a b vars) (swap a b x).
+intros 4;elim vars;simplify
+  [reflexivity
+  |rewrite < H;elim (decidable_eq_nat x a1)
+     [rewrite > H1;do 2 rewrite > eqb_n_n;reflexivity
+     |elim (decidable_eq_nat (swap a b x) (swap a b a1))
+        [elim H1;autobatch
+        |rewrite > (not_eq_to_eqb_false ? ? H1);
+         rewrite > (not_eq_to_eqb_false ? ? H2);reflexivity]]]
+qed.
+
+lemma remove_inlist : \forall x,y,l.x ∈ (remove_nat y l) → x ∈ l \land x ≠ y.
+intros 3;elim l 0;simplify;intro
+  [elim (not_in_list_nil ? ? H)
+  |elim (decidable_eq_nat y a)
+     [rewrite > H in H2;rewrite > eqb_n_n in H2;simplify in H2;
+      rewrite > H in H1;elim (H1 H2);rewrite > H;split
+        [apply in_list_cons;assumption
+        |assumption]
+     |rewrite > (not_eq_to_eqb_false ? ? H) in H2;simplify in H2;
+      inversion H2;intros;destruct;
+        [split;autobatch
+        |elim (H1 H3);split;autobatch]]]
+qed.
+
+lemma inlist_remove : ∀x,y,l.x ∈ l → x ≠ y → x ∈ (remove_nat y l).
+intros 3;elim l
+  [elim (not_in_list_nil ? ? H);
+  |simplify;elim (decidable_eq_nat y a)
+     [rewrite > (eq_to_eqb_true ? ? H3);simplify;apply H
+        [inversion H1;intros;destruct;
+           [elim H2;reflexivity
+           |assumption]
+        |assumption]
+     |rewrite > (not_eq_to_eqb_false ? ? H3);simplify;
+      inversion H1;intros;destruct;autobatch]]
+qed.
+
+lemma swap_case: ∀u,v,x.(swap u v x) = u ∨ (swap u v x) = v ∨ (swap u v x = x).
+intros;unfold in match swap;simplify;elim (eqb x u);simplify
+  [autobatch
+  |elim (eqb x v);simplify;autobatch]
+qed.
+    
+definition distinct_list ≝
+λl.∀n,m.n < length ? l → m < length ? l → n ≠ m → nth ? l O n ≠ nth ? l O m.
+
+lemma posn_nth: ∀l,n.distinct_list l → n < length ? l → 
+                    posn l (nth ? l O n) = n.
+intro;elim l
+  [simplify in H1;elim (not_le_Sn_O ? H1)
+  |simplify in H2;generalize in match H2;elim n
+     [simplify;rewrite > eqb_n_n;simplify;reflexivity
+     |simplify;cut (nth ? (a::l1) O (S n1) ≠ nth ? (a::l1) O O)
+        [simplify in Hcut;rewrite > (not_eq_to_eqb_false ? ? Hcut);simplify;
+         rewrite > (H n1)
+           [reflexivity
+           |unfold;intros;unfold in H1;lapply (H1 (S n2) (S m));
+              [simplify in Hletin;assumption
+              |2,3:simplify;autobatch
+              |intro;apply H7;destruct H8;reflexivity]
+           |autobatch]
+        |intro;apply H1;
+           [6:apply H5
+           |skip
+           |skip
+           |(*** *:autobatch; *)
+            apply H4
+           |simplify;autobatch
+           |intro;elim (not_eq_O_S n1);symmetry;assumption]]]]
+qed.
+
+lemma nth_in_list : ∀l,n. n < length ? l → (nth ? l O n) ∈ l.
+intro;elim l
+  [simplify in H;elim (not_le_Sn_O ? H)
+  |generalize in match H1;elim n;simplify
+     [apply in_list_head
+     |apply in_list_cons;apply H;simplify in H3;apply (le_S_S_to_le ? ? H3)]]
+qed.
+
+lemma lookup_nth : \forall l,n.n < length ? l \to 
+                   lookup (nth nat l O n) l = true.
+intro;elim l
+  [elim (not_le_Sn_O ? H);
+  |generalize in match H1;elim n;simplify
+     [rewrite > eqb_n_n;reflexivity
+     |elim (eqb (nth nat l1 O n1) a);simplify;
+        [reflexivity
+        |apply H;apply le_S_S_to_le;assumption]]]
+qed.
\ No newline at end of file