diff --git a/Coq/f.v b/Coq/f.v
index 415c537a5fb431ce3f896ce3979af453180d2b8c..2d31325c8bdd05e0d4c40772d104c6bcbd809b8d 100644
--- a/Coq/f.v
+++ b/Coq/f.v
@@ -33,46 +33,29 @@ Fixpoint type_subst (n : nat) (T : type) (U : type) : type :=
   | TForall T => TForall (type_subst (S n) T (type_lift 0 U))
  end.
 
-(* Curch-style terms of System F.
+(* Derivations in System F.
    de Bruijn indices again. *)
-Inductive fterm : Type :=
- | FVar : nat -> fterm
- | FAbs : type -> fterm -> fterm
- | FApp : fterm -> fterm -> fterm
- | FTAbs : fterm -> fterm
- | FTApp : fterm -> type -> fterm.
+Inductive fvar : list type -> type -> Type :=
+ | FVar0 : forall {context : list type} (T : type), fvar (T::context) T
+ | FVarS : forall {context : list type} {T : type} {U : type}, fvar context T -> fvar (U::context) T.
+Inductive fterm : list type -> type -> Type :=
+ | FVar : forall {context : list type} {T : type}, fvar context T -> fterm context T
+ | FAbs : forall {context : list type} {T : type} {U : type}, fterm (T::context) U -> fterm context (TArrow T U)
+ | FApp : forall {context : list type} {T : type} {U : type}, fterm context (TArrow T U) -> fterm context T -> fterm context U
+ | FTAbs : forall {context : list type} {T : type}, fterm (map (type_lift 0) context) T -> fterm context (TForall T)
+ | FTApp : forall {context : list type} {T : type}, fterm context (TForall T) -> forall (U : type), fterm context (type_subst 0 T U).
+Definition fterm_get_context {context : list type} {T : type} (t : fterm context T) := context.
+Definition fterm_get_type {context : list type} {T : type} (t : fterm context T) := T.
+(* ∀X.(X→X) *)
+Definition type1 : type := TForall (TArrow (TVar 0) (TVar 0)).
 (* ΛX.λx:X.x *)
-Definition term1 : fterm :=  FTAbs (FAbs (TVar 0) (FVar 0)).
+Definition term1 : fterm [] type1 :=
+  FTAbs (FAbs (FVar (FVar0 (TVar 0)))).
+(* ∀X.(X→X)→∀X.(X→X) *)
+Definition type2 : type := (TArrow type1 type1).
 (* λx:∀X(X→X).x(∀X(X→X))x *)
-Definition term2 : fterm :=  FAbs (TForall (TArrow (TVar 0) (TVar 0))) (FApp (FTApp (FVar 0) (TForall (TArrow (TVar 0) (TVar 0)))) (FVar 0)).
-(* "type_get context t" is the type
-   of t in context context. *)
-Fixpoint type_get (context : list type) (t : fterm) : type :=
- match t with
-  | FVar n => nth n context (TVar 0)
-  | FAbs T t => TArrow T (type_get (T::context) t)
-  | FApp t u =>
-   match type_get context t with
-    | TArrow T U => U
-    | _ => TVar 0
-   end
-  | FTAbs t => TForall (type_get (map (type_lift 0) context) t)
-  | FTApp t T =>
-   match type_get context t with
-    | TForall U => type_subst 0 U T
-    | _ => TVar 0
-   end
- end.
-(* "type_correct context t" holds if
-   t is typable in context context. *)
-Fixpoint type_correct (context : list type) (t : fterm) : Prop :=
- match t with
-  | FVar n => n < length context
-  | FAbs T t => type_correct (T::context) t
-  | FApp t u => type_correct context t /\ type_correct context u /\ exists T, type_get context t = TArrow (type_get context u) T
-  | FTAbs t => type_correct (map (type_lift 0) context) t
-  | FTApp t T => type_correct context t /\ exists T, type_get context t = TForall T
- end.
+Definition term2 : fterm [] type2 :=
+  FAbs (FApp (FTApp (FVar (FVar0 type1)) type1) (FVar (FVar0 type1))).
 
 (* Untyped lambda-terms.
    Still de Bruijn indices. *)
@@ -82,13 +65,18 @@ Inductive term : Type :=
  | App : term -> term -> term.
 (* Erasure from Church-style System F
    terms to untyped (Curry-style) terms *)
-Fixpoint fterm_to_term (t : fterm) : term :=
+Fixpoint fvar_to_nat {context : list type} {T : type} (t : fvar context T) : nat :=
  match t with
-  | FVar n => Var n
-  | FAbs T t => Abs (fterm_to_term t)
+  | FVar0 _ => 0
+  | FVarS t => S (fvar_to_nat t)
+ end.
+Fixpoint fterm_to_term {context : list type} {T : type} (t : fterm context T) : term :=
+ match t with
+  | FVar t => Var (fvar_to_nat t)
+  | FAbs t => Abs (fterm_to_term t)
   | FApp t u => App (fterm_to_term t) (fterm_to_term u)
   | FTAbs t => fterm_to_term t
-  | FTApp t T => fterm_to_term t
+  | FTApp t _ => fterm_to_term t
  end.
 (* "term_equal t u" is true if t and u
    are syntactically equal. *)
@@ -311,6 +299,23 @@ Fixpoint form_lift2 (n : nat) (f : form) : form :=
   | FForallp f => FForallp (form_lift2 n f)
   | FForall2 f => FForall2 (form_lift2 (S n) f)
  end.
+Lemma form_lift2_substt : forall m n f t, form_lift2 m (form_substt n f t) = form_substt n (form_lift2 m f) t.
+intros m n f; revert m n; induction f; intros m p t; simpl.
+destruct (n <? m); reflexivity.
+reflexivity.
+rewrite IHf1.
+rewrite IHf2.
+reflexivity.
+rewrite IHf1.
+rewrite IHf2.
+reflexivity.
+rewrite IHf.
+reflexivity.
+rewrite IHf.
+reflexivity.
+rewrite IHf.
+reflexivity.
+Qed.
 (* "form_subst2 n f g" is f[g/n].
    2nd-order variables of f with
    index >= n are decremented. *)
@@ -358,6 +363,33 @@ Fixpoint rc (T : type) : form :=
   | TArrow T U => FForallt (FImp (rc T) (form_substt 0 (rc U) (LApp (LMetavar 1) (LLList [LMetavar 0]))))
   | TForall T => FForall2 (FImp redcand (rc T))
  end.
+Lemma form_lift2_rc : forall n U, form_lift2 n (rc U) = rc (type_lift n U).
+intros n U; revert n; induction U; intro m; simpl.
+destruct (n <? m); reflexivity.
+f_equal.
+f_equal.
+apply IHU1.
+rewrite form_lift2_substt.
+rewrite IHU2.
+reflexivity.
+rewrite IHU.
+reflexivity.
+Qed.
+Lemma form_subst2_lift2 : forall m T n U, form_subst2 m (rc T) (form_lift2 n (rc U)) = form_subst2 m (rc T) (rc (type_lift n U)).
+intros m T; revert m; induction T; intros m p U; simpl.
+destruct (n ?= m).
+rewrite form_lift2_rc.
+reflexivity.
+reflexivity.
+reflexivity.
+rewrite IHT1.
+rewrite form_lift2_rc.
+reflexivity.
+rewrite IHT.
+rewrite form_lift2_rc.
+rewrite form_lift2_rc.
+reflexivity.
+Qed.
 
 (* "form_to_type f" is the type of
    realizers of f. *)
@@ -511,6 +543,21 @@ reflexivity.
 rewrite IHf.
 reflexivity.
 Qed.
+Lemma form_to_type_subst2_type_subst : forall T U n, form_to_type (form_subst2 n (rc T) (rc U)) = form_to_type (rc (type_subst n T U)).
+intro t; induction t; intros U m; simpl.
+destruct (n ?= m); simpl.
+apply form_to_type_substt.
+reflexivity.
+reflexivity.
+rewrite IHt1.
+rewrite form_to_type_substt.
+rewrite form_to_type_subst2_substt.
+rewrite IHt2.
+reflexivity.
+rewrite <- IHt.
+rewrite form_subst2_lift2.
+reflexivity.
+Qed.
 (*Lemma form_to_type_subst2_fin2 : forall (f : form) (n : nat) (t : logterm), form_to_type (form_subst2 n (FIn t n) f) = form_to_type f.
 intros f n t; simpl.
 rewrite Nat.compare_refl.
@@ -840,70 +887,43 @@ Qed.
    H is a proof that t is well-typed
    in context context) is the realizer of
    RC_{(type_get context t)[U_1...U_n/0]}(t[u_1...u_n/0]) *)
