(* File: Rules.v  (last edited on 27/10/2000) (c) Klaus Weich  *)


Require Export Minimal.
Require Export Sound.
Require Export NSearch.


Inductive search_spec_aux (goal : form) (gamma : flist) 
(work : nf_list) (context : flist) : Set :=
  | derivable :
      Derivable context goal -> search_spec_aux goal gamma work context
  | refutable :
      forall k : kripke_tree,
      Is_Monotone_kripke_tree k ->
      forces_gamma gamma work k ->
      (forces_t k goal -> False) -> search_spec_aux goal gamma work context.

Definition search_spec (goal : form) (gamma : flist) 
  (work : nf_list) (context : flist) (i : Int) :=
  below_form goal i ->
  below_list gamma i ->
  below_list context i ->
  sound gamma work context ->
  minimal gamma work context -> search_spec_aux goal gamma work context.



(**********************************************************************)


Lemma rule_shift_gamma_work :
 forall (goal : form) (l : list Int) (a : normal_form) 
   (gamma : flist) (work : nf_list) (context : flist) 
   (j : Int),
 search_spec goal gamma (nvimp l a :: work) context j ->
 search_spec goal (vimp l (nf2form a) :: gamma) work context j.
(* Goal: forall (goal : form) (l : list Int) (a : form) (gamma : flist) (work : nf_list) (context : flist) (j : Int) (_ : search_spec goal (@cons form (vimp l a) gamma) work context j), search_spec goal (@cons form (vimp l (OrF a Falsum)) gamma) work context j *)
intros goal l a gamma work context j spec0.
(* Goal: search_spec goal (@cons form (vimp l (nf2form a)) gamma) work context j *)
 rewrite (vimp_eq_nvimp l a).
(* Goal: search_spec goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context j *)
unfold search_spec in |- *.
(* Goal: forall (_ : below_form goal j) (_ : below_list (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) j) (_ : below_list context j) (_ : sound (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context) (_ : minimal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
intros below_goal below_gamma below_context sound0 minimal0.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
elim spec0; clear spec0; try assumption.
(* Goal: forall _ : Derivable context goal, search_spec_aux goal (@cons form (vimp l (Imp (Imp Falsum b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l c) gamma) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp Falsum b) c)) gamma) work context *)
(* Goal: below_list (@cons form (vimp l c) gamma) j *)
(* Goal: sound (@cons form (vimp l c) gamma) work context *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros der_goal; apply derivable; assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros k k_is_mon k_forces_gamma k_notforces_goal.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply refutable with k; try assumption.
(* Goal: forces_gamma (@cons form (nf2form (nvimp l a)) gamma) work k *)
(* Goal: below_list gamma j *)
(* Goal: sound gamma (@cons normal_form (nvimp l a) work) context *)
(* Goal: minimal gamma (@cons normal_form (nvimp l a) work) context *)
apply forces_gamma_shift_work_gamma; assumption.
(* Goal: below_list gamma j *)
(* Goal: sound gamma (@cons normal_form (nvimp l a) work) context *)
(* Goal: minimal gamma (@cons normal_form (nvimp l a) work) context *)
apply below_cons_list_tail with (nf2form (nvimp l a)); assumption.
(* Goal: sound gamma (@cons normal_form (nvimp l a) work) context *)
(* Goal: minimal gamma (@cons normal_form (nvimp l a) work) context *)
apply sound_shift_gamma_work; assumption.
(* Goal: minimal gamma (@cons normal_form (nvimp l a) work) context *)
apply minimal_shift_gamma_work; assumption.
Qed.



(*********************************************************************)



Lemma search_spec_subst_gamma_pos :
 forall (goal : form) (gamma : flist) (work : nf_list) 
   (context : flist) (j j1 : Int) (a b c : form),
 Less j j1 ->
 (below_form c j -> below_form a j /\ below_form b j1 /\ subst_form j a b = c) ->
 (forall k : kripke_tree,
  Is_Monotone_kripke_tree k ->
  forces_t k b -> forces_t k (Imp (Atom j) a) -> forces_t k c) ->
 search_spec goal (b :: Imp (Atom j) a :: gamma) work
   (b :: Imp (Atom j) a :: context) j1 ->
 search_spec goal (c :: gamma) work context j.
(* Goal: forall (goal : form) (gamma : flist) (work : nf_list) (context : flist) (j j1 : Int) (a b c : form) (_ : Less j j1) (_ : forall _ : below_form c j, and (below_form a j) (and (below_form b j1) (@eq form (subst_form j a b) c))) (_ : forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k b) (_ : forces_t k (Imp (Atom j) a)), forces_t k c) (_ : search_spec goal (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) j1), search_spec goal (@cons form c gamma) work context j *)
intros goal gamma work context j j1 a b c less1 below_x forces0 spec0.
(* Goal: search_spec goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context j *)
unfold search_spec in |- *.
(* Goal: forall (_ : below_form goal j) (_ : below_list (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) j) (_ : below_list context j) (_ : sound (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context) (_ : minimal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
intros below_goal below_gamma below_context sound0 minimal0.
(* Goal: search_spec_aux goal (@cons form c gamma) work context *)
generalize (below_cons_list_head c gamma j below_gamma).
(* Goal: forall _ : below_form (vimp l (OrF a b)) j, and (below_form a j) (and (below_form (vimp l (OrF (Atom j) b)) j1) (@eq form (subst_form j a (vimp l (OrF (Atom j) b))) (vimp l (OrF a b)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (OrF (Atom j) b))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (OrF a b)) *)
intros below_c.
(* Goal: search_spec_aux goal (@cons form c gamma) work context *)
generalize (below_x below_c); clear below_x; intros below_x.
(* Goal: search_spec_aux goal (@cons form c gamma) work context *)
elim below_x; clear below_x; intros below_a below_x.
(* Goal: search_spec_aux goal (@cons form c gamma) work context *)
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.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
elim spec0; clear spec0; try assumption.
(* Goal: forall _ : Derivable (@cons form b (@cons form (Imp (Atom j) a) context)) goal, search_spec_aux goal (@cons form c gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form b (@cons form (Imp (Atom j) a) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form c gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form b (@cons form (Imp (Atom j) a) gamma)) j1 *)
(* Goal: below_list (@cons form b (@cons form (Imp (Atom j) a) context)) j1 *)
(* Goal: sound (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) *)
(* Goal: minimal (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) *)
clear minimal0 forces0.
(* Goal: forall _ : Derivable (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) goal, search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros derivable_i.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply derivable.
(* Goal: Derivable context goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form b (@cons form (Imp (Atom j) a) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form c gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form b (@cons form (Imp (Atom j) a) gamma)) j1 *)
(* Goal: below_list (@cons form b (@cons form (Imp (Atom j) a) context)) j1 *)
(* Goal: sound (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) *)
(* Goal: minimal (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) *)
apply derivable_cut with (subst_form j a (Imp (Atom j) a)).
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: @eq flist (@cons form (Imp (subst_form j a a) (if equal_dec j j then a else Atom j)) (subst_list j a context)) (@cons form (Imp a a) context) *)
(* Goal: @eq form (subst_form j a (Atom j)) a *)
(* Goal: Derivable (subst_list j a (@cons form (Imp a (Atom j)) context)) (subst_form j a (Atom j)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (Imp a (Atom j)) gamma) work k) (_ : forall _ : forces_t k (Atom j), False), search_spec_aux a gamma work context *)
(* Goal: below_list (@cons form (Imp a (Atom j)) gamma) j1 *)
(* Goal: below_list (@cons form (Imp a (Atom j)) context) j1 *)
(* Goal: sound (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) *)
(* Goal: minimal (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) *)
 rewrite (subst_form_below j a a); try assumption.
(* Goal: @eq form (vimp l (Imp (Imp (if equal_dec j j then a else Atom j) b) c)) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (equal_dec_refl j form a (Atom j)).
(* Goal: Derivable fnil (Imp a a) *)
(* Goal: Derivable (@cons form (Imp a a) context) a *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (Imp a (Atom j)) gamma) work k) (_ : forall _ : forces_t k (Atom j), False), search_spec_aux a gamma work context *)
(* Goal: below_list (@cons form (Imp a (Atom j)) gamma) j1 *)
(* Goal: below_list (@cons form (Imp a (Atom j)) context) j1 *)
(* Goal: sound (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) *)
(* Goal: minimal (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) *)
apply derivable_a_imp_a.
(* Goal: Derivable (@cons form (subst_form j a (Imp (Atom j) a)) context) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form b (@cons form (Imp (Atom j) a) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form c gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form b (@cons form (Imp (Atom j) a) gamma)) j1 *)
(* Goal: below_list (@cons form b (@cons form (Imp (Atom j) a) context)) j1 *)
(* Goal: sound (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) *)
(* Goal: minimal (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) *)
apply derivable_cut_merge with c.
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context) (subst_form j b (vimp l (Imp (Imp (Atom a) (Atom j)) c))) *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Imp (Atom a) (Atom j)) c))) (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context)) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply derivable_weak.
(* Goal: Derivable context (vimp l (Imp (Imp (Atom a) b) c)) *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Imp (Atom a) (Atom j)) c))) (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context)) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply sound0.
(* Goal: in_gamma (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma) work (vimp (@cons Int a l) (Imp b (Atom j))) *)
(* Goal: forces_t k x *)
apply in_gamma_cons_gamma_head.
(* Goal: Derivable (@cons form c (@cons form (subst_form j a (Imp (Atom j) a)) context)) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form b (@cons form (Imp (Atom j) a) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form c gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form b (@cons form (Imp (Atom j) a) gamma)) j1 *)
(* Goal: below_list (@cons form b (@cons form (Imp (Atom j) a) context)) j1 *)
(* Goal: sound (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) *)
(* Goal: minimal (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) *)
 rewrite <- eq_c.
(* Goal: Derivable (@cons form (subst_form j a b) (@cons form (subst_form j a (Imp (Atom j) a)) context)) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form b (@cons form (Imp (Atom j) a) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form c gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form b (@cons form (Imp (Atom j) a) gamma)) j1 *)
(* Goal: below_list (@cons form b (@cons form (Imp (Atom j) a) context)) j1 *)
(* Goal: sound (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) *)
(* Goal: minimal (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) *)
 rewrite <- (subst_form_below j a goal); try assumption.
(* Goal: Derivable (@cons form (subst_form j a b) (@cons form (subst_form j a (Imp (Atom j) a)) context)) (subst_form j a goal) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form b (@cons form (Imp (Atom j) a) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form c gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form b (@cons form (Imp (Atom j) a) gamma)) j1 *)
(* Goal: below_list (@cons form b (@cons form (Imp (Atom j) a) context)) j1 *)
(* Goal: sound (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) *)
(* Goal: minimal (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) *)
 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 |- *.
