intros goal gamma work context j j1 a b c less1 below_x forces0 spec0.
unfold search_spec in |- *.
intros below_goal below_gamma below_context sound0 minimal0.
generalize (below_cons_list_head c gamma j below_gamma).
intros below_c.
generalize (below_x below_c); clear below_x; intros below_x.
elim below_x; clear below_x; intros below_a below_x.
elim below_x; clear below_x; intros below_b eq_c.
generalize (below_cons_list_tail c gamma j below_gamma); clear below_gamma;
intros below_gamma.
elim spec0; clear spec0; try assumption.
clear minimal0 forces0.
intros derivable_i.
apply derivable.
apply derivable_cut with (subst_form j a (Imp (Atom j) a)).
simpl in |- *.
rewrite (subst_form_below j a a); try assumption.
rewrite (equal_dec_refl j form a (Atom j)).
apply derivable_a_imp_a.
apply derivable_cut_merge with c.
apply derivable_weak.
apply sound0.
apply in_gamma_cons_gamma_head.
rewrite <- eq_c.
rewrite <- (subst_form_below j a goal); try assumption.
rewrite <- (subst_list_below j a context); try assumption.
change
(Derivable (subst_list j a (b :: Imp (Atom j) a :: context))
(subst_form j a goal)) in |- *.
apply derivable_subst; assumption.
clear minimal0 sound0 below_context below_gamma below_goal.
intros k k_is_mon k_forces_gamma k_notforces_goal.
apply refutable with k; try assumption.
apply forces_gamma_cons_gamma_weak2 with b (Imp (Atom j) a); try assumption.
intros forces1 forces2.
apply forces0; assumption.
apply below_form_less_below_form with j; assumption.
clear minimal0 sound0 forces0.
apply below_cons_list.
assumption.
apply below_cons_list.
split.
assumption.
apply below_form_less_below_form with j; assumption.
apply below_list_less_below_list with j; assumption.
apply below_cons_list.
assumption.
apply below_cons_list.
split.
assumption.
apply below_form_less_below_form with j; assumption.
apply below_list_less_below_list with j; assumption.
clear minimal0 below_context below_gamma below_goal forces0.
apply sound_cons_gamma_cons_context.
apply sound_cons_gamma_cons_context.
apply sound_cons_gamma_tail with c; assumption.
clear sound0 below_context below_gamma below_goal below_b below_a.
unfold minimal in |- *.
intros x k k_is_mon k_forces_gamma in_x.
inversion_clear in_x.
rewrite <- H; clear H x.
apply k_forces_gamma.
apply in_gamma_cons_gamma_head.
inversion_clear H.
rewrite <- H0; clear H0 x.
apply k_forces_gamma.
apply in_gamma_cons_gamma_tail.
apply in_gamma_cons_gamma_head.
apply minimal0; try assumption.
clear H0 x.
apply forces_gamma_cons_gamma_weak2 with b (Imp (Atom j) a); try assumption.
intros forces1 forces2.
apply forces0; assumption.
Qed.
(* Lemma search_spec_subst_gamma : (goal:form; gamma:flist; work:nf_list; context:flist; j,j1:Int; a,b,c,d:form) (Less j j1) ->((below_form c j) ->  (below_form a j) /\ (below_form b j1) /\ (below_form d j1) /\ (subst_form j a b)=c /\ (subst_form j a d)=(Imp a a)) ->((k:kripke_tree) (Is_Monotone_kripke_tree k) ->(forces_t k b)->(forces_t k d)->(forces_t k c)) ->(search_spec goal (cons b (cons d gamma)) work (cons b (cons d context)) j1) ->(search_spec goal (cons c gamma) work context j). Intros goal gamma work context j j1 a b c d less1 below_x forces0 spec0. Unfold search_spec. Intros below_goal below_gamma below_context sound0 minimal0. Generalize (below_cons_list_head c gamma j below_gamma). Intros below_c. Generalize (below_x below_c); Clear below_x; Intros below_x. Elim below_x; Clear below_x; Intros below_a below_x. Elim below_x; Clear below_x; Intros below_b below_x. Elim below_x; Clear below_x; Intros below_d below_x. Elim below_x; Clear below_x; Intros eq_c eq_d. Generalize (below_cons_list_tail c gamma j below_gamma); Clear below_gamma; Intros below_gamma. Elim spec0; Clear spec0; Try Assumption. Clear minimal0 forces0. Intros derivable_i. Apply derivable. Apply derivable_cut with (subst_form j a d). Rewrite eq_d. Apply derivable_a_imp_a. Apply derivable_cut_merge with c. Apply derivable_weak. Apply sound0. Apply in_gamma_cons_gamma_head. Rewrite <- eq_c. Rewrite <- (subst_form_below j a goal); Try Assumption. Rewrite <- (subst_list_below j a context); Try Assumption. Change (Derivable (subst_list j a (cons b (cons d context))) (subst_form j a  goal)). Apply derivable_subst; Assumption. Clear minimal0 sound0 below_context below_gamma below_goal. Intros k k_is_mon k_forces_gamma k_notforces_goal. Apply refutable with k; Try Assumption. Apply forces_gamma_cons_gamma_weak2 with b d; Try Assumption. Intros forces1 forces2. Apply forces0; Assumption. Apply below_form_less_below_form with j; Assumption. Clear minimal0 sound0 forces0. Apply below_cons_list. Assumption. Apply below_cons_list. Assumption. Apply below_list_less_below_list with j; Assumption. Apply below_cons_list. Assumption. Apply below_cons_list. Assumption. Apply below_list_less_below_list with j; Assumption. Clear minimal0 below_context below_gamma below_goal forces0. Apply sound_cons_gamma_cons_context. Apply sound_cons_gamma_cons_context. Apply sound_cons_gamma_tail with c; Assumption. Clear sound0 below_context below_gamma below_goal below_b below_a. Unfold minimal. Intros x k k_is_mon k_forces_gamma in_x. Inversion_clear in_x. Rewrite <- H; Clear H x. Apply k_forces_gamma. Apply in_gamma_cons_gamma_head. Inversion_clear H. Rewrite <- H0; Clear H0 x. Apply k_forces_gamma. Apply in_gamma_cons_gamma_tail. Apply in_gamma_cons_gamma_head. Apply minimal0; Try Assumption. Clear H0 x. Apply forces_gamma_cons_gamma_weak2 with b d; Try Assumption. Intros forces1 forces1. Apply forces0; Assumption. Save. *)

(* Specifications: *)
Lemma rule_vimp_a_gamma :
forall (goal : form) (l : list Int) (a : form) (gamma : flist)
(work : nf_list) (context : flist) (j j1 : Int),
Less j j1 ->
search_spec goal (vimp (j :: nil) a :: gamma) (nvimp l (NAtom j) :: work)
(vimp l (Atom j) :: Imp (Atom j) a :: context) j1 ->
search_spec goal (vimp l a :: gamma) work context j.