-Program Fixpoint adeq (context : list (term * {T : type & form_to_type (rc T)})) (tcontext : list (form_to_type redcand)) (t : fterm) (H : type_correct (map (fun a => projT1 (snd a)) context) t) : form_to_type (rc (type_get (map (fun a => projT1 (snd a)) context) t)) :=
+Program Fixpoint adeq_var (tcontext : list (form_to_type redcand)) (context : list (term * {T : type & form_to_type (rc T)})) (T : type) (t : fvar (map (@projT1 type (fun T => form_to_type (rc T))) (map snd context)) T) : form_to_type (rc T) :=
+   match t with
+    | FVar0 T => match context with [] => match _ : False with end | (t, existT _ T x)::context => x end
+    | FVarS t => match context with [] => match _ : False with end | _::context => rew [id] _ in adeq_var tcontext context T t end
+   end.
+Program Fixpoint adeq (tcontext : list (form_to_type redcand)) (context : list (term * {T : type & form_to_type (rc T)})) (T : type) (t : fterm (map (@projT1 type (fun T => form_to_type (rc T))) (map snd context)) T) : form_to_type (rc T) :=
  match t with
-  | FVar n => rew [id] _ in projT2 (snd (nth n context (Var 0, existT _ (TVar 0) 0)))
-  | FAbs T t =>
+  | @FVar _ _ t => adeq_var tcontext context _ t
+  | @FAbs _ T U t =>
    fun u y =>
     let context := (u, existT _ T y)::context in