(* Goal: Derivable (subst_list j b (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp l (Imp (Atom a) (Imp b (Atom j)))) context))) (subst_form j b goal) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply derivable_subst; assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
clear minimal0 sound0 below_context below_gamma below_goal.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros k k_is_mon k_forces_gamma k_notforces_goal.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply refutable with k; try assumption.
(* Goal: forces_gamma (@cons form c gamma) work k *)
apply forces_gamma_cons_gamma_weak2 with b (Imp (Atom j) a); try assumption.
(* Goal: forall (_ : forces_t k (vimp l (Imp (Imp (Atom a) (Atom j)) c))) (_ : forces_t k (vimp (@cons Int a l) (Imp b (Atom j)))), forces_t k (vimp l (Imp (Imp (Atom a) b) c)) *)
intros forces1 forces2.
(* Goal: forces_t k c *)
apply forces0; assumption.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_list (@cons form b (@cons form (Imp (Atom j) a) gamma)) j1 *)
(* Goal: below_list (@cons form b (@cons form (Imp (Atom j) a) context)) j1 *)
(* Goal: sound (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) *)
(* Goal: minimal (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) *)
clear minimal0 sound0 forces0.
(* Goal: below_list (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply below_cons_list.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_list (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply below_cons_list.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_list_less_below_list with j; assumption.
(* Goal: below_list (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply below_cons_list.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_list (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply below_cons_list.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_list_less_below_list with j; assumption.
(* Goal: sound (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) *)
(* Goal: minimal (@cons form b (@cons form (Imp (Atom j) a) gamma)) work (@cons form b (@cons form (Imp (Atom j) a) context)) *)
clear minimal0 below_context below_gamma below_goal forces0.
(* Goal: sound (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma) work (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply sound_cons_gamma_cons_context.
(* Goal: sound (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma) work (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply sound_cons_gamma_cons_context.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply sound_cons_gamma_tail with c; assumption.
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
clear sound0 below_context below_gamma below_goal below_b below_a.
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
unfold minimal in |- *.
(* Goal: forall (a0 : form) (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : @In form a0 (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context))), forces_t k a0 *)
intros x k k_is_mon k_forces_gamma in_x.
(* Goal: forces_t k x *)
inversion_clear in_x.
(* Goal: forces_t k x *)
(* Goal: forces_t k x *)
 rewrite <- H; clear H x.
(* Goal: forces_t k (vimp (@cons Int a l) (Imp b (Atom j))) *)
(* Goal: forces_t k x *)
apply k_forces_gamma.
(* Goal: in_gamma (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma) work (vimp (@cons Int a l) (Imp b (Atom j))) *)
(* Goal: forces_t k x *)
apply in_gamma_cons_gamma_head.
(* Goal: forces_t k x *)
inversion_clear H.
(* Goal: forces_t k x *)
(* Goal: forces_t k x *)
 rewrite <- H0; clear H0 x.
(* Goal: forces_t k (vimp (@cons Int a l) (Imp b (Atom j))) *)
(* Goal: forces_t k x *)
apply k_forces_gamma.
(* Goal: in_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (vimp (@cons Int a l) (Imp b (Atom j))) *)
(* Goal: forces_t k x *)
apply in_gamma_cons_gamma_tail.
(* Goal: in_gamma (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma) work (vimp (@cons Int a l) (Imp b (Atom j))) *)
(* Goal: forces_t k x *)
apply in_gamma_cons_gamma_head.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply minimal0; try assumption.
(* Goal: forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work k *)
clear H0 x.
(* Goal: forces_gamma (@cons form c gamma) work k *)
apply forces_gamma_cons_gamma_weak2 with b (Imp (Atom j) a); try assumption.
(* Goal: forall (_ : forces_t k (vimp l (Imp (Imp (Atom a) (Atom j)) c))) (_ : forces_t k (vimp (@cons Int a l) (Imp b (Atom j)))), forces_t k (vimp l (Imp (Imp (Atom a) b) c)) *)
intros forces1 forces2.
(* Goal: forces_t k c *)
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.
*)


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.
(* Goal: forall (goal : form) (l : list Int) (a : form) (gamma : flist) (work : nf_list) (context : flist) (j j1 : Int) (_ : Less j j1) (_ : search_spec goal (@cons form (vimp (@cons Int j (@nil Int)) a) gamma) (@cons normal_form (nvimp l (NAtom j)) work) (@cons form (vimp l (Atom j)) (@cons form (Imp (Atom j) a) context)) j1), search_spec goal (@cons form (vimp l a) gamma) work context j *)
intros goal l a gamma work context j j1 less1 spec0.
apply
 search_spec_subst_gamma_pos with (j1 := j1) (a := a) (b := vimp l (Atom j));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: forall _ : below_form (vimp l (OrF a b)) j, and (below_form a j) (and (below_form (vimp l (OrF (Atom j) b)) j1) (@eq form (subst_form j a (vimp l (OrF (Atom j) b))) (vimp l (OrF a b)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (OrF (Atom j) b))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (OrF a b)) *)
intros below_c.
(* Goal: and (below_form a j) (and (below_form (vimp l (Atom j)) j1) (@eq form (subst_form j a (vimp l (Atom j))) (vimp l a))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Atom j))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l a) *)
(* Goal: search_spec goal (@cons form (vimp l (Atom j)) (@cons form (Imp (Atom j) a) gamma)) work (@cons form (vimp l (Atom j)) (@cons form (Imp (Atom j) a) context)) j1 *)
generalize (below_vimp_tail j l a below_c).
(* Goal: forall _ : forall (i : Int) (_ : @In Int i l), Less i j, and (below_form a j) (and (below_form (vimp l (Atom j)) j1) (@eq form (subst_form j a (vimp l (Atom j))) (vimp l a))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Atom j))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l a) *)
(* Goal: search_spec goal (@cons form (vimp l (Atom j)) (@cons form (Imp (Atom j) a) gamma)) work (@cons form (vimp l (Atom j)) (@cons form (Imp (Atom j) a) context)) j1 *)
generalize (below_vimp_head j l a below_c); clear below_c.
(* Goal: forall (_ : below_form a j) (_ : forall (i : Int) (_ : @In Int i l), Less i j), and (below_form a j) (and (below_form (vimp l (Atom j)) j1) (@eq form (subst_form j a (vimp l (Atom j))) (vimp l a))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Atom j))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l a) *)
(* Goal: search_spec goal (@cons form (vimp l (Atom j)) (@cons form (Imp (Atom j) a) gamma)) work (@cons form (vimp l (Atom j)) (@cons form (Imp (Atom j) a) context)) j1 *)
intros below_a below_l.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp_split; try assumption.
(* Goal: forall (i : Int) (_ : @In Int i l), Less i j1 *)
(* Goal: below_form (Imp a (Atom j)) j1 *)
(* Goal: @eq form (subst_form j b (vimp l (Imp a (Atom j)))) (vimp l (Imp a b)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp a (Atom j)))) (_ : forces_t k (Imp (Atom j) b)), forces_t k (vimp l (Imp a b)) *)
intros i in0. 
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply less_trans with j; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_l; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_vimp_head j a l (Atom j)); try assumption.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: @eq form (vimp l (Imp (Imp (if equal_dec j j then a else Atom j) b) c)) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (equal_dec_refl j form a (Atom j)).
(* Goal: @eq form (vimp l (Imp (Imp a b) c)) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
trivial.

(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros k k_is_mon forces1 forces2.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_vimp with (Atom j); try assumption.
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k) (_ : forces_t2 k k' (Imp a (Atom j))), forces_t2 k k' (Imp a b) *)
intros k' suc1 forces_j.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply (forces2 k'); assumption.

(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply rule_shift_gamma_work with (a := NAtom j); assumption.
Qed.


Lemma rule_vimp_imp_gamma :
 forall (goal : form) (l : list Int) (a b : form) (gamma : flist)
   (work : nf_list) (context : flist) (j j1 : Int),
 Less j j1 ->
 search_spec goal (vimp l (Imp a (Atom j)) :: vimp (j :: nil) b :: gamma)
   work (vimp l (Imp a (Atom j)) :: Imp (Atom j) b :: context) j1 ->
 search_spec goal (vimp l (Imp a b) :: gamma) work context j.
(* Goal: forall (goal : form) (l : list Int) (a b : form) (gamma : flist) (work : nf_list) (context : flist) (j j1 : Int) (_ : Less j j1) (_ : search_spec goal (@cons form (vimp l (OrF (Atom j) b)) (@cons form (vimp (@cons Int j (@nil Int)) a) gamma)) work (@cons form (vimp l (OrF (Atom j) b)) (@cons form (Imp (Atom j) a) context)) j1), search_spec goal (@cons form (vimp l (OrF a b)) gamma) work context j *)
intros goal l a b gamma work context j j1 less1 spec0.
apply
 search_spec_subst_gamma_pos
  with (j1 := j1) (a := b) (b := vimp l (Imp a (Atom j))); 
 try assumption; clear spec0.
(* Goal: forall _ : below_form (vimp l (OrF a b)) j, and (below_form a j) (and (below_form (vimp l (OrF (Atom j) b)) j1) (@eq form (subst_form j a (vimp l (OrF (Atom j) b))) (vimp l (OrF a b)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (OrF (Atom j) b))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (OrF a b)) *)
intros below_c.
(* Goal: and (below_form b j) (and (below_form (vimp l (Imp a (Atom j))) j1) (@eq form (subst_form j b (vimp l (Imp a (Atom j)))) (vimp l (Imp a b)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp a (Atom j)))) (_ : forces_t k (Imp (Atom j) b)), forces_t k (vimp l (Imp a b)) *)
generalize (below_vimp_tail j l (Imp a b) below_c).
(* Goal: forall _ : forall (i : Int) (_ : @In Int i l), Less i j, and (below_form b j) (and (below_form (vimp l (Imp a (Atom j))) j1) (@eq form (subst_form j b (vimp l (Imp a (Atom j)))) (vimp l (Imp a b)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp a (Atom j)))) (_ : forces_t k (Imp (Atom j) b)), forces_t k (vimp l (Imp a b)) *)
generalize (below_vimp_head j l (Imp a b) below_c); clear below_c.
intros below_ab below_l; elim below_ab; clear below_ab;
 intros below_a below_b.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp_split; try assumption.
(* Goal: forall (i : Int) (_ : @In Int i l), Less i j1 *)
(* Goal: below_form (Imp a (Atom j)) j1 *)
(* Goal: @eq form (subst_form j b (vimp l (Imp a (Atom j)))) (vimp l (Imp a b)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp a (Atom j)))) (_ : forces_t k (Imp (Atom j) b)), forces_t k (vimp l (Imp a b)) *)
intros i in0. 
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply less_trans with j; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_l; assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_vimp_head j b l (Imp a (Atom j))); try assumption.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: Derivable context (vimp l (Imp (Imp (if equal_dec j a then b else Atom a) (if equal_dec j j then b else Atom j)) c)) *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Imp (Atom a) (Atom j)) c))) (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context)) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
 rewrite (equal_dec_refl j form b (Atom j)).
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_form_below j b a); try assumption.
(* Goal: @eq form (vimp l (Imp (Imp a b) c)) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
trivial.

(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros k k_is_mon forces1 forces2.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_vimp with (Imp a (Atom j)); try assumption.
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k) (_ : forces_t2 k k' (Imp a (Atom j))), forces_t2 k k' (Imp a b) *)
intros k' suc1 forces_j.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
unfold forces_t2 in |- *; simpl in |- *.
(* Goal: forall (k'0 : kripke_tree) (_ : Suc k'0 k) (_ : Suc k'0 k') (_ : forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k'0 a), forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k'0 b *)
intros k'' suc2 suc3 forces_a.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply (forces2 k''); try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply (forces_j k''); assumption.
Qed.


(****************************************************)
(*                                                  *)
(* rules for   goal = ...                           *)
(*                                                  *)
(****************************************************)


Lemma rule_gamma_falsum :
 forall (gamma : flist) (work : nf_list) (context : flist) (i j : Int),
 Less i j ->
 search_spec (Atom i) gamma work context j ->
 search_spec Falsum gamma work context i.
(* Goal: forall (gamma : flist) (work : nf_list) (context : flist) (i j : Int) (_ : Less i j) (_ : search_spec (Atom i) gamma work context j), search_spec Falsum gamma work context i *)
intros gamma work context i j less_ij spec0.
(* Goal: search_spec goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context j *)
unfold search_spec in |- *.
(* Goal: forall (_ : below_form goal j) (_ : below_list (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) j) (_ : below_list context j) (_ : sound (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context) (_ : minimal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
intros below_goal below_gamma below_context sound0 minimal0.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
elim spec0; clear spec0; try assumption.
(* Goal: forall _ : Derivable (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) goal, search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros derivable_i.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply derivable.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply snd_order_inst with i; assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma gamma work k) (_ : forall _ : forces_t k (Atom i), False), search_spec_aux Falsum gamma work context *)
(* Goal: below_list gamma j *)
(* Goal: below_list context j *)
intros k k_is_mon k_forces_gamma k_notforces_i.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply refutable with k; try assumption.
(* Goal: @eq form (vimp l (Imp (Imp a b) c)) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
trivial.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_list_less_below_list with i; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_list_less_below_list with i; assumption.
Qed.


Lemma rule_gamma_a_imp_b :
 forall (a b : form) (gamma : flist) (work : nf_list) 
   (context : flist) (j : Int),
 search_spec b (a :: gamma) work (a :: context) j ->
 search_spec (Imp a b) gamma work context j.
(* Goal: forall (a b : form) (gamma : flist) (work : nf_list) (context : flist) (j : Int) (_ : search_spec b (@cons form a gamma) work (@cons form a context) j), search_spec (Imp a b) gamma work context j *)
intros a b gamma work context j spec0.
(* Goal: search_spec goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context j *)
unfold search_spec in |- *.
(* Goal: forall (_ : below_form goal j) (_ : below_list (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) j) (_ : below_list context j) (_ : sound (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context) (_ : minimal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
intros below_goal below_gamma below_context sound0 minimal0.
(* Goal: search_spec_aux (Imp a b) gamma work context *)
elim below_goal; clear below_goal; intros below_a below_b.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
elim spec0; clear spec0; try assumption.
(* Goal: forall _ : Derivable (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) goal, search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros derivable_i.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply derivable.
(* Goal: Derivable context (Imp a b) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form a gamma) work k) (_ : forall _ : forces_t k b, False), search_spec_aux (Imp a b) gamma work context *)
(* Goal: below_list (@cons form a gamma) j *)
(* Goal: below_list (@cons form a context) j *)
(* Goal: sound (@cons form a gamma) work (@cons form a context) *)
(* Goal: minimal (@cons form a gamma) work (@cons form a context) *)
elim derivable_i; clear derivable_i; intros t der_t.
(* Goal: Derivable context (Imp a b) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form a gamma) work k) (_ : forall _ : forces_t k b, False), search_spec_aux (Imp a b) gamma work context *)
(* Goal: below_list (@cons form a gamma) j *)
(* Goal: below_list (@cons form a context) j *)
(* Goal: sound (@cons form a gamma) work (@cons form a context) *)
(* Goal: minimal (@cons form a gamma) work (@cons form a context) *)
apply Derivable_Intro with (Abs a t).
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply ImpIntro; assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form a gamma) work k) (_ : forall _ : forces_t k b, False), search_spec_aux (Imp a b) gamma work context *)
(* Goal: below_list (@cons form a gamma) j *)
(* Goal: below_list (@cons form a context) j *)
(* Goal: sound (@cons form a gamma) work (@cons form a context) *)
(* Goal: minimal (@cons form a gamma) work (@cons form a context) *)
intros k k_is_mon k_forces_gamma k_notforces_b.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply refutable with k; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_gamma_cons_gamma_tail with a; assumption.
(* Goal: forall _ : forces_t2 k k'' (Imp a b), forces_t2 k k'' c *)
intros forces_ab.
(* Goal: False *)
(* Goal: below_list (@cons form a gamma) j *)
(* Goal: below_list (@cons form a context) j *)
(* Goal: sound (@cons form a gamma) work (@cons form a context) *)
(* Goal: minimal (@cons form a gamma) work (@cons form a context) *)
apply k_notforces_b.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_a_a_imp_b__forces_b_t with a; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_gamma_cons_gamma_head with gamma work; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_cons_list; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_cons_list; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply sound_cons_gamma_cons_context; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply minimal_cons_gamma_cons_context; assumption.
Qed.


Lemma rule_gamma_a :
 forall (a : form) (gamma : flist) (work : nf_list) 
   (context : flist) (j j1 : Int),
 Less j j1 ->
 search_spec (Atom j) (Imp a (Atom j) :: gamma) work
   (Imp a (Atom j) :: context) j1 -> search_spec a gamma work context j.
(* Goal: forall (a : form) (gamma : flist) (work : nf_list) (context : flist) (j j1 : Int) (_ : Less j j1) (_ : search_spec (Atom j) (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) j1), search_spec a gamma work context j *)
intros a gamma work context j j1 less1 spec0.
(* Goal: search_spec goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context j *)
unfold search_spec in |- *.
(* Goal: forall (_ : below_form goal j) (_ : below_list (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) j) (_ : below_list context j) (_ : sound (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context) (_ : minimal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
intros below_goal below_gamma below_context sound0 minimal0.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
elim spec0; clear spec0; try assumption.
(* Goal: forall _ : Derivable context (vimp l (Imp (Imp Falsum b) c)), Derivable context (vimp l c) *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros der.
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
clear minimal0 sound0.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply derivable.
(* Goal: Derivable context a *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (Imp a (Atom j)) gamma) work k) (_ : forall _ : forces_t k (Atom j), False), search_spec_aux a gamma work context *)
(* Goal: below_list (@cons form (Imp a (Atom j)) gamma) j1 *)
(* Goal: below_list (@cons form (Imp a (Atom j)) context) j1 *)
(* Goal: sound (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) *)
(* Goal: minimal (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) *)
apply derivable_cut with (Imp a a).
(* Goal: Derivable fnil (Imp a a) *)
(* Goal: Derivable (@cons form (Imp a a) context) a *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (Imp a (Atom j)) gamma) work k) (_ : forall _ : forces_t k (Atom j), False), search_spec_aux a gamma work context *)
(* Goal: below_list (@cons form (Imp a (Atom j)) gamma) j1 *)
(* Goal: below_list (@cons form (Imp a (Atom j)) context) j1 *)
(* Goal: sound (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) *)
(* Goal: minimal (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) *)
apply derivable_a_imp_a.
apply
 derivable_eq
  with (subst_list j a (Imp a (Atom j) :: context)) (subst_form j a (Atom j)).
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: @eq flist (@cons form (Imp (subst_form j a a) (if equal_dec j j then a else Atom j)) (subst_list j a context)) (@cons form (Imp a a) context) *)
(* Goal: @eq form (subst_form j a (Atom j)) a *)
(* Goal: Derivable (subst_list j a (@cons form (Imp a (Atom j)) context)) (subst_form j a (Atom j)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (Imp a (Atom j)) gamma) work k) (_ : forall _ : forces_t k (Atom j), False), search_spec_aux a gamma work context *)
(* Goal: below_list (@cons form (Imp a (Atom j)) gamma) j1 *)
(* Goal: below_list (@cons form (Imp a (Atom j)) context) j1 *)
(* Goal: sound (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) *)
(* Goal: minimal (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) *)
 rewrite (subst_form_below j a a); try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_list_below j a context); try assumption.
