intros context t b der_t.
elim der_t; clear der_t context t b.
intros context n a nth b l1 l2 eq_context.
rewrite eq_context in nth.
elim (inv_nth_app form n l1 (b :: l2) a nth); clear nth.
intros nth0 der_b.
apply Derivable_Intro with (Var n).
apply ByAssumption.
apply nth_app0; assumption.
clear n; intros n; case n; clear n.
intros nth_eq.
rewrite (inv_nthO form b l2 a nth_eq).
intros der_a.
rewrite (app_nil_end (l1 ++ l2)).
apply derivable_weak_list.
assumption.
intros n nth1 der_b.
apply Derivable_Intro with (Var (length l1 + n)).
apply ByAssumption.
apply nth_app1.
inversion_clear nth1; assumption.
intros context t a der_t ih b l1 l2 eq_context der_b.
elim (ih b l1 l2); try assumption.
intros t0 der_t0.
apply Derivable_Intro with (Efq t0 a).
apply ByAbsurdity; assumption.
intros context a t b der_t ih c l1 l2 eq_context der_c.
elim (ih c (a :: l1) l2); clear ih.
intros t0 der_t0.
apply Derivable_Intro with (Abs a t0).
apply ImpIntro; assumption.
rewrite eq_context.
trivial.
assumption.
intros context r s a b der_r ih_r der_s ih_s c l1 l2 eq_context der_c.
elim (ih_r c l1 l2); clear ih_r; try assumption.
intros r0 der_r0.
elim (ih_s c l1 l2); clear ih_s; try assumption.
intros s0 der_s0.
apply Derivable_Intro with (App a r0 s0).
apply ImpElim; assumption.
intros context r s a b der_r ih_r der_s ih_s c l1 l2 eq_context der_c.
elim (ih_r c l1 l2); clear ih_r; try assumption.
intros r0 der_r0.
elim (ih_s c l1 l2); clear ih_s; try assumption.
intros s0 der_s0.
apply Derivable_Intro with (Pair r0 s0).
apply AndFIntro; assumption.
intros context r a b der_r ih_r c l1 l2 eq_context der_c.
elim (ih_r c l1 l2); clear ih_r; try assumption.
intros r0 der_r0.
apply Derivable_Intro with (PrL b r0).
apply AndFElimL; assumption.
intros context r a b der_r ih_r c l1 l2 eq_context der_c.
elim (ih_r c l1 l2); clear ih_r; try assumption.
intros r0 der_r0.
apply Derivable_Intro with (PrR a r0).
apply AndFElimR; assumption.
intros context r a b der_r ih_r c l1 l2 eq_context der_c.
elim (ih_r c l1 l2); clear ih_r; try assumption.
intros r0 der_r0.
apply Derivable_Intro with (OrFL r0 b).
apply OrFIntroL; assumption.
intros context r a b der_r ih_r c l1 l2 eq_context der_c.
elim (ih_r c l1 l2); clear ih_r; try assumption.
intros r0 der_r0.
apply Derivable_Intro with (OrFR r0 a).
apply OrFIntroR; assumption.
intros context r s t a b c der_r ih_r der_s ih_s der_t ih_t d l1 l2
eq_context der_d; clear der_r der_s der_t.
elim (ih_r d l1 l2); try assumption; clear ih_r.
intros r0 der_r0.
elim (ih_s d (a :: l1) l2); clear ih_s.
intros s0 der_s0.
elim (ih_t d (b :: l1) l2); clear ih_t.
intros t0 der_t0.
apply Derivable_Intro with (Cas a b r0 s0 t0).
apply OrFElim; assumption.
rewrite eq_context; trivial.
assumption.
rewrite eq_context; trivial.
assumption.
intros context r a b der_r ih_r c l1.
case l1; clear l1.
simpl in |- *; intros l2 eq_context der_c.
apply Derivable_Intro with r.
injection eq_context; intros H1 H2.
rewrite <- H1; assumption.
simpl in |- *; intros d l1 l2 eq_context der_c.
elim (ih_r c l1 l2); clear ih_r; try assumption.
intros r0 der_r0.
apply derivable_weak.
apply Derivable_Intro with r0; assumption.
injection eq_context.
intros; assumption.
Qed.

Lemma derivable_cut :
forall (context : flist) (a b : form),
Derivable fnil a -> Derivable (a :: context) b -> Derivable context b.