-    rew [id] _ in snd (isrc tcontext (type_get (map (fun a => projT1 (snd a)) context) t)) (term_subst 1 (fterm_to_term t) (map (fun a => term_lift 0 (fst a)) context)) u [] (rew [id] _ in adeq context tcontext t _)
-  | FApp t u => (rew [id] _ in adeq context tcontext t _) (term_subst 0 (fterm_to_term u) (map (fun a => fst a) context)) (adeq context tcontext u _)
-  | FTAbs t => fun x => rew [id] _ in adeq (map (fun a => (fst a, existT _ (type_lift 0 (projT1 (snd a))) (rew [id] _ in projT2 (snd a)))) context) (x::tcontext) t _
-  | FTApp t T =>
-   let U := match type_get (map (fun a => projT1 (snd a)) context) t with TForall U => U | _ => TVar 0 end in
-   rew [id] _ in elim (FImp redcand (form_substt 0 (rc U) (term_to_logterm (term_subst 0 (fterm_to_term t) (map (fun a => fst a) context))))) (rc T) (rew [id] _ in adeq context tcontext t _) (isrc tcontext T)
+    rew [id] _ in snd (isrc tcontext U) (term_subst 1 (fterm_to_term t) (map (fun a => term_lift 0 (fst a)) context)) u [] (rew [id] _ in adeq tcontext context U t)
+  | @FApp _ T U t u => rew [id] _ in adeq tcontext context (TArrow T U) t (term_subst 0 (fterm_to_term u) (map (fun a => fst a) context)) (adeq tcontext context T u)
+  | @FTAbs _ T t => fun x => rew [id] _ in adeq (x::tcontext) (map (fun a => (fst a, existT _ (type_lift 0 (projT1 (snd a))) (rew [id] _ in projT2 (snd a)))) context) T t
+  | @FTApp _ T t U => rew [id] _ in elim (FImp redcand (form_substt 0 (rc T) (term_to_logterm (term_subst 0 (fterm_to_term t) (map (fun a => fst a) context))))) (rc U) (rew [id] _ in adeq tcontext context (TForall T) t) (isrc tcontext U)
  end.
 Next Obligation.
-revert n H.
-induction context; intros n H.
-rewrite nth_overflow; [ | apply le_0_n ].
-rewrite nth_overflow; [ | apply le_0_n ].
-reflexivity.
-rewrite map_cons.
-destruct n.
-reflexivity.
-simpl nth.
-apply IHcontext.
-simpl type_correct in *.
-apply lt_S_n.
-apply H.
-Qed.
-Next Obligation.
+fold form_to_type.
 rewrite form_to_type_substt.
 reflexivity.
 Qed.
 Next Obligation.
