(* 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.
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.
intros below_c.
generalize (below_vimp_tail j l (Imp a b) below_c).
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.
split.
assumption.
split.
apply below_vimp_split; try assumption.
intros i in0.
apply less_trans with j; try assumption.
apply below_l; assumption.
split.
apply below_form_less_below_form with j; assumption.
assumption.
rewrite (subst_vimp_head j b l (Imp a (Atom j))); try assumption.
simpl in |- *.
rewrite (equal_dec_refl j form b (Atom j)).
rewrite (subst_form_below j b a); try assumption.
trivial.
intros k k_is_mon forces1 forces2.
apply forces_vimp with (Imp a (Atom j)); try assumption.
intros k' suc1 forces_j.
unfold forces_t2 in |- *; simpl in |- *.
intros k'' suc2 suc3 forces_a.
apply (forces2 k''); try assumption.
apply (forces_j k''); assumption.
Qed.
(****************************************************)
(*                                                  *)
(* rules for   goal = ...                           *)
(*                                                  *)
(****************************************************)
intros gamma work context i j less_ij spec0.
unfold search_spec in |- *.
intros below_goal below_gamma below_context sound0 minimal0.
elim spec0; clear spec0; try assumption.
intros derivable_i.
apply derivable.
apply snd_order_inst with i; assumption.
intros k k_is_mon k_forces_gamma k_notforces_i.
apply refutable with k; try assumption.
trivial.
apply below_list_less_below_list with i; assumption.
apply below_list_less_below_list with i; assumption.
Qed.
intros a b gamma work context j spec0.
unfold search_spec in |- *.
intros below_goal below_gamma below_context sound0 minimal0.
elim below_goal; clear below_goal; intros below_a below_b.
elim spec0; clear spec0; try assumption.
intros derivable_i.
apply derivable.
elim derivable_i; clear derivable_i; intros t der_t.
apply Derivable_Intro with (Abs a t).
apply ImpIntro; assumption.
intros k k_is_mon k_forces_gamma k_notforces_b.
apply refutable with k; try assumption.
apply forces_gamma_cons_gamma_tail with a; assumption.
intros forces_ab.
apply k_notforces_b.
apply forces_a_a_imp_b__forces_b_t with a; try assumption.
apply forces_gamma_cons_gamma_head with gamma work; assumption.
apply below_cons_list; assumption.
apply below_cons_list; assumption.
apply sound_cons_gamma_cons_context; assumption.
apply minimal_cons_gamma_cons_context; assumption.
Qed.
intros a gamma work context j j1 less1 spec0.
unfold search_spec in |- *.
intros below_goal below_gamma below_context sound0 minimal0.
elim spec0; clear spec0; try assumption.
intros der.
clear minimal0 sound0.
apply derivable.
apply derivable_cut with (Imp a a).
apply derivable_a_imp_a.
apply
derivable_eq
with (subst_list j a (Imp a (Atom j) :: context)) (subst_form j a (Atom j)).
simpl in |- *.
rewrite (subst_form_below j a a); try assumption.
rewrite (subst_list_below j a context); try assumption.
rewrite (equal_dec_refl j form a (Atom j)).
trivial.
simpl in |- *.
apply equal_dec_refl.
apply derivable_subst; assumption.
clear minimal0 sound0.
intros k k_is_mon k_forces_gamma k_notforces_j.
apply refutable with k; try assumption.
apply forces_gamma_cons_gamma_tail with (Imp a (Atom j)); assumption.
intros forces_a.
apply k_notforces_j.
apply forces_a_a_imp_b__forces_b_t with a; try assumption.
apply forces_gamma_cons_gamma_head with gamma work; assumption.
apply below_cons_list.
split.
apply below_form_less_below_form with j; assumption.
assumption.
apply below_list_less_below_list with j; assumption.
apply below_cons_list.
split.
apply below_form_less_below_form with j; assumption.
assumption.
apply below_list_less_below_list with j; assumption.
apply sound_cons_gamma_cons_context; assumption.
apply minimal_cons_gamma_cons_context; assumption.
Qed.
(***********************************************************************)
(***********************************************************************)
(*****************************************************)
(* rules for   ...(cons (vimp l (AndF a b)) gamma)... *)
intros goal l b0 b1 gamma work context j spec0.
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_cons_gamma_weak2 with (vimp l b0) (vimp l b1);
try assumption.
intros forces_ab0 forces_ab1.
apply forces_vimp2 with b0 b1; try assumption.
intros; split; assumption.
apply below_list_weak2 with (vimp l (AndF b0 b1)); try assumption.
intros below_ab0b1.
split.
apply below_vimp with (AndF b0 b1); try assumption.
intros j' below_b0b1; elim below_b0b1; clear below_b0b1; intros; assumption.
apply below_vimp with (AndF b0 b1); try assumption.
intros j' below_b0b1; elim below_b0b1; clear below_b0b1; intros; assumption.
apply sound_cons_gamma_weak2 with (vimp l (AndF b0 b1)); try assumption.
intros der.
split.
apply derivable_vimp with (AndF b0 b1); try assumption.
intros context' der'.
apply (derivable_a_and_b__derivable_a b0 b1 context'); assumption.
apply derivable_vimp with (AndF b0 b1); try assumption.
intros context' der'.
apply (derivable_a_and_b__derivable_b b0 b1 context'); assumption.
apply minimal_cons_gamma_weak2 with (vimp l (AndF b0 b1)); try assumption.
intros k k_is_mon forces_b0 forces_b1.
apply forces_vimp2 with b0 b1; try assumption.
intros; split; assumption.
Qed.
intros goal l b0 b1 gamma work context j j1 less1 spec0.
apply rule_vimp_a_gamma with j1; try assumption.
apply rule_vimp_conj_gamma; assumption.
Qed.
(****************************************************)
(* rules for   ...(cons (vimp l (OrF a b)) gamma)... *)
intros goal l a gamma work context j spec0.
unfold search_spec in |- *.
intros below_goal below_gamma below_context sound0 minimal0.
elim spec0; clear spec0; try assumption.
intros derivable_i; apply derivable; assumption.
intros k k_is_mon k_forces_gamma k_notforces_goal.
apply refutable with k; try assumption.
apply forces_gamma_cons_gamma_weak with (vimp l a); try assumption.
intros forces_la.
apply forces_vimp with a.
intros; right; assumption.
assumption.
apply below_list_weak with (vimp l (OrF Falsum a)); try assumption.
intros below_x.
apply below_vimp with (OrF Falsum a); try assumption.
intros j0 below_or; elim below_or; intros; assumption.
apply sound_cons_gamma_weak with (vimp l (OrF Falsum a)); try assumption.
intros der.
apply derivable_vimp with (OrF Falsum a); try assumption.
intros context0 der0.
apply derivable_falsum_or_a__derivable_a; assumption.
apply minimal_cons_gamma_weak with (vimp l (OrF Falsum a)); try assumption.
intros k k_is_mon k_forces_la.
apply forces_vimp with a; try assumption.
intros; right; assumption.
Qed.
intros goal l a gamma work context j spec0.
unfold search_spec in |- *.
intros below_goal below_gamma below_context sound0 minimal0.
elim spec0; clear spec0; try assumption.
intros derivable_i; apply derivable; assumption.
intros k k_is_mon k_forces_gamma k_notforces_goal.
apply refutable with k; try assumption.
apply forces_gamma_cons_gamma_weak with (vimp l a); try assumption.
intros forces_la.
apply forces_vimp with a.
intros; left; assumption.
assumption.
apply below_list_weak with (vimp l (OrF a Falsum)); try assumption.
intros below_x.
apply below_vimp with (OrF a Falsum); try assumption.
intros j0 below_or; elim below_or; intros; assumption.
apply sound_cons_gamma_weak with (vimp l (OrF a Falsum)); try assumption.
intros der.
apply derivable_vimp with (OrF a Falsum); try assumption.
intros context0 der0.
apply derivable_a_or_falsum__derivable_a; assumption.
apply minimal_cons_gamma_weak with (vimp l (OrF a Falsum)); try assumption.
intros k k_is_mon k_forces_la.
apply forces_vimp with a; try assumption.
intros; left; assumption.
Qed.
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)));
try assumption.
intros below_c.
generalize (below_vimp_tail j l (OrF (Atom i) a) below_c).
generalize (below_vimp_head j l (OrF (Atom i) a) below_c); clear below_c.
intros below_c below_l; elim below_c; clear below_c; intros below_i below_a.
split.
assumption.
split.
apply below_vimp_split.
intros i0 in0.
apply less_trans with j; try assumption.
apply below_l; assumption.
split.
apply below_form_less_below_form with j; try assumption.
assumption.
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 |- *.
rewrite (subst_form_below j a (Atom i)); 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 (OrF (Atom i) (Atom j)).
intros k' suc1 forces_ij.
elim forces_ij; clear forces_ij.
intros; left; assumption.
intros; right.
change (forces_t2 k k' a) in |- *.
apply (forces2 k'); assumption.
assumption.
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.