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