+fold form_to_type.
+fold rc.
 rewrite form_to_type_substt.
 rewrite form_to_type_substt.
 reflexivity.
 Qed.
 Next Obligation.
-simpl type_correct in H.
-destruct H.
-apply H.
-Qed.
-Next Obligation.
-simpl type_correct in H.
-destruct H.
-destruct H0.
-destruct H1.
-destruct (type_get _ t); try discriminate.
-simpl.
+fold form_to_type.
+fold rc.
 rewrite form_to_type_substt.
-injection H1 as H11 H12.
-rewrite <- H11.
 reflexivity.
 Qed.
 Next Obligation.
-simpl type_correct in H.
-destruct H.
-destruct H0.
-apply H0.
-Qed.
-Next Obligation.
-simpl; clear.
-generalize 0.
-induction s; simpl; intro m.
+simpl.
+generalize 0; clear; induction s; intro m; simpl.
 destruct (n <? m); reflexivity.
 rewrite form_to_type_substt.
 rewrite form_to_type_substt.
@@ -914,88 +934,22 @@ rewrite <- IHs.
 reflexivity.
 Qed.
 Next Obligation.
-simpl type_correct in H.
 rewrite map_map.
-simpl.
-rewrite map_map in H.
-apply H.
-Qed.
-Next Obligation.
 rewrite map_map.
 rewrite map_map.
+rewrite map_map.
+apply map_ext.
 reflexivity.
 Qed.
 Next Obligation.
-simpl type_correct in H.
-destruct H.
-apply H.
-Qed.
-Next Obligation.
-simpl type_correct in H.
-destruct H.
-destruct H0.
-rewrite H0.
-simpl.
 rewrite form_to_type_substt.
 reflexivity.
 Qed.
 Next Obligation.
-simpl type_correct in H.
-destruct H.
-destruct H0.
-rewrite H0.
-rewrite form_to_type_subst2_substt.
-clear; revert T.
-generalize 0.
-clear; induction x; intros m T.
-simpl.
-destruct (n ?= m); simpl.
-rewrite form_to_type_substt.
-reflexivity.
-reflexivity.
-reflexivity.
-simpl.
-rewrite IHx1.
-rewrite form_to_type_substt.
+fold form_to_type.
+fold form_subst2.
 rewrite form_to_type_subst2_substt.
-rewrite IHx2.
-reflexivity.
-simpl.
-rewrite (form_to_type_subst2 _ _ _ (rc T)).
-rewrite IHx.
-assert (forall a b c, b = c -> (a -> b) = (a -> c)).
-intros a b c Heq; rewrite Heq; reflexivity.
-apply H; clear H.
-generalize (S m); clear.
-revert T; induction x; intros T m.
-simpl.
-destruct (n ?= m).
-generalize 0; clear; induction T; intro m.
-simpl.
-destruct (n <? m); reflexivity.
-simpl.
-rewrite form_to_type_substt.
-rewrite form_to_type_substt.
-rewrite <- IHT1.
-rewrite <- IHT2.
-reflexivity.
-simpl.
-rewrite <- IHT.
-reflexivity.
-reflexivity.
-reflexivity.
-simpl.
-rewrite form_to_type_substt.
-rewrite form_to_type_substt.
-rewrite <- IHx1.
-rewrite <- IHx2.
-reflexivity.
-simpl.
-rewrite <- IHx.
-rewrite <- IHx.
-rewrite <- IHx.
-reflexivity.
-rewrite form_to_type_lift2.
+rewrite form_to_type_subst2_type_subst.
 reflexivity.
 Qed.
 
@@ -1004,11 +958,12 @@ Qed.
    context) computes a bound a bound
    on the number of reduction steps
    of t *)
-Program Definition bound (t : fterm) (H : type_correct [] t) : nat :=
- snd (fst (isrc [] (type_get [] t))) (fterm_to_term t) (adeq [] [] t H) id.
+Program Definition bound (T : type) (t : fterm [] T) : nat :=
+ snd (fst (isrc [] T)) (fterm_to_term t) (rew [id] _ in adeq [] [] T t) id.
 Next Obligation.
-Admitted.
-
+rewrite form_to_type_substt.
+reflexivity.
+Qed.
 
 Extract Inductive unit => "unit" [ "()" ].
 Extract Inductive bool => "bool" [ "true" "false" ].