(* File: Derivable.v  (last edited on 1/1/2000) (c) Klaus Weich  *)
Require Export Derivable_Def.
intros context context' a a' eq_context eq_a.
rewrite eq_context.
rewrite eq_a.
intros; assumption.
Qed.
intros i g context a der.
elim der; clear der.
intros t der.
elim der; clear der a t context.
intros context n a nth.
apply Derivable_Intro with (Var n).
apply ByAssumption.
apply subst_nth; assumption.
intros context t a der ih.
elim ih; clear ih.
intros t1 der1.
apply Derivable_Intro with (Efq t1 (subst_form i g a)).
apply ByAbsurdity; assumption.
intros context a t b der ih.
elim ih; clear ih.
intros t1 der1.
apply Derivable_Intro with (Abs (subst_form i g a) t1).
simpl in |- *.
apply ImpIntro; assumption.
intros context r s a b der_r ih_r der_s ih_s.
elim ih_r; clear ih_r.
intros r1 der_r1.
elim ih_s; clear ih_s.
intros s1 der_s1.
apply Derivable_Intro with (App (subst_form i g a) r1 s1).
apply ImpElim; assumption.
intros context r s a b der_r ih_r der_s ih_s.
elim ih_r; clear ih_r.
intros r1 der_r1.
elim ih_s; clear ih_s.
intros s1 der_s1.
apply Derivable_Intro with (Pair r1 s1).
simpl in |- *; apply AndFIntro; assumption.
intros context r a b der_r ih.
elim ih; clear ih; intros r1 der_r1.
apply Derivable_Intro with (PrL (subst_form i g b) r1).
apply AndFElimL; assumption.
intros context r a b der_r ih.
elim ih; clear ih; intros r1 der_r1.
apply Derivable_Intro with (PrR (subst_form i g a) r1).
apply AndFElimR; assumption.
intros context r a b der_r ih.
elim ih; clear ih; intros r1 der_r1.
apply Derivable_Intro with (OrFL r1 (subst_form i g b)).
simpl in |- *; apply OrFIntroL; assumption.
intros context r a b der_r ih.
elim ih; clear ih; intros r1 der_r1.
apply Derivable_Intro with (OrFR r1 (subst_form i g a)).
simpl in |- *; apply OrFIntroR; assumption.
intros context r s t a b c der_r ih_r der_s ih_s der_t ih_t.
elim ih_r; clear ih_r; intros r1 der_r1.
elim ih_s; clear ih_s; intros s1 der_s1.
elim ih_t; clear ih_t; intros t1 der_t1.
apply
Derivable_Intro with (Cas (subst_form i g a) (subst_form i g b) r1 s1 t1).
apply OrFElim; assumption.
intros context r a b der_r ih_r.
elim ih_r; clear ih_r; intros r1 der_r1.
apply Derivable_Intro with (Shift r1).
simpl in |- *; apply ShiftIntro; assumption.
Qed.
intros context i der below b.
cut (subst_form i b (Atom i) = b).
intro eq_b.
rewrite <- eq_b.
rewrite <- (subst_list_below i b context).
apply derivable_subst; assumption.
assumption.
simpl in |- *.
apply equal_dec_refl.
Qed.
intros context a b der_a.
elim der_a; clear der_a.
intros t der_t.
apply Derivable_Intro with (Shift t).
apply ShiftIntro; assumption.
Qed.
intros context1 context2 a der1.
elim context2; clear context2.
assumption.
intros b context2 ih.
simpl in |- *; apply derivable_weak; assumption.
Qed.
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.
intros context a b der_a der_b.
elim der_b; clear der_b.
intros t der_b.
apply (derivable_cut_aux (a :: context) t b der_b a fnil context).
trivial.
assumption.
Qed.

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