(* Goal: @eq form (vimp l (Imp (Imp (if equal_dec j j then a else Atom j) b) c)) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (equal_dec_refl j form a (Atom j)).
(* Goal: @eq form (vimp l (Imp (Imp a b) c)) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
trivial.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: @eq form (if equal_dec j j then a else Atom j) a *)
(* Goal: Derivable (subst_list j a (@cons form (Imp a (Atom j)) context)) (subst_form j a (Atom j)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (Imp a (Atom j)) gamma) work k) (_ : forall _ : forces_t k (Atom j), False), search_spec_aux a gamma work context *)
(* Goal: below_list (@cons form (Imp a (Atom j)) gamma) j1 *)
(* Goal: below_list (@cons form (Imp a (Atom j)) context) j1 *)
(* Goal: sound (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) *)
(* Goal: minimal (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) *)
apply equal_dec_refl.
(* Goal: Derivable (subst_list j b (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp l (Imp (Atom a) (Imp b (Atom j)))) context))) (subst_form j b goal) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply derivable_subst; assumption.
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
clear minimal0 sound0.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (Imp a (Atom j)) gamma) work k) (_ : forall _ : forces_t k (Atom j), False), search_spec_aux a gamma work context *)
(* Goal: below_list (@cons form (Imp a (Atom j)) gamma) j1 *)
(* Goal: below_list (@cons form (Imp a (Atom j)) context) j1 *)
(* Goal: sound (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) *)
(* Goal: minimal (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) *)
intros k k_is_mon k_forces_gamma k_notforces_j.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply refutable with k; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_gamma_cons_gamma_tail with (Imp a (Atom j)); assumption.
(* Goal: forall _ : forces_t2 k k''' (Atom a), forces_t2 k k''' (Atom j) *)
intros forces_a.
(* Goal: False *)
(* Goal: below_list (@cons form (Imp a (Atom j)) gamma) j1 *)
(* Goal: below_list (@cons form (Imp a (Atom j)) context) j1 *)
(* Goal: sound (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) *)
(* Goal: minimal (@cons form (Imp a (Atom j)) gamma) work (@cons form (Imp a (Atom j)) context) *)
apply k_notforces_j.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_a_a_imp_b__forces_b_t with a; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_gamma_cons_gamma_head with gamma work; assumption.
(* Goal: below_list (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply below_cons_list.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_list_less_below_list with j; assumption.
(* Goal: below_list (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply below_cons_list.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_list_less_below_list with j; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply sound_cons_gamma_cons_context; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply minimal_cons_gamma_cons_context; assumption.
Qed.


(***********************************************************************)
(***********************************************************************)


(*****************************************************)
(* rules for   ...(cons (vimp l (AndF a b)) gamma)... *)

Lemma rule_vimp_conj_gamma :
 forall (goal : form) (l : list Int) (b0 b1 : form) 
   (gamma : flist) (work : nf_list) (context : flist) 
   (j : Int),
 search_spec goal (vimp l b0 :: vimp l b1 :: gamma) work context j ->
 search_spec goal (vimp l (AndF b0 b1) :: gamma) work context j.
(* Goal: forall (goal : form) (l : list Int) (b0 b1 : form) (gamma : flist) (work : nf_list) (context : flist) (j : Int) (_ : search_spec goal (@cons form (vimp l b0) (@cons form (vimp l b1) gamma)) work context j), search_spec goal (@cons form (vimp l (AndF b0 b1)) gamma) work context j *)
intros goal l b0 b1 gamma work context j spec0.
(* Goal: search_spec goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context j *)
unfold search_spec in |- *.
(* Goal: forall (_ : below_form goal j) (_ : below_list (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) j) (_ : below_list context j) (_ : sound (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context) (_ : minimal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
intros below_goal below_gamma below_context sound0 minimal0.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
elim spec0; clear spec0; try assumption.
(* Goal: forall _ : Derivable context goal, search_spec_aux goal (@cons form (vimp l (Imp (Imp Falsum b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l c) gamma) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp Falsum b) c)) gamma) work context *)
(* Goal: below_list (@cons form (vimp l c) gamma) j *)
(* Goal: sound (@cons form (vimp l c) gamma) work context *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros der_goal; apply derivable; assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros k k_is_mon k_forces_gamma k_notforces_goal.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply refutable with k; try assumption.
apply forces_gamma_cons_gamma_weak2 with (vimp l b0) (vimp l b1);
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: forall (_ : forces_t k (vimp l b0)) (_ : forces_t k (vimp l b1)), forces_t k (vimp l (AndF b0 b1)) *)
(* Goal: below_list (@cons form (vimp l b0) (@cons form (vimp l b1) gamma)) j *)
(* Goal: sound (@cons form (vimp l b0) (@cons form (vimp l b1) gamma)) work context *)
(* Goal: minimal (@cons form (vimp l b0) (@cons form (vimp l b1) gamma)) work context *)
intros forces_ab0 forces_ab1.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_vimp2 with b0 b1; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros; split; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_list_weak2 with (vimp l (AndF b0 b1)); try assumption.
(* Goal: forall _ : below_form (vimp l (AndF b0 b1)) j, and (below_form (vimp l b0) j) (below_form (vimp l b1) j) *)
(* Goal: sound (@cons form (vimp l b0) (@cons form (vimp l b1) gamma)) work context *)
(* Goal: minimal (@cons form (vimp l b0) (@cons form (vimp l b1) gamma)) work context *)
intros below_ab0b1.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp with (AndF b0 b1); try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros j' below_b0b1; elim below_b0b1; clear below_b0b1; intros; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp with (AndF b0 b1); try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros j' below_b0b1; elim below_b0b1; clear below_b0b1; intros; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply sound_cons_gamma_weak2 with (vimp l (AndF b0 b1)); try assumption.

(* Goal: forall _ : Derivable context (vimp l (Imp (Imp Falsum b) c)), Derivable context (vimp l c) *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros der.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply derivable_vimp with (AndF b0 b1); try assumption.
(* Goal: forall (context : flist) (_ : Derivable context (Imp (Imp Falsum b) c)), Derivable context c *)
(* Goal: Derivable context (vimp l (Imp (Imp Falsum b) c)) *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros context' der'.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply (derivable_a_and_b__derivable_a b0 b1 context'); assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply derivable_vimp with (AndF b0 b1); try assumption.
(* Goal: forall (context : flist) (_ : Derivable context (Imp (Imp Falsum b) c)), Derivable context c *)
(* Goal: Derivable context (vimp l (Imp (Imp Falsum b) c)) *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros context' der'.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply (derivable_a_and_b__derivable_b b0 b1 context'); assumption.

(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply minimal_cons_gamma_weak2 with (vimp l (AndF b0 b1)); try assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l b0)) (_ : forces_t k (vimp l b1)), forces_t k (vimp l (AndF b0 b1)) *)
intros k k_is_mon forces_b0 forces_b1.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_vimp2 with b0 b1; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros; split; assumption.
Qed.


Lemma rule_vimp_conj_gamma_new :
 forall (goal : form) (l : list Int) (b0 b1 : form) 
   (gamma : flist) (work : nf_list) (context : flist) 
   (j j1 : Int),
 Less j j1 ->
 search_spec goal (vimp (j :: nil) b0 :: vimp (j :: nil) b1 :: gamma)
   (nvimp l (NAtom j) :: work)
   (vimp l (Atom j) :: Imp (Atom j) (AndF b0 b1) :: context) j1 ->
 search_spec goal (vimp l (AndF b0 b1) :: gamma) work context j.
(* Goal: forall (goal : form) (l : list Int) (b0 b1 : form) (gamma : flist) (work : nf_list) (context : flist) (j j1 : Int) (_ : Less j j1) (_ : search_spec goal (@cons form (vimp (@cons Int j (@nil Int)) b0) (@cons form (vimp (@cons Int j (@nil Int)) b1) gamma)) (@cons normal_form (nvimp l (NAtom j)) work) (@cons form (vimp l (Atom j)) (@cons form (Imp (Atom j) (AndF b0 b1)) context)) j1), search_spec goal (@cons form (vimp l (AndF b0 b1)) gamma) work context j *)
intros goal l b0 b1 gamma work context j j1 less1 spec0.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply rule_vimp_a_gamma with j1; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply rule_vimp_conj_gamma; assumption.
Qed.


(****************************************************)
(* rules for   ...(cons (vimp l (OrF a b)) gamma)... *)

Lemma rule_vimp_falsum_or_a_gamma :
 forall (goal : form) (l : list Int) (a : form) (gamma : flist)
   (work : nf_list) (context : flist) (j : Int),
 search_spec goal (vimp l a :: gamma) work context j ->
 search_spec goal (vimp l (OrF Falsum a) :: gamma) work context j.
(* Goal: forall (goal : form) (l : list Int) (a : form) (gamma : flist) (work : nf_list) (context : flist) (j : Int) (_ : search_spec goal (@cons form (vimp l a) gamma) work context j), search_spec goal (@cons form (vimp l (OrF a Falsum)) gamma) work context j *)
intros goal l a gamma work context j spec0.
(* Goal: search_spec goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context j *)
unfold search_spec in |- *.
(* Goal: forall (_ : below_form goal j) (_ : below_list (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) j) (_ : below_list context j) (_ : sound (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context) (_ : minimal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
intros below_goal below_gamma below_context sound0 minimal0.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
elim spec0; clear spec0; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros derivable_i; apply derivable; assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros k k_is_mon k_forces_gamma k_notforces_goal.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply refutable with k; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_gamma_cons_gamma_weak with (vimp l a); try assumption.
(* Goal: forall _ : forces_t k (vimp l a), forces_t k (vimp l (OrF a Falsum)) *)
(* Goal: below_list (@cons form (vimp l a) gamma) j *)
(* Goal: sound (@cons form (vimp l a) gamma) work context *)
(* Goal: minimal (@cons form (vimp l a) gamma) work context *)
intros forces_la.
(* Goal: forces_t k (vimp l (OrF a Falsum)) *)
(* Goal: below_list (@cons form (vimp l a) gamma) j *)
(* Goal: sound (@cons form (vimp l a) gamma) work context *)
(* Goal: minimal (@cons form (vimp l a) gamma) work context *)
apply forces_vimp with a.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros; right; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_list_weak with (vimp l (OrF Falsum a)); try assumption.
(* Goal: forall _ : below_form (vimp l (Imp (Imp a b) c)) j, and (below_form a j) (and (below_form (vimp l (Imp (Imp (Atom j) b) c)) j1) (@eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros below_x.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp with (OrF Falsum a); try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros j0 below_or; elim below_or; intros; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply sound_cons_gamma_weak with (vimp l (OrF Falsum a)); try assumption.
(* Goal: forall _ : Derivable context (vimp l (Imp (Imp Falsum b) c)), Derivable context (vimp l c) *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros der.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply derivable_vimp with (OrF Falsum a); try assumption.
(* Goal: forall (context : flist) (_ : Derivable context (OrF a Falsum)), Derivable context a *)
(* Goal: minimal (@cons form (vimp l a) gamma) work context *)
intros context0 der0.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply derivable_falsum_or_a__derivable_a; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply minimal_cons_gamma_weak with (vimp l (OrF Falsum a)); try assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l a)), forces_t k (vimp l (OrF a Falsum)) *)
intros k k_is_mon k_forces_la.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_vimp with a; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros; right; assumption.
Qed.


Lemma rule_vimp_a_or_falsum_gamma :
 forall (goal : form) (l : list Int) (a : form) (gamma : flist)
   (work : nf_list) (context : flist) (j : Int),
 search_spec goal (vimp l a :: gamma) work context j ->
 search_spec goal (vimp l (OrF a Falsum) :: gamma) work context j.
(* Goal: forall (goal : form) (l : list Int) (a : form) (gamma : flist) (work : nf_list) (context : flist) (j : Int) (_ : search_spec goal (@cons form (vimp l a) gamma) work context j), search_spec goal (@cons form (vimp l (OrF a Falsum)) gamma) work context j *)
intros goal l a gamma work context j spec0.
(* Goal: search_spec goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context j *)
unfold search_spec in |- *.
(* Goal: forall (_ : below_form goal j) (_ : below_list (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) j) (_ : below_list context j) (_ : sound (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context) (_ : minimal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
intros below_goal below_gamma below_context sound0 minimal0.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
elim spec0; clear spec0; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros derivable_i; apply derivable; assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros k k_is_mon k_forces_gamma k_notforces_goal.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply refutable with k; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_gamma_cons_gamma_weak with (vimp l a); try assumption.
(* Goal: forall _ : forces_t k (vimp l a), forces_t k (vimp l (OrF a Falsum)) *)
(* Goal: below_list (@cons form (vimp l a) gamma) j *)
(* Goal: sound (@cons form (vimp l a) gamma) work context *)
(* Goal: minimal (@cons form (vimp l a) gamma) work context *)
intros forces_la.
(* Goal: forces_t k (vimp l (OrF a Falsum)) *)
(* Goal: below_list (@cons form (vimp l a) gamma) j *)
(* Goal: sound (@cons form (vimp l a) gamma) work context *)
(* Goal: minimal (@cons form (vimp l a) gamma) work context *)
apply forces_vimp with a.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros; left; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_list_weak with (vimp l (OrF a Falsum)); try assumption.
(* Goal: forall _ : below_form (vimp l (Imp (Imp a b) c)) j, and (below_form a j) (and (below_form (vimp l (Imp (Imp (Atom j) b) c)) j1) (@eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros below_x.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp with (OrF a Falsum); try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros j0 below_or; elim below_or; intros; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply sound_cons_gamma_weak with (vimp l (OrF a Falsum)); try assumption.
(* Goal: forall _ : Derivable context (vimp l (Imp (Imp Falsum b) c)), Derivable context (vimp l c) *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros der.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply derivable_vimp with (OrF a Falsum); try assumption.
(* Goal: forall (context : flist) (_ : Derivable context (OrF a Falsum)), Derivable context a *)
(* Goal: minimal (@cons form (vimp l a) gamma) work context *)
intros context0 der0.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply derivable_a_or_falsum__derivable_a; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply minimal_cons_gamma_weak with (vimp l (OrF a Falsum)); try assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l a)), forces_t k (vimp l (OrF a Falsum)) *)
intros k k_is_mon k_forces_la.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_vimp with a; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros; left; assumption.
Qed.



Lemma rule_vimp_atom_or_a_gamma :
 forall (goal : form) (l : list Int) (i : Int) (a : form) 
   (gamma : flist) (work : nf_list) (context : flist) 
   (j j1 : Int),
 Less j j1 ->
 search_spec goal (Imp (Atom j) a :: gamma) (nvimp l (NDisj i j) :: work)
   (vimp l (OrF (Atom i) (Atom j)) :: Imp (Atom j) a :: context) j1 ->
 search_spec goal (vimp l (OrF (Atom i) a) :: gamma) work context j.
(* Goal: forall (goal : form) (l : list Int) (i : Int) (a : form) (gamma : flist) (work : nf_list) (context : flist) (j j1 : Int) (_ : Less j j1) (_ : search_spec goal (@cons form (Imp (Atom j) a) gamma) (@cons normal_form (nvimp l (NDisj i j)) work) (@cons form (vimp l (OrF (Atom i) (Atom j))) (@cons form (Imp (Atom j) a) context)) j1), search_spec goal (@cons form (vimp l (OrF (Atom i) a)) gamma) work context j *)
intros goal l i a gamma work context j j1 less1 spec0.
apply
 search_spec_subst_gamma_pos
  with (j1 := j1) (a := a) (b := vimp l (OrF (Atom i) (Atom j)));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: forall _ : below_form (vimp l (OrF a b)) j, and (below_form a j) (and (below_form (vimp l (OrF (Atom j) b)) j1) (@eq form (subst_form j a (vimp l (OrF (Atom j) b))) (vimp l (OrF a b)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (OrF (Atom j) b))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (OrF a b)) *)
intros below_c.
(* Goal: and (below_form a j) (and (below_form (vimp l (OrF (Atom i) (Atom j))) j1) (@eq form (subst_form j a (vimp l (OrF (Atom i) (Atom j)))) (vimp l (OrF (Atom i) a)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (OrF (Atom i) (Atom j)))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (OrF (Atom i) a)) *)
(* Goal: search_spec goal (@cons form (vimp l (OrF (Atom i) (Atom j))) (@cons form (Imp (Atom j) a) gamma)) work (@cons form (vimp l (OrF (Atom i) (Atom j))) (@cons form (Imp (Atom j) a) context)) j1 *)
generalize (below_vimp_tail j l (OrF (Atom i) a) below_c).
(* Goal: forall _ : forall (i : Int) (_ : @In Int i l), Less i j, and (below_form a j) (and (below_form (vimp l (OrF (Atom i) (Atom j))) j1) (@eq form (subst_form j a (vimp l (OrF (Atom i) (Atom j)))) (vimp l (OrF (Atom i) a)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (OrF (Atom i) (Atom j)))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (OrF (Atom i) a)) *)
(* Goal: search_spec goal (@cons form (vimp l (OrF (Atom i) (Atom j))) (@cons form (Imp (Atom j) a) gamma)) work (@cons form (vimp l (OrF (Atom i) (Atom j))) (@cons form (Imp (Atom j) a) context)) j1 *)
generalize (below_vimp_head j l (OrF (Atom i) a) below_c); clear below_c.
(* Goal: forall (_ : below_form (OrF (Atom i) a) j) (_ : forall (i : Int) (_ : @In Int i l), Less i j), and (below_form a j) (and (below_form (vimp l (OrF (Atom i) (Atom j))) j1) (@eq form (subst_form j a (vimp l (OrF (Atom i) (Atom j)))) (vimp l (OrF (Atom i) a)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (OrF (Atom i) (Atom j)))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (OrF (Atom i) a)) *)
(* Goal: search_spec goal (@cons form (vimp l (OrF (Atom i) (Atom j))) (@cons form (Imp (Atom j) a) gamma)) work (@cons form (vimp l (OrF (Atom i) (Atom j))) (@cons form (Imp (Atom j) a) context)) j1 *)
intros below_c below_l; elim below_c; clear below_c; intros below_i below_a.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp_split.
(* Goal: forall (i : Int) (_ : @In Int i l), Less i j1 *)
(* Goal: below_form (Imp (Imp a (Atom j)) c) j1 *)
(* Goal: below_list context j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
intros i0 in0.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply less_trans with j; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_l; assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split. 
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_vimp_head j a l (OrF (Atom i) (Atom j))); try assumption.
change
  (vimp l (OrF (subst_form j a (Atom i)) (subst_form j a (Atom j))) =
   vimp l (OrF (Atom i) a)) in |- *.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_form_below j a (Atom i)); try assumption.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: @eq form (vimp l (Imp (Imp (if equal_dec j j then a else Atom j) b) c)) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (equal_dec_refl j form a (Atom j)).
(* Goal: @eq form (vimp l (Imp (Imp a b) c)) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
trivial.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros k k_is_mon forces1 forces2.
(* Goal: forces_t k (vimp l (OrF (Atom i) a)) *)
(* Goal: search_spec goal (@cons form (vimp l (OrF (Atom i) (Atom j))) (@cons form (Imp (Atom j) a) gamma)) work (@cons form (vimp l (OrF (Atom i) (Atom j))) (@cons form (Imp (Atom j) a) context)) j1 *)
apply forces_vimp with (OrF (Atom i) (Atom j)).
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k) (_ : forces_t2 k k' (OrF (Atom i) (Atom j))), forces_t2 k k' (OrF (Atom i) a) *)
(* Goal: forces_t k (vimp l (OrF (Atom i) (Atom j))) *)
(* Goal: search_spec goal (@cons form (vimp l (OrF (Atom i) (Atom j))) (@cons form (Imp (Atom j) a) gamma)) work (@cons form (vimp l (OrF (Atom i) (Atom j))) (@cons form (Imp (Atom j) a) context)) j1 *)
intros k' suc1 forces_ij.
(* Goal: forces_t2 k k' (OrF (Atom i) a) *)
(* Goal: forces_t k (vimp l (OrF (Atom i) (Atom j))) *)
(* Goal: search_spec goal (@cons form (vimp l (OrF (Atom i) (Atom j))) (@cons form (Imp (Atom j) a) gamma)) work (@cons form (vimp l (OrF (Atom i) (Atom j))) (@cons form (Imp (Atom j) a) context)) j1 *)
elim forces_ij; clear forces_ij.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros; left; assumption.
(* Goal: forall _ : forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' (Atom j), forces_t2 k k' (OrF (Atom i) a) *)
(* Goal: forces_t k (vimp l (OrF (Atom i) (Atom j))) *)
(* Goal: search_spec goal (@cons form (vimp l (OrF (Atom i) (Atom j))) (@cons form (Imp (Atom j) a) gamma)) work (@cons form (vimp l (OrF (Atom i) (Atom j))) (@cons form (Imp (Atom j) a) context)) j1 *)
intros; right.
(* Goal: forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' a *)
(* Goal: forall _ : forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' b, forces_t2 k k' (OrF a b) *)
(* Goal: forces_t k (vimp l (OrF (Atom j) b)) *)
change (forces_t2 k k' a) in |- *.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply (forces2 k'); assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply rule_shift_gamma_work with (a := NDisj i j); assumption.
Qed.



Lemma rule_vimp_a_or_b_gamma :
 forall (goal : form) (l : list Int) (a b : form) (gamma : flist)
   (work : nf_list) (context : flist) (j j1 : Int),
 Less j j1 ->
 search_spec goal (vimp l (OrF (Atom j) b) :: vimp (j :: nil) a :: gamma)
   work (vimp l (OrF (Atom j) b) :: Imp (Atom j) a :: context) j1 ->
 search_spec goal (vimp l (OrF a b) :: gamma) work context j.
(* Goal: forall (goal : form) (l : list Int) (a b : form) (gamma : flist) (work : nf_list) (context : flist) (j j1 : Int) (_ : Less j j1) (_ : search_spec goal (@cons form (vimp l (OrF (Atom j) b)) (@cons form (vimp (@cons Int j (@nil Int)) a) gamma)) work (@cons form (vimp l (OrF (Atom j) b)) (@cons form (Imp (Atom j) a) context)) j1), search_spec goal (@cons form (vimp l (OrF a b)) gamma) work context j *)
intros goal l a b gamma work context j j1 less1 spec0.
apply
 search_spec_subst_gamma_pos
  with (j1 := j1) (a := a) (b := vimp l (OrF (Atom j) b)); 
 try assumption; clear spec0.
(* Goal: forall _ : below_form (vimp l (OrF a b)) j, and (below_form a j) (and (below_form (vimp l (OrF (Atom j) b)) j1) (@eq form (subst_form j a (vimp l (OrF (Atom j) b))) (vimp l (OrF a b)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (OrF (Atom j) b))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (OrF a b)) *)
intros below_c.
(* Goal: and (below_form a j) (and (below_form (vimp l (OrF (Atom j) b)) j1) (@eq form (subst_form j a (vimp l (OrF (Atom j) b))) (vimp l (OrF a b)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (OrF (Atom j) b))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (OrF a b)) *)
generalize (below_vimp_tail j l (OrF a b) below_c).
(* Goal: forall _ : forall (i : Int) (_ : @In Int i l), Less i j, and (below_form a j) (and (below_form (vimp l (OrF (Atom j) b)) j1) (@eq form (subst_form j a (vimp l (OrF (Atom j) b))) (vimp l (OrF a b)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (OrF (Atom j) b))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (OrF a b)) *)
generalize (below_vimp_head j l (OrF a b) below_c); clear below_c.
intros below_ab below_l; elim below_ab; clear below_ab;
 intros below_a below_b.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp_split.
(* Goal: forall (i : Int) (_ : @In Int i l), Less i j1 *)
(* Goal: below_form (Imp (Imp a (Atom j)) c) j1 *)
(* Goal: below_list context j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
intros i0 in0.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply less_trans with j; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_l; assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_vimp_head j a l (OrF (Atom j) b)); try assumption.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_form_below j a b); try assumption.
(* Goal: @eq form (vimp l (Imp (Imp (if equal_dec j j then a else Atom j) b) c)) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (equal_dec_refl j form a (Atom j)).
(* Goal: @eq form (vimp l (Imp (Imp a b) c)) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
trivial.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros k k_is_mon forces1 forces2.
(* Goal: forces_t k (vimp l (OrF a b)) *)
apply forces_vimp with (OrF (Atom j) b).
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k) (_ : forces_t2 k k' (OrF (Atom j) b)), forces_t2 k k' (OrF a b) *)
(* Goal: forces_t k (vimp l (OrF (Atom j) b)) *)
intros k' suc1 forces_jb.
(* Goal: forces_t2 k k' (OrF a b) *)
(* Goal: forces_t k (vimp l (OrF (Atom j) b)) *)
elim forces_jb; clear forces_jb.
(* Goal: forall _ : forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' (Atom j), forces_t2 k k' (OrF a b) *)
(* Goal: forall _ : forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' b, forces_t2 k k' (OrF a b) *)
(* Goal: forces_t k (vimp l (OrF (Atom j) b)) *)
intros; left.
(* Goal: forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' a *)
(* Goal: forall _ : forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' b, forces_t2 k k' (OrF a b) *)
(* Goal: forces_t k (vimp l (OrF (Atom j) b)) *)
change (forces_t2 k k' a) in |- *.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply (forces2 k'); assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros; right; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
Qed.


(**********************************************************)
(* rules for   ...(cons (vimp l (Imp Falsum b)) gamma)... *)

Lemma rule_vimp_falsum_imp_b_gamma :
 forall (goal : form) (l : list Int) (b : form) (gamma : flist)
   (work : nf_list) (context : flist) (j : Int),
 search_spec goal gamma work context j ->
 search_spec goal (vimp l (Imp Falsum b) :: gamma) work context j.
(* Goal: forall (goal : form) (l : list Int) (b : form) (gamma : flist) (work : nf_list) (context : flist) (j : Int) (_ : search_spec goal gamma work context j), search_spec goal (@cons form (vimp l (Imp Falsum b)) gamma) work context j *)
intros goal l b gamma work context j spec0.
(* Goal: search_spec goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context j *)
unfold search_spec in |- *.
(* Goal: forall (_ : below_form goal j) (_ : below_list (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) j) (_ : below_list context j) (_ : sound (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context) (_ : minimal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
intros below_goal below_gamma below_context sound0 minimal0.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
elim spec0; clear spec0; try assumption.
(* Goal: forall _ : Derivable context goal, search_spec_aux goal (@cons form (vimp l (Imp (Imp Falsum b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l c) gamma) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp Falsum b) c)) gamma) work context *)
(* Goal: below_list (@cons form (vimp l c) gamma) j *)
(* Goal: sound (@cons form (vimp l c) gamma) work context *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros der_goal; apply derivable; assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros k k_is_mon k_forces_gamma k_notforces_goal.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply refutable with k; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_gamma_cons_gamma; try assumption.
(* Goal: forces_t k (vimp l (Imp Falsum b)) *)
apply forces_vimp0.
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k), forces_t2 k k' (Imp Falsum b) *)
intros k' suc1.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
unfold forces_t in |- *; unfold forces_t2 in |- *; simpl in |- *.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros; elimtype False; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_cons_list_tail with (vimp l (Imp Falsum b)); assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply sound_cons_gamma_tail with (vimp l (Imp Falsum b)); assumption.
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
unfold minimal in |- *.
(* Goal: forall (a : form) (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma gamma work k) (_ : @In form a context), forces_t k a *)
intros c k k_is_mon k_forces_gamma in_c.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply minimal0; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_gamma_cons_gamma; try assumption.
(* Goal: forces_t k (vimp l (Imp Falsum b)) *)
apply forces_vimp0.
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k), forces_t2 k k' (Imp Falsum b) *)
intros k' suc1.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
unfold forces_t in |- *; unfold forces_t2 in |- *; simpl in |- *.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros; elimtype False; assumption.
Qed.

(**********************************************************)
(* rules for   ...(cons (vimp l (Imp (Atom i) b)) gamma)... *)

Lemma rule_vimp_atom_imp_b_gamma :
 forall (goal : form) (l : list Int) (i : Int) (b : form) 
   (gamma : flist) (work : nf_list) (context : flist) 
   (j : Int),
 search_spec goal (vimp (i :: l) b :: gamma) work context j ->
 search_spec goal (vimp l (Imp (Atom i) b) :: gamma) work context j.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros; assumption.
Qed.


(*****************************************************)
(* rules for   ...(cons (Imp (AndF a0 a1) b) gamma)... *)

Lemma rule_vimp_and_imp_gamma :
 forall (goal : form) (l : list Int) (a0 a1 b : form) 
   (gamma : flist) (work : nf_list) (context : flist) 
   (j : Int),
 search_spec goal (vimp l (Imp a0 (Imp a1 b)) :: gamma) work context j ->
 search_spec goal (vimp l (Imp (AndF a0 a1) b) :: gamma) work context j.
(* Goal: forall (goal : form) (l : list Int) (a0 a1 b : form) (gamma : flist) (work : nf_list) (context : flist) (j : Int) (_ : search_spec goal (@cons form (vimp l (Imp a0 b)) (@cons form (vimp l (Imp a1 b)) gamma)) work context j), search_spec goal (@cons form (vimp l (Imp (OrF a0 a1) b)) gamma) work context j *)
intros goal l a0 a1 b gamma work context j spec0.
(* Goal: search_spec goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context j *)
unfold search_spec in |- *.
(* Goal: forall (_ : below_form goal j) (_ : below_list (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) j) (_ : below_list context j) (_ : sound (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context) (_ : minimal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
intros below_goal below_gamma below_context sound0 minimal0.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
elim spec0; clear spec0; try assumption.
(* Goal: forall _ : Derivable context goal, search_spec_aux goal (@cons form (vimp l (Imp (Imp Falsum b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l c) gamma) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp Falsum b) c)) gamma) work context *)
(* Goal: below_list (@cons form (vimp l c) gamma) j *)
(* Goal: sound (@cons form (vimp l c) gamma) work context *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros der_goal; apply derivable; assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros k k_is_mon k_forces_gamma k_notforces_goal.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply refutable with k; try assumption.
apply forces_gamma_cons_gamma_weak with (vimp l (Imp a0 (Imp a1 b)));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: forall _ : forces_t k (vimp l (Imp a0 (Imp a1 b))), forces_t k (vimp l (Imp (AndF a0 a1) b)) *)
(* Goal: below_list (@cons form (vimp l (Imp a0 (Imp a1 b))) gamma) j *)
(* Goal: sound (@cons form (vimp l (Imp a0 (Imp a1 b))) gamma) work context *)
(* Goal: minimal (@cons form (vimp l (Imp a0 (Imp a1 b))) gamma) work context *)
intros forces_a0a1b.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_vimp with (Imp a0 (Imp a1 b)); try assumption.
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k) (_ : forces_t2 k k' (Imp (Imp a (Atom j)) c)), forces_t2 k k' (Imp (Imp a Falsum) c) *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
intros k' suc1 forces1.
unfold forces_t2 in |- *;
 apply forces_a0_imp_a1_imp_b__forces_a0_and_a1_imp_b; 
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply kripke_tree_kripke_model; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_list_weak with (vimp l (Imp (AndF a0 a1) b)); try assumption.
(* Goal: forall _ : below_form (vimp l (Imp (AndF a0 a1) b)) j, below_form (vimp l (Imp a0 (Imp a1 b))) j *)
(* Goal: sound (@cons form (vimp l (Imp a0 (Imp a1 b))) gamma) work context *)
(* Goal: minimal (@cons form (vimp l (Imp a0 (Imp a1 b))) gamma) work context *)
intros below_lab.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp with (Imp (AndF a0 a1) b); try assumption.
(* Goal: forall (j : Int) (_ : below_form (Imp (Imp Falsum b) c) j), below_form c j *)
(* Goal: sound (@cons form (vimp l c) gamma) work context *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros j' below_ab; elim below_ab; clear below_ab; intros below_a below_b.
(* Goal: below_form (Imp a1 b) j' *)
(* Goal: sound (@cons form (vimp l (Imp a0 b)) (@cons form (vimp l (Imp a1 b)) gamma)) work context *)
(* Goal: minimal (@cons form (vimp l (Imp a0 b)) (@cons form (vimp l (Imp a1 b)) gamma)) work context *)
elim below_a; clear below_a; intros below_a0 below_a1.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split; assumption.
apply sound_cons_gamma_weak with (vimp l (Imp (AndF a0 a1) b));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: forall _ : Derivable context (vimp l (Imp (Imp Falsum b) c)), Derivable context (vimp l c) *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros der.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply derivable_vimp with (Imp (AndF a0 a1) b); try assumption.
(* Goal: forall (context : flist) (_ : Derivable context (Imp (Imp Falsum b) c)), Derivable context c *)
(* Goal: Derivable context (vimp l (Imp (Imp Falsum b) c)) *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros context' der'.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply derivable_a0_and_a1_imp_b__derivable_a0_imp_a1_imp_b; assumption.
apply minimal_cons_gamma_weak with (vimp l (Imp (AndF a0 a1) b));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l c)), forces_t k (vimp l (Imp (Imp Falsum b) c)) *)
intros k k_is_mon forces1.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_vimp with (Imp a0 (Imp a1 b)); try assumption.
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k) (_ : forces_t2 k k' (Imp a0 (Imp a1 b))), forces_t2 k k' (Imp (AndF a0 a1) b) *)
intros k' suc1 forces'.
unfold forces_t2 in |- *;
 apply forces_a0_imp_a1_imp_b__forces_a0_and_a1_imp_b; 
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply kripke_tree_kripke_model; assumption.
Qed.


(**************************************************************)
(* rules for   ...(cons (vimp l (Imp (OrF a0 a1) b)) gamma)... *)


Lemma rule_vimp_or_imp_gamma :
 forall (goal : form) (l : list Int) (a0 a1 b : form) 
   (gamma : flist) (work : nf_list) (context : flist) 
   (j : Int),
 search_spec goal (vimp l (Imp a0 b) :: vimp l (Imp a1 b) :: gamma) work
   context j ->
 search_spec goal (vimp l (Imp (OrF a0 a1) b) :: gamma) work context j.
(* Goal: forall (goal : form) (l : list Int) (a0 a1 b : form) (gamma : flist) (work : nf_list) (context : flist) (j : Int) (_ : search_spec goal (@cons form (vimp l (Imp a0 b)) (@cons form (vimp l (Imp a1 b)) gamma)) work context j), search_spec goal (@cons form (vimp l (Imp (OrF a0 a1) b)) gamma) work context j *)
intros goal l a0 a1 b gamma work context j spec0.
(* Goal: search_spec goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context j *)
unfold search_spec in |- *.
(* Goal: forall (_ : below_form goal j) (_ : below_list (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) j) (_ : below_list context j) (_ : sound (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context) (_ : minimal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
intros below_goal below_gamma below_context sound0 minimal0.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
elim spec0; clear spec0; try assumption.
(* Goal: forall _ : Derivable context goal, search_spec_aux goal (@cons form (vimp l (Imp (Imp Falsum b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l c) gamma) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp Falsum b) c)) gamma) work context *)
(* Goal: below_list (@cons form (vimp l c) gamma) j *)
(* Goal: sound (@cons form (vimp l c) gamma) work context *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros der_goal; apply derivable; assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros k k_is_mon k_forces_gamma k_notforces_goal.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply refutable with k; try assumption.
apply
 forces_gamma_cons_gamma_weak2 with (vimp l (Imp a0 b)) (vimp l (Imp a1 b));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: forall (_ : forces_t k (vimp l (Imp (Imp (Atom a) (Atom j)) c))) (_ : forces_t k (vimp (@cons Int a l) (Imp b (Atom j)))), forces_t k (vimp l (Imp (Imp (Atom a) b) c)) *)
intros forces1 forces2.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_vimp2 with (Imp a0 b) (Imp a1 b); try assumption.
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k) (_ : forces_t2 k k' (Imp a0 b)) (_ : forces_t2 k k' (Imp a1 b)), forces_t2 k k' (Imp (OrF a0 a1) b) *)
intros k' suc1 forces_a0b forces_a1b.
unfold forces_t2 in |- *;
 apply forces_a0_imp_b_and_a1_imp_b__forces_a0_or_a1_imp_b; 
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_list_weak2 with (vimp l (Imp (OrF a0 a1) b)); try assumption.
(* Goal: forall _ : below_form (vimp l (Imp (OrF a0 a1) b)) j, and (below_form (vimp l (Imp a0 b)) j) (below_form (vimp l (Imp a1 b)) j) *)
(* Goal: sound (@cons form (vimp l (Imp a0 b)) (@cons form (vimp l (Imp a1 b)) gamma)) work context *)
(* Goal: minimal (@cons form (vimp l (Imp a0 b)) (@cons form (vimp l (Imp a1 b)) gamma)) work context *)
intros below1.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp with (Imp (OrF a0 a1) b); try assumption.
(* Goal: forall (j : Int) (_ : below_form (Imp (Imp Falsum b) c) j), below_form c j *)
(* Goal: sound (@cons form (vimp l c) gamma) work context *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros j' below_ab; elim below_ab; clear below_ab; intros below_a below_b.
(* Goal: below_form (Imp a1 b) j' *)
(* Goal: sound (@cons form (vimp l (Imp a0 b)) (@cons form (vimp l (Imp a1 b)) gamma)) work context *)
(* Goal: minimal (@cons form (vimp l (Imp a0 b)) (@cons form (vimp l (Imp a1 b)) gamma)) work context *)
elim below_a; clear below_a; intros below_a0 below_a1.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp with (Imp (OrF a0 a1) b); try assumption.
(* Goal: forall (j : Int) (_ : below_form (Imp (Imp Falsum b) c) j), below_form c j *)
(* Goal: sound (@cons form (vimp l c) gamma) work context *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros j' below_ab; elim below_ab; clear below_ab; intros below_a below_b.
(* Goal: below_form (Imp a1 b) j' *)
(* Goal: sound (@cons form (vimp l (Imp a0 b)) (@cons form (vimp l (Imp a1 b)) gamma)) work context *)
(* Goal: minimal (@cons form (vimp l (Imp a0 b)) (@cons form (vimp l (Imp a1 b)) gamma)) work context *)
elim below_a; clear below_a; intros below_a0 below_a1.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split; assumption.
apply sound_cons_gamma_weak2 with (vimp l (Imp (OrF a0 a1) b));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: forall _ : Derivable context (vimp l (Imp (Imp Falsum b) c)), Derivable context (vimp l c) *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros der.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply derivable_vimp with (Imp (OrF a0 a1) b); try assumption.
(* Goal: forall (context : flist) (_ : Derivable context (Imp (Imp Falsum b) c)), Derivable context c *)
(* Goal: Derivable context (vimp l (Imp (Imp Falsum b) c)) *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros context' der'.
apply (derivable_a0_or_a1_imp_b__derivable_a0_imp_b context' a0 a1 b der');
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply derivable_vimp with (Imp (OrF a0 a1) b); try assumption.
(* Goal: forall (context : flist) (_ : Derivable context (Imp (Imp Falsum b) c)), Derivable context c *)
(* Goal: Derivable context (vimp l (Imp (Imp Falsum b) c)) *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros context' der'.
apply (derivable_a0_or_a1_imp_b__derivable_a1_imp_b context' a0 a1 b der');
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 assumption.                     

apply minimal_cons_gamma_weak2 with (vimp l (Imp (OrF a0 a1) b));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros k k_is_mon forces1 forces2.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_vimp2 with (Imp a0 b) (Imp a1 b); try assumption.
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k) (_ : forces_t2 k k' (Imp a0 b)) (_ : forces_t2 k k' (Imp a1 b)), forces_t2 k k' (Imp (OrF a0 a1) b) *)
intros k' suc1 forces_a0b forces_a1b.
unfold forces_t2 in |- *;
 apply forces_a0_imp_b_and_a1_imp_b__forces_a0_or_a1_imp_b; 
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
Qed.



Lemma rule_vimp_or_imp_gamma_new :
 forall (goal : form) (l : list Int) (a0 a1 b : form) 
   (gamma : flist) (work : nf_list) (context : flist) 
   (j j1 : Int),
 Less j j1 ->
 search_spec goal
   (vimp l (Imp a0 (Atom j))
    :: vimp l (Imp a1 (Atom j)) :: vimp (j :: nil) b :: gamma) work
   (vimp l (Imp (OrF a0 a1) (Atom j)) :: Imp (Atom j) b :: context) j1 ->
 search_spec goal (vimp l (Imp (OrF a0 a1) b) :: gamma) work context j.
(* Goal: forall (goal : form) (l : list Int) (a0 a1 b : form) (gamma : flist) (work : nf_list) (context : flist) (j j1 : Int) (_ : Less j j1) (_ : search_spec goal (@cons form (vimp l (Imp a0 (Atom j))) (@cons form (vimp l (Imp a1 (Atom j))) (@cons form (vimp (@cons Int j (@nil Int)) b) gamma))) work (@cons form (vimp l (Imp (OrF a0 a1) (Atom j))) (@cons form (Imp (Atom j) b) context)) j1), search_spec goal (@cons form (vimp l (Imp (OrF a0 a1) b)) gamma) work context j *)
intros goal l a0 a1 b gamma work context j j1 less1 spec0.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply rule_vimp_imp_gamma with j1; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply rule_vimp_or_imp_gamma; assumption.
Qed.



(*************************************************************)
(* rules for   ...(cons (vimp l (Imp (Imp a b) c)) gamma)... *)


Lemma rule_vimp_falsum_imp_imp_gamma :
 forall (goal : form) (l : list Int) (b c : form) (gamma : flist)
   (work : nf_list) (context : flist) (j : Int),
 search_spec goal (vimp l c :: gamma) work context j ->
 search_spec goal (vimp l (Imp (Imp Falsum b) c) :: gamma) work context j.
(* Goal: forall (goal : form) (l : list Int) (b c : form) (gamma : flist) (work : nf_list) (context : flist) (j : Int) (_ : search_spec goal (@cons form (vimp l c) gamma) work context j), search_spec goal (@cons form (vimp l (Imp (Imp Falsum b) c)) gamma) work context j *)
intros goal l b c gamma work context j spec0.
(* Goal: search_spec goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context j *)
unfold search_spec in |- *.
(* Goal: forall (_ : below_form goal j) (_ : below_list (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) j) (_ : below_list context j) (_ : sound (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context) (_ : minimal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
intros below_goal below_gamma below_context sound0 minimal0.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
elim spec0; clear spec0; try assumption.
(* Goal: forall _ : Derivable context goal, search_spec_aux goal (@cons form (vimp l (Imp (Imp Falsum b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l c) gamma) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp Falsum b) c)) gamma) work context *)
(* Goal: below_list (@cons form (vimp l c) gamma) j *)
(* Goal: sound (@cons form (vimp l c) gamma) work context *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros der_goal; apply derivable; assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros k k_is_mon k_forces_gamma k_notforces_goal.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply refutable with k; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_gamma_cons_gamma_weak with (vimp l c); try assumption.
(* Goal: forall _ : forces_t k (vimp l (Imp (Imp a (Atom j)) c)), forces_t k (vimp l (Imp (Imp a Falsum) c)) *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
intros forces_lc.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_vimp with c; try assumption.
(* Goal: forall context : flist, Derivable context (Imp b b) *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
unfold forces_t2 in |- *; apply forces_b__forces_a_imp_b; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply kripke_tree_kripke_model; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_list_weak with (vimp l (Imp (Imp Falsum b) c)); try assumption.
(* Goal: forall _ : below_form (vimp l (Imp (Imp a Falsum) c)) j, search_spec_aux goal (@cons form (vimp l (Imp (Imp a Falsum) c)) gamma) work context *)
intros below_lc.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp with (Imp (Imp Falsum b) c); try assumption.
(* Goal: forall (j : Int) (_ : below_form (Imp (Imp Falsum b) c) j), below_form c j *)
(* Goal: sound (@cons form (vimp l c) gamma) work context *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros j' below_ab; elim below_ab; clear below_ab; intros below_a below_b.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
apply sound_cons_gamma_weak with (vimp l (Imp (Imp Falsum b) c));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: forall _ : Derivable context (vimp l (Imp (Imp Falsum b) c)), Derivable context (vimp l c) *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros der.
(* Goal: Derivable context (vimp l c) *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
apply derivable_vimp with (Imp (Imp Falsum b) c).
(* Goal: forall (context : flist) (_ : Derivable context (Imp (Imp Falsum b) c)), Derivable context c *)
(* Goal: Derivable context (vimp l (Imp (Imp Falsum b) c)) *)
(* Goal: minimal (@cons form (vimp l c) gamma) work context *)
intros context' der'.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply derivable_falsum_imp_b_imp_c__derivable_c with b; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
apply minimal_cons_gamma_weak with (vimp l (Imp (Imp Falsum b) c));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l c)), forces_t k (vimp l (Imp (Imp Falsum b) c)) *)
intros k k_is_mon forces1.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_vimp with c; try assumption.
(* Goal: forall context : flist, Derivable context (Imp b b) *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
unfold forces_t2 in |- *; apply forces_b__forces_a_imp_b; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply kripke_tree_kripke_model; assumption.
Qed.


Lemma rule_vimp_imp_falsum_imp_gamma :
 forall (goal : form) (l : list Int) (a c : form) (gamma : flist)
   (work : nf_list) (context : flist) (j j1 : Int),
 Less j j1 ->
 search_spec goal (vimp l (Imp (Imp a (Atom j)) c) :: gamma) work
   (vimp l (Imp (Imp a (Atom j)) c) :: context) j1 ->
 search_spec goal (vimp l (Imp (Imp a Falsum) c) :: gamma) work context j.
(* Goal: forall (goal : form) (l : list Int) (a c : form) (gamma : flist) (work : nf_list) (context : flist) (j j1 : Int) (_ : Less j j1) (_ : search_spec goal (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) j1), search_spec goal (@cons form (vimp l (Imp (Imp a Falsum) c)) gamma) work context j *)
intros goal l a c gamma work context j j1 less1 spec0.
(* Goal: search_spec goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context j *)
unfold search_spec in |- *.
(* Goal: forall (_ : below_form goal j) (_ : below_list (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) j) (_ : below_list context j) (_ : sound (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context) (_ : minimal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
intros below_goal below_gamma below_context sound0 minimal0.
generalize
 (below_cons_list_head (vimp l (Imp (Imp a Falsum) c)) gamma j below_gamma).
(* Goal: forall _ : below_form (vimp l (Imp (Imp a Falsum) c)) j, search_spec_aux goal (@cons form (vimp l (Imp (Imp a Falsum) c)) gamma) work context *)
intros below_lc.
generalize
 (below_cons_list_tail (vimp l (Imp (Imp a Falsum) c)) gamma j below_gamma).
(* Goal: forall _ : below_list gamma j, search_spec_aux goal (@cons form (vimp l (Imp (Imp a Falsum) c)) gamma) work context *)
clear below_gamma; intros below_gamma.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp a Falsum) c)) gamma) work context *)
elim (below_vimp_head j l (Imp (Imp a Falsum) c) below_lc).
(* Goal: forall (_ : below_form (Imp a Falsum) j) (_ : below_form c j), search_spec_aux goal (@cons form (vimp l (Imp (Imp a Falsum) c)) gamma) work context *)
intros below_a_falsum; elim below_a_falsum; clear below_a_falsum.
(* Goal: forall (_ : below_form a j) (_ : below_form Falsum j) (_ : below_form c j), search_spec_aux goal (@cons form (vimp l (Imp (Imp a Falsum) c)) gamma) work context *)
intros below_a below_falsum below_c.
generalize (below_vimp_tail j l (Imp (Imp a Falsum) c) below_lc);
 clear below_lc.
(* Goal: forall _ : forall (i : Int) (_ : @In Int i l), Less i j, search_spec_aux goal (@cons form (vimp l (Imp (Imp a Falsum) c)) gamma) work context *)
intros below_l.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
elim spec0; clear spec0; try assumption.
(* Goal: forall _ : Derivable (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) goal, search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
clear minimal0.
(* Goal: forall _ : Derivable (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) goal, search_spec_aux goal (@cons form (vimp l (Imp (Imp a Falsum) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp a Falsum) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
intros der_goal.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply derivable.
(* Goal: Derivable context goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp a Falsum) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
apply derivable_cut_merge with (vimp l (Imp (Imp a Falsum) c)).
(* Goal: Derivable context (vimp l (Imp (Imp (Atom a) b) c)) *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Imp (Atom a) (Atom j)) c))) (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context)) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply sound0.
(* Goal: in_gamma (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma) work (vimp (@cons Int a l) (Imp b (Atom j))) *)
(* Goal: forces_t k x *)
apply in_gamma_cons_gamma_head.
apply
 derivable_eq
  with
    (subst_list j Falsum (vimp l (Imp (Imp a (Atom j)) c) :: context))
    (subst_form j Falsum goal).
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: @eq flist (@cons form (subst_form j Falsum (vimp l (Imp (Imp a (Atom j)) c))) (subst_list j Falsum context)) (@cons form (vimp l (Imp (Imp a Falsum) c)) context) *)
(* Goal: @eq form (subst_form j Falsum goal) goal *)
(* Goal: Derivable (subst_list j Falsum (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context)) (subst_form j Falsum goal) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp a Falsum) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
 rewrite (subst_vimp_head j Falsum l (Imp (Imp a (Atom j)) c)).
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_form_below j Falsum a); try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_form_below j Falsum c); try assumption.
(* Goal: @eq flist (@cons form (vimp l (Imp (Imp a (if equal_dec j j then Falsum else Atom j)) c)) (subst_list j Falsum context)) (@cons form (vimp l (Imp (Imp a Falsum) c)) context) *)
(* Goal: forall (i : Int) (_ : @In Int i l), Less i j *)
(* Goal: @eq form (subst_form j Falsum goal) goal *)
(* Goal: Derivable (subst_list j Falsum (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context)) (subst_form j Falsum goal) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp a Falsum) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
 rewrite (equal_dec_refl j form Falsum (Atom j)).
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_list_below j Falsum context); try assumption.
(* Goal: @eq form (vimp l (Imp (Imp a b) c)) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
trivial.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply subst_form_below; assumption.
(* Goal: Derivable (subst_list j b (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp l (Imp (Atom a) (Imp b (Atom j)))) context))) (subst_form j b goal) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply derivable_subst; assumption.
(* Goal: forall _ : Derivable (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) goal, search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
clear minimal0.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros k k_is_mon k_forces_gamma k_notforces_goal.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply refutable with k; try assumption.
apply forces_gamma_cons_gamma_weak with (vimp l (Imp (Imp a (Atom j)) c));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: forall _ : forces_t k (vimp l (Imp (Imp a (Atom j)) c)), forces_t k (vimp l (Imp (Imp a Falsum) c)) *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
intros forces_lc.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_vimp with (Imp (Imp a (Atom j)) c); try assumption.
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k) (_ : forces_t2 k k' (Imp (Imp a (Atom j)) c)), forces_t2 k k' (Imp (Imp a Falsum) c) *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
intros k' suc1 forces1.
apply forces_a_imp_b_imp_c__forces_a_imp_falsum_imp_c_t2 with (Atom j);
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 assumption.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_list (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply below_cons_list.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp_split.
(* Goal: forall (i : Int) (_ : @In Int i l), Less i j1 *)
(* Goal: below_form (Imp (Imp a (Atom j)) c) j1 *)
(* Goal: below_list context j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
intros i0 in0.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply less_trans with j; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_l; assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_list_less_below_list with j; assumption.
(* Goal: below_list (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply below_cons_list.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp_split.
(* Goal: forall (i : Int) (_ : @In Int i l), Less i j1 *)
(* Goal: below_form (Imp (Imp a (Atom j)) c) j1 *)
(* Goal: below_list context j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp a (Atom j)) c)) gamma) work (@cons form (vimp l (Imp (Imp a (Atom j)) c)) context) *)
intros i0 in0.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply less_trans with j; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_l; assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_list_less_below_list with j; assumption.
(* Goal: sound (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma) work (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply sound_cons_gamma_cons_context.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply sound_cons_gamma_tail with (vimp l (Imp (Imp a Falsum) c)); assumption.
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
unfold minimal in |- *.
(* Goal: forall (a0 : form) (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : @In form a0 (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context))), forces_t k a0 *)
intros x k k_is_mon k_forces_gamma in_x.
(* Goal: forces_t k x *)
inversion_clear in_x.
(* Goal: forces_t k x *)
(* Goal: forces_t k x *)
 rewrite <- H; clear H x.
(* Goal: forces_t k (vimp (@cons Int a l) (Imp b (Atom j))) *)
(* Goal: forces_t k x *)
apply k_forces_gamma.
(* Goal: in_gamma (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma) work (vimp (@cons Int a l) (Imp b (Atom j))) *)
(* Goal: forces_t k x *)
apply in_gamma_cons_gamma_head.
(* Goal: forces_t k x *)
apply minimal0; try assumption; clear H.
apply forces_gamma_cons_gamma_weak with (vimp l (Imp (Imp a (Atom j)) c));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: forall _ : forces_t k (vimp l (Imp (Imp a (Atom j)) c)), forces_t k (vimp l (Imp (Imp a Falsum) c)) *)
intros forces1.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_vimp with (Imp (Imp a (Atom j)) c); try assumption.
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k) (_ : forces_t2 k k' (Imp (Imp a (Atom j)) c)), forces_t2 k k' (Imp (Imp a Falsum) c) *)
intros k' suc1 forces2.
apply forces_a_imp_b_imp_c__forces_a_imp_falsum_imp_c_t2 with (Atom j);
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 assumption.
Qed.


Lemma rule_atom_imp_atom_imp_c_gamma :
 forall (goal : form) (l : list Int) (a b : Int) (c : form) 
   (gamma : flist) (work : nf_list) (context : flist) 
   (j j1 : Int),
 Less j j1 ->
 search_spec goal (Imp (Atom j) c :: gamma)
   (nvimp l (NImp_NF (NImp a b (NAtom j))) :: work)
   (vimp l (Imp (Imp (Atom a) (Atom b)) (Atom j))
    :: Imp (Atom j) c :: context) j1 ->
 search_spec goal (vimp l (Imp (Imp (Atom a) (Atom b)) c) :: gamma) work
   context j.
(* Goal: forall (goal : form) (l : list Int) (a b c : form) (gamma : flist) (work : nf_list) (context : flist) (j j1 : Int) (_ : Less j j1) (_ : search_spec goal (@cons form (vimp l (Imp (Imp (Atom j) b) c)) (@cons form (Imp (Atom j) a) gamma)) work (@cons form (vimp l (Imp (Imp (Atom j) b) c)) (@cons form (Imp (Atom j) a) context)) j1), search_spec goal (@cons form (vimp l (Imp (Imp a b) c)) gamma) work context j *)
intros goal l a b c gamma work context j j1 less1 spec0.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply rule_vimp_imp_gamma with j1; try assumption.
apply rule_shift_gamma_work with (a := NImp_NF (NImp a b (NAtom j)));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 assumption.
Qed.


Lemma rule_atom_imp_b_imp_c_gamma :
 forall (goal : form) (l : list Int) (a : Int) (b c : form) 
   (gamma : flist) (work : nf_list) (context : flist) 
   (j j1 : Int),
 Less j j1 ->
 search_spec goal
   (vimp l (Imp (Imp (Atom a) (Atom j)) c)
    :: vimp (a :: l) (Imp b (Atom j)) :: gamma) work
   (vimp l (Imp (Imp (Atom a) (Atom j)) c)
    :: vimp (a :: l) (Imp b (Atom j)) :: context) j1 ->
 search_spec goal (vimp l (Imp (Imp (Atom a) b) c) :: gamma) work context j.
(* Goal: forall (goal : form) (l : list Int) (a b c : form) (gamma : flist) (work : nf_list) (context : flist) (j j1 : Int) (_ : Less j j1) (_ : search_spec goal (@cons form (vimp l (Imp (Imp (Atom j) b) c)) (@cons form (Imp (Atom j) a) gamma)) work (@cons form (vimp l (Imp (Imp (Atom j) b) c)) (@cons form (Imp (Atom j) a) context)) j1), search_spec goal (@cons form (vimp l (Imp (Imp a b) c)) gamma) work context j *)
intros goal l a b c gamma work context j j1 less1 spec0.
(* Goal: search_spec goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context j *)
unfold search_spec in |- *.
(* Goal: forall (_ : below_form goal j) (_ : below_list (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) j) (_ : below_list context j) (_ : sound (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context) (_ : minimal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
intros below_goal below_gamma below_context sound0 minimal0.
generalize
 (below_cons_list_head (vimp l (Imp (Imp (Atom a) b) c)) gamma j below_gamma).
generalize
 (below_cons_list_tail (vimp l (Imp (Imp (Atom a) b) c)) gamma j below_gamma);
 clear below_gamma.
(* Goal: forall (_ : below_list gamma j) (_ : below_form (vimp l (Imp (Imp (Atom a) b) c)) j), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
intros below_gamma below_x.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
generalize (below_vimp_head j l (Imp (Imp (Atom a) b) c) below_x).
generalize (below_vimp_tail j l (Imp (Imp (Atom a) b) c) below_x);
 clear below_x.
(* Goal: forall (_ : forall (i : Int) (_ : @In Int i l), Less i j) (_ : below_form (Imp (Imp (Atom a) b) c) j), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
intros below_l below_x.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
elim below_x; clear below_x; intros below_x below_c.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
elim below_x; clear below_x; intros below_a below_b.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
elim spec0; clear spec0; try assumption.
(* Goal: forall _ : Derivable (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) goal, search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
clear minimal0.
(* Goal: forall _ : Derivable (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) goal, search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros derivable_i.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply derivable.
apply
 derivable_cut with (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))).
 rewrite (subst_vimp_head j b l (Imp (Atom a) (Imp b (Atom j))));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_form_below j b b); try assumption.
(* Goal: Derivable context (vimp l (Imp (Imp (if equal_dec j a then b else Atom a) (if equal_dec j j then b else Atom j)) c)) *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Imp (Atom a) (Atom j)) c))) (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context)) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
 rewrite (equal_dec_refl j form b (Atom j)).
change (Derivable fnil (vimp l (Imp (subst_form j b (Atom a)) (Imp b b))))
 in |- *.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_form_below j b (Atom a)); try assumption.
(* Goal: Derivable fnil (vimp l (Imp (Atom a) (Imp b b))) *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
change (Derivable fnil (vimp (a :: l) (Imp b b))) in |- *.
(* Goal: Derivable fnil (vimp (@cons Int a l) (Imp b b)) *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply derivable_vimp0.
(* Goal: forall context : flist, Derivable context (Imp b b) *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros.
(* Goal: Derivable context0 (Imp b b) *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply Derivable_Intro with (Abs b (Var 0)).
(* Goal: derives context0 (Abs b (Var O)) (Imp b b) *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply ImpIntro.
(* Goal: derives (@cons form b context0) (Var O) b *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply ByAssumption.
(* Goal: my_nth form O (@cons form b context0) b *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply My_NthO.
apply
 derivable_cut_merge
  with (subst_form j b (vimp l (Imp (Imp (Atom a) (Atom j)) c))).
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context) (subst_form j b (vimp l (Imp (Imp (Atom a) (Atom j)) c))) *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Imp (Atom a) (Atom j)) c))) (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context)) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply derivable_weak.
 rewrite (subst_vimp_head j b l (Imp (Imp (Atom a) (Atom j)) c));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_form_below j b c); try assumption.
(* Goal: Derivable context (vimp l (Imp (Imp (if equal_dec j a then b else Atom a) (if equal_dec j j then b else Atom j)) c)) *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Imp (Atom a) (Atom j)) c))) (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context)) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
 rewrite (equal_dec_refl j form b (Atom j)).
change (Derivable context (vimp l (Imp (Imp (subst_form j b (Atom a)) b) c)))
 in |- *.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_form_below j b (Atom a)); try assumption.
(* Goal: Derivable context (vimp l (Imp (Imp (Atom a) b) c)) *)
(* Goal: Derivable (@cons form (subst_form j b (vimp l (Imp (Imp (Atom a) (Atom j)) c))) (@cons form (subst_form j b (vimp l (Imp (Atom a) (Imp b (Atom j))))) context)) goal *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply sound0.
(* Goal: in_gamma (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma) work (vimp (@cons Int a l) (Imp b (Atom j))) *)
(* Goal: forces_t k x *)
apply in_gamma_cons_gamma_head.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite <- (subst_form_below j b goal); try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite <- (subst_list_below j b context); try assumption.
change
  (Derivable
     (subst_list j b
        (vimp l (Imp (Imp (Atom a) (Atom j)) c)
         :: vimp l (Imp (Atom a) (Imp b (Atom j))) :: context))
     (subst_form j b goal)) in |- *.
(* Goal: Derivable (subst_list j b (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp l (Imp (Atom a) (Imp b (Atom j)))) context))) (subst_form j b goal) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply derivable_subst; assumption.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
clear minimal0 sound0 below_context below_gamma below_goal.
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : forall _ : forces_t k goal, False), search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros k k_is_mon k_forces_gamma k_notforces_goal.
(* Goal: search_spec_aux goal (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work context *)
(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply refutable with k; try assumption.
apply
 forces_gamma_cons_gamma_weak2
  with
    (vimp l (Imp (Imp (Atom a) (Atom j)) c))
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
    (vimp (a :: l) (Imp b (Atom j))); try assumption.
(* Goal: forall (_ : forces_t k (vimp l (Imp (Imp (Atom a) (Atom j)) c))) (_ : forces_t k (vimp (@cons Int a l) (Imp b (Atom j)))), forces_t k (vimp l (Imp (Imp (Atom a) b) c)) *)
intros forces1 forces2.
apply
 forces_vimp2
  with (Imp (Imp (Atom a) (Atom j)) c) (Imp (Atom a) (Imp b (Atom j)));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k) (_ : forces_t2 k k' (Imp (Imp (Atom a) (Atom j)) c)) (_ : forces_t2 k k' (Imp (Atom a) (Imp b (Atom j)))), forces_t2 k k' (Imp (Imp (Atom a) b) c) *)
intros k' suc1 forces_ajc forces_abj.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
unfold forces_t2 in |- *; simpl in |- *.
(* Goal: forall (k'0 : kripke_tree) (_ : Suc k'0 k) (_ : Suc k'0 k') (_ : forall (k' : kripke_tree) (_ : Suc k' k) (_ : Suc k' k'0) (_ : forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' a), forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' b), forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k'0 c *)
intros k'' suc2 suc3.
(* Goal: forall _ : forall (k' : kripke_tree) (_ : Suc k' k) (_ : Suc k' k'') (_ : forces0_t (Atms k') a), forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' b, forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k'' c *)
change (forces_t2 k k'' (Imp (Atom a) b) -> forces_t2 k k'' c) in |- *.
(* Goal: forall _ : forces_t2 k k'' (Imp a b), forces_t2 k k'' c *)
intros forces_ab.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply (forces_ajc k''); try assumption.
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k) (_ : Suc k' k'') (_ : forces0_t (Atms k') j), (fix forces (A : Set) (World : forall _ : A, Type) (le : forall (_ : A) (_ : A), Type) (forces0 : forall (_ : A) (_ : Int), Prop) (k : A) (a : form) {struct a} : Prop := match a with | Falsum => False | Atom i => forces0 k i | AndF a0 a1 => and (forces A World le forces0 k a0) (forces A World le forces0 k a1) | OrF a0 a1 => or (forces A World le forces0 k a0) (forces A World le forces0 k a1) | Imp a0 a1 => forall (k'0 : A) (_ : World k'0) (_ : le k k'0) (_ : forces A World le forces0 k'0 a0), forces A World le forces0 k'0 a1 end) kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' b *)
intros k''' suc4 suc5.
(* Goal: forall _ : forces0_t (Atms k''') a, forces0_t (Atms k''') j *)
change (forces_t2 k k''' (Atom a) -> forces_t2 k k''' (Atom j)) in |- *.
(* Goal: forall _ : forces_t2 k k''' (Atom a), forces_t2 k k''' (Atom j) *)
intros forces_a.
(* Goal: forces_t2 k k''' (Atom j) *)
generalize (forces_abj k''' suc4).
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: forall _ : forall (_ : Suc k''' k') (_ : forces0_t (Atms k''') a) (k' : kripke_tree) (_ : Suc k' k) (_ : Suc k' k''') (_ : (fix forces (A : Set) (World : forall _ : A, Type) (le : forall (_ : A) (_ : A), Type) (forces0 : forall (_ : A) (_ : Int), Prop) (k : A) (a : form) {struct a} : Prop := match a with | Falsum => False | Atom i => forces0 k i | AndF a0 a1 => and (forces A World le forces0 k a0) (forces A World le forces0 k a1) | OrF a0 a1 => or (forces A World le forces0 k a0) (forces A World le forces0 k a1) | Imp a0 a1 => forall (k'0 : A) (_ : World k'0) (_ : le k k'0) (_ : forces A World le forces0 k'0 a0), forces A World le forces0 k'0 a1 end) kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' b), forces0_t (Atms k') j, forces_t2 k k''' (Atom j) *)
fold forces in |- *.
(* Goal: forall _ : forall (_ : Suc k''' k') (_ : forces0_t (Atms k''') a) (k' : kripke_tree) (_ : Suc k' k) (_ : Suc k' k''') (_ : forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' b), forces0_t (Atms k') j, forces_t2 k k''' (Atom j) *)
clear forces_abj; intros forces_abj.
(* Goal: forces_t2 k k''' (Atom j) *)
unfold forces_t2 in |- *.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_abj; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
unfold Suc in |- *; apply succs_trans with k''; try assumption.
(* Goal: Suc k''' k''' *)
(* Goal: forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k''' b *)
unfold Suc in |- *; apply successor_refl.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_ab; try assumption.


(* Goal: below_form goal j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
clear minimal0 sound0.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_list (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply below_cons_list.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp_split.
(* Goal: forall (i : Int) (_ : @In Int i l), Less i j1 *)
(* Goal: below_form (Imp (Imp (Atom a) (Atom j)) c) j1 *)
(* Goal: below_list (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma) j1 *)
(* Goal: below_list (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
intros i0 in0; apply less_trans with j.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_l; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_list (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply below_cons_list.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp_split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros i0 in0; apply less_trans with j; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_l; assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_list_less_below_list with j; assumption.
(* Goal: below_list (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply below_cons_list.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp_split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros i0 in0; apply less_trans with j; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_l; assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_list (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) j1 *)
(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply below_cons_list.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp_split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros i0 in0; apply less_trans with j; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_l; assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_list_less_below_list with j; assumption.

(* Goal: sound (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
clear minimal0 below_context below_gamma below_goal.
(* Goal: sound (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma) work (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply sound_cons_gamma_cons_context.
(* Goal: sound (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma) work (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context) *)
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
apply sound_cons_gamma_cons_context.
apply sound_cons_gamma_tail with (vimp l (Imp (Imp (Atom a) b) c));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 assumption.
(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
clear sound0 below_context below_gamma below_goal below_b below_a.

(* Goal: minimal (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context)) *)
unfold minimal in |- *.
(* Goal: forall (a0 : form) (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work k) (_ : @In form a0 (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) context))), forces_t k a0 *)
intros x k k_is_mon k_forces_gamma in_x.
(* Goal: forces_t k x *)
inversion_clear in_x.
(* Goal: forces_t k x *)
(* Goal: forces_t k x *)
 rewrite <- H; clear H x.
(* Goal: forces_t k (vimp (@cons Int a l) (Imp b (Atom j))) *)
(* Goal: forces_t k x *)
apply k_forces_gamma.
(* Goal: in_gamma (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma) work (vimp (@cons Int a l) (Imp b (Atom j))) *)
(* Goal: forces_t k x *)
apply in_gamma_cons_gamma_head.
(* Goal: forces_t k x *)
inversion_clear H.
(* Goal: forces_t k x *)
(* Goal: forces_t k x *)
 rewrite <- H0; clear H0 x.
(* Goal: forces_t k (vimp (@cons Int a l) (Imp b (Atom j))) *)
(* Goal: forces_t k x *)
apply k_forces_gamma.
(* Goal: in_gamma (@cons form (vimp l (Imp (Imp (Atom a) (Atom j)) c)) (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma)) work (vimp (@cons Int a l) (Imp b (Atom j))) *)
(* Goal: forces_t k x *)
apply in_gamma_cons_gamma_tail.
(* Goal: in_gamma (@cons form (vimp (@cons Int a l) (Imp b (Atom j))) gamma) work (vimp (@cons Int a l) (Imp b (Atom j))) *)
(* Goal: forces_t k x *)
apply in_gamma_cons_gamma_head.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply minimal0; try assumption.
(* Goal: forces_gamma (@cons form (vimp l (Imp (Imp (Atom a) b) c)) gamma) work k *)
clear H0 x.
apply
 forces_gamma_cons_gamma_weak2
  with
    (vimp l (Imp (Imp (Atom a) (Atom j)) c))
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
    (vimp (a :: l) (Imp b (Atom j))); try assumption.
(* Goal: forall (_ : forces_t k (vimp l (Imp (Imp (Atom a) (Atom j)) c))) (_ : forces_t k (vimp (@cons Int a l) (Imp b (Atom j)))), forces_t k (vimp l (Imp (Imp (Atom a) b) c)) *)
intros forces1 forces2.
apply
 forces_vimp2
  with (Imp (Imp (Atom a) (Atom j)) c) (Imp (Atom a) (Imp b (Atom j)));
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 try assumption.
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k) (_ : forces_t2 k k' (Imp (Imp (Atom a) (Atom j)) c)) (_ : forces_t2 k k' (Imp (Atom a) (Imp b (Atom j)))), forces_t2 k k' (Imp (Imp (Atom a) b) c) *)
intros k' suc1 forces_ajc forces_abj.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
unfold forces_t2 in |- *; simpl in |- *.
(* Goal: forall (k'0 : kripke_tree) (_ : Suc k'0 k) (_ : Suc k'0 k') (_ : forall (k' : kripke_tree) (_ : Suc k' k) (_ : Suc k' k'0) (_ : forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' a), forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' b), forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k'0 c *)
intros k'' suc2 suc3.
(* Goal: forall _ : forall (k' : kripke_tree) (_ : Suc k' k) (_ : Suc k' k'') (_ : forces0_t (Atms k') a), forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' b, forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k'' c *)
change (forces_t2 k k'' (Imp (Atom a) b) -> forces_t2 k k'' c) in |- *.
(* Goal: forall _ : forces_t2 k k'' (Imp a b), forces_t2 k k'' c *)
intros forces_ab.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply (forces_ajc k''); try assumption.
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k) (_ : Suc k' k'') (_ : forces0_t (Atms k') j), (fix forces (A : Set) (World : forall _ : A, Type) (le : forall (_ : A) (_ : A), Type) (forces0 : forall (_ : A) (_ : Int), Prop) (k : A) (a : form) {struct a} : Prop := match a with | Falsum => False | Atom i => forces0 k i | AndF a0 a1 => and (forces A World le forces0 k a0) (forces A World le forces0 k a1) | OrF a0 a1 => or (forces A World le forces0 k a0) (forces A World le forces0 k a1) | Imp a0 a1 => forall (k'0 : A) (_ : World k'0) (_ : le k k'0) (_ : forces A World le forces0 k'0 a0), forces A World le forces0 k'0 a1 end) kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' b *)
intros k''' suc4 suc5.
(* Goal: forall _ : forces0_t (Atms k''') a, forces0_t (Atms k''') j *)
change (forces_t2 k k''' (Atom a) -> forces_t2 k k''' (Atom j)) in |- *.
(* Goal: forall _ : forces_t2 k k''' (Atom a), forces_t2 k k''' (Atom j) *)
intros forces_a.
(* Goal: forces_t2 k k''' (Atom j) *)
generalize (forces_abj k''' suc4).
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: forall _ : forall (_ : Suc k''' k') (_ : forces0_t (Atms k''') a) (k' : kripke_tree) (_ : Suc k' k) (_ : Suc k' k''') (_ : (fix forces (A : Set) (World : forall _ : A, Type) (le : forall (_ : A) (_ : A), Type) (forces0 : forall (_ : A) (_ : Int), Prop) (k : A) (a : form) {struct a} : Prop := match a with | Falsum => False | Atom i => forces0 k i | AndF a0 a1 => and (forces A World le forces0 k a0) (forces A World le forces0 k a1) | OrF a0 a1 => or (forces A World le forces0 k a0) (forces A World le forces0 k a1) | Imp a0 a1 => forall (k'0 : A) (_ : World k'0) (_ : le k k'0) (_ : forces A World le forces0 k'0 a0), forces A World le forces0 k'0 a1 end) kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' b), forces0_t (Atms k') j, forces_t2 k k''' (Atom j) *)
fold forces in |- *.
(* Goal: forall _ : forall (_ : Suc k''' k') (_ : forces0_t (Atms k''') a) (k' : kripke_tree) (_ : Suc k' k) (_ : Suc k' k''') (_ : forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' b), forces0_t (Atms k') j, forces_t2 k k''' (Atom j) *)
clear forces_abj; intros forces_abj.
(* Goal: forces_t2 k k''' (Atom j) *)
unfold forces_t2 in |- *.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_abj; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
unfold Suc in |- *; apply succs_trans with k''; try assumption.
(* Goal: Suc k''' k''' *)
(* Goal: forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k''' b *)
unfold Suc in |- *; apply successor_refl.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_ab; try assumption.
Qed.





Lemma rule_a_imp_b_imp_c_gamma :
 forall (goal : form) (l : list Int) (a b c : form) 
   (gamma : flist) (work : nf_list) (context : flist) 
   (j j1 : Int),
 Less j j1 ->
 search_spec goal
   (vimp l (Imp (Imp (Atom j) b) c) :: Imp (Atom j) a :: gamma) work
   (vimp l (Imp (Imp (Atom j) b) c) :: Imp (Atom j) a :: context) j1 ->
 search_spec goal (vimp l (Imp (Imp a b) c) :: gamma) work context j.
(* Goal: forall (goal : form) (l : list Int) (a b c : form) (gamma : flist) (work : nf_list) (context : flist) (j j1 : Int) (_ : Less j j1) (_ : search_spec goal (@cons form (vimp l (Imp (Imp (Atom j) b) c)) (@cons form (Imp (Atom j) a) gamma)) work (@cons form (vimp l (Imp (Imp (Atom j) b) c)) (@cons form (Imp (Atom j) a) context)) j1), search_spec goal (@cons form (vimp l (Imp (Imp a b) c)) gamma) work context j *)
intros goal l a b c gamma work context j j1 less1 spec0.
apply
 search_spec_subst_gamma_pos
  with (j1 := j1) (a := a) (b := vimp l (Imp (Imp (Atom j) b) c));
 try assumption; clear spec0.
(* Goal: forall _ : below_form (vimp l (Imp (Imp a b) c)) j, and (below_form a j) (and (below_form (vimp l (Imp (Imp (Atom j) b) c)) j1) (@eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros below_x.
(* Goal: and (below_form a j) (and (below_form (vimp l (Imp (Imp (Atom j) b) c)) j1) (@eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
generalize (below_vimp_tail j l (Imp (Imp a b) c) below_x).
(* Goal: forall _ : forall (i : Int) (_ : @In Int i l), Less i j, and (below_form a j) (and (below_form (vimp l (Imp (Imp (Atom j) b) c)) j1) (@eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
generalize (below_vimp_head j l (Imp (Imp a b) c) below_x); clear below_x.
(* Goal: forall (_ : below_form (Imp (Imp a b) c) j) (_ : forall (i : Int) (_ : @In Int i l), Less i j), and (below_form a j) (and (below_form (vimp l (Imp (Imp (Atom j) b) c)) j1) (@eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros below_x below_l.
(* Goal: and (below_form a j) (and (below_form (vimp l (Imp (Imp (Atom j) b) c)) j1) (@eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
elim below_x; clear below_x; intros below_ab below_c.
(* Goal: and (below_form a j) (and (below_form (vimp l (Imp (Imp (Atom j) b) c)) j1) (@eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)))) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
elim below_ab; clear below_ab; intros below_a below_b.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_vimp_split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros i0 in0; apply less_trans with j; try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_l; assumption.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Imp (Atom j) b) j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
split.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
assumption.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply below_form_less_below_form with j; assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_vimp_head j a l (Imp (Imp (Atom j) b) c)); try assumption.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
simpl in |- *.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_form_below j a b); try assumption.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (subst_form_below j a c); try assumption.
(* Goal: @eq form (vimp l (Imp (Imp (if equal_dec j j then a else Atom j) b) c)) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
 rewrite (equal_dec_refl j form a (Atom j)).
(* Goal: @eq form (vimp l (Imp (Imp a b) c)) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
trivial.

(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
intros k k_is_mon forces1 forces2.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply forces_vimp with (Imp (Imp (Atom j) b) c); try assumption.
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k) (_ : forces_t2 k k' (Imp (Imp (Atom j) b) c)), forces_t2 k k' (Imp (Imp a b) c) *)
intros k' suc1 forces_jbc.
(* Goal: @eq form (vimp l (subst_form j a (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
unfold forces_t2 in |- *; simpl in |- *.
(* Goal: forall (k'0 : kripke_tree) (_ : Suc k'0 k) (_ : Suc k'0 k') (_ : forall (k' : kripke_tree) (_ : Suc k' k) (_ : Suc k' k'0) (_ : forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' a), forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' b), forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k'0 c *)
intros k'' suc2 suc3.
(* Goal: forall _ : forall (k' : kripke_tree) (_ : Suc k' k) (_ : Suc k' k'') (_ : forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' a), forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' b, forces kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k'' c *)
change (forces_t2 k k'' (Imp a b) -> forces_t2 k k'' c) in |- *.
(* Goal: forall _ : forces_t2 k k'' (Imp a b), forces_t2 k k'' c *)
intros forces_ab.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply (forces_jbc k''); try assumption.
(* Goal: forall (k' : kripke_tree) (_ : Suc k' k) (_ : Suc k' k'') (_ : forces0_t (Atms k') j), (fix forces (A : Set) (World : forall _ : A, Type) (le : forall (_ : A) (_ : A), Type) (forces0 : forall (_ : A) (_ : Int), Prop) (k : A) (a : form) {struct a} : Prop := match a with | Falsum => False | Atom i => forces0 k i | AndF a0 a1 => and (forces A World le forces0 k a0) (forces A World le forces0 k a1) | OrF a0 a1 => or (forces A World le forces0 k a0) (forces A World le forces0 k a1) | Imp a0 a1 => forall (k'0 : A) (_ : World k'0) (_ : le k k'0) (_ : forces A World le forces0 k'0 a0), forces A World le forces0 k'0 a1 end) kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k' b *)
intros k''' suc4 suc5.
(* Goal: forall _ : forces0_t (Atms k''') j, (fix forces (A : Set) (World : forall _ : A, Type) (le : forall (_ : A) (_ : A), Type) (forces0 : forall (_ : A) (_ : Int), Prop) (k : A) (a : form) {struct a} : Prop := match a with | Falsum => False | Atom i => forces0 k i | AndF a0 a1 => and (forces A World le forces0 k a0) (forces A World le forces0 k a1) | OrF a0 a1 => or (forces A World le forces0 k a0) (forces A World le forces0 k a1) | Imp a0 a1 => forall (k' : A) (_ : World k') (_ : le k k') (_ : forces A World le forces0 k' a0), forces A World le forces0 k' a1 end) kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k''' b *)
change (forces_t2 k k''' (Atom j) -> forces_t2 k k''' b) in |- *.
(* Goal: forall _ : forces_t2 k k''' (Atom j), forces_t2 k k''' b *)
intros forces_j.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply (forces_ab k'''); try assumption.
(* Goal: (fix forces (A : Set) (World : forall _ : A, Type) (le : forall (_ : A) (_ : A), Type) (forces0 : forall (_ : A) (_ : Int), Prop) (k : A) (a : form) {struct a} : Prop := match a with | Falsum => False | Atom i => forces0 k i | AndF a0 a1 => and (forces A World le forces0 k a0) (forces A World le forces0 k a1) | OrF a0 a1 => or (forces A World le forces0 k a0) (forces A World le forces0 k a1) | Imp a0 a1 => forall (k' : A) (_ : World k') (_ : le k k') (_ : forces A World le forces0 k' a0), forces A World le forces0 k' a1 end) kripke_tree (fun k0 : kripke_tree => Suc k0 k) (fun k0 k1 : kripke_tree => Suc k1 k0) (fun (k0 : kripke_tree) (i : Int) => forces0_t (Atms k0) i) k''' a *)
change (forces_t2 k k''' a) in |- *.
(* Goal: below_form (Atom j) j1 *)
(* Goal: below_form b j1 *)
(* Goal: below_form c j1 *)
(* Goal: @eq form (subst_form j a (vimp l (Imp (Imp (Atom j) b) c))) (vimp l (Imp (Imp a b) c)) *)
(* Goal: forall (k : kripke_tree) (_ : Is_Monotone_kripke_tree k) (_ : forces_t k (vimp l (Imp (Imp (Atom j) b) c))) (_ : forces_t k (Imp (Atom j) a)), forces_t k (vimp l (Imp (Imp a b) c)) *)
apply (forces2 k'''); assumption.
Qed.
