(* File: Forms.v  (last edited on 27/10/2000) (c) Klaus Weich  *)
Require Export ML_Int.
Require Export My_Nth.
(*******   forms    ***********************************************)
Inductive form : Set :=
| Falsum : form
| Atom : Int -> form
| AndF : form -> form -> form
| OrF : form -> form -> form
| Imp : form -> form -> form.
Definition flist := list form.
Definition fnil := nil (A:=form).
(* vimp qs a := vec(qs) imp a *)
Fixpoint vimp (qs : list Int) : form -> form :=
match qs with
| nil => fun a : form => a
| q :: qs => fun a : form => vimp qs (Imp (Atom q) a)
end.
(*********************************************************************)
(* Substitute (Atom i) by a in b:                                    *)
Fixpoint subst_form (i : Int) (a b : form) {struct b} : form :=
match b with
| Falsum => Falsum
| Atom j => match equal_dec i j with
| left _ => a
| right _ => Atom j
end
| OrF b0 b1 => OrF (subst_form i a b0) (subst_form i a b1)
| AndF b0 b1 => AndF (subst_form i a b0) (subst_form i a b1)
| Imp b0 b1 => Imp (subst_form i a b0) (subst_form i a b1)
end.
Definition subst_list (i : Int) (a : form) (l : flist) :=
map (subst_form i a) l.
intros i g n; elim n; clear n.
intros l a nth; inversion_clear nth.
simpl in |- *.
apply My_NthO.
intros n ih l a nth.
inversion_clear nth.
simpl in |- *.
apply My_NthS.
apply ih.
assumption.
Qed.
(************************************************************************)
Fixpoint below_form (a : form) (i : Int) {struct a} : Prop :=
match a with
| Falsum => True
| Atom j => Less j i
| AndF a0 a1 => below_form a0 i /\ below_form a1 i
| OrF a0 a1 => below_form a0 i /\ below_form a1 i
| Imp a0 a1 => below_form a0 i /\ below_form a1 i
end.
Definition below_list (L : flist) (i : Int) :=
forall a : form, In a L -> below_form a i.
(********************************************************************)
intros a i j.
elim a; clear a.
intros; trivial.
simpl in |- *.
intros i0 less_i0 less_i.
apply less_trans with i; assumption.
intros a ih_a b ih_b below_ab less_ij.
elim below_ab; clear below_ab.
intros below_a below_b.
split.
apply ih_a; assumption.
apply ih_b; assumption.
intros a ih_a b ih_b below_ab less_ij.
elim below_ab; clear below_ab.
intros below_a below_b.
split.
apply ih_a; assumption.
apply ih_b; assumption.
intros a ih_a b ih_b below_ab less_ij.
elim below_ab; clear below_ab.
intros below_a below_b.
split.
apply ih_a; assumption.
apply ih_b; assumption.
Qed.
intros l i j below_l less_ij.
unfold below_list in |- *.
intros a in_a.
apply below_form_less_below_form with i.
apply below_l; assumption.
assumption.
Qed.
intros a l i below_l.
apply below_l.
left; trivial.
Qed.
intros a l i below_l.
unfold below_list in |- *.
intros b in_b.
apply below_l.
right; assumption.
Qed.
intros a l i below_a below_l.
unfold below_list in |- *.
intros b in_b.
inversion_clear in_b.
rewrite <- H; assumption.
apply below_l; assumption.
Qed.
intros l a b i below_ab below_l.
unfold below_list in |- *.
intros x in_x.
inversion_clear in_x.
rewrite <- H; clear H x.
apply below_ab.
apply below_l.
left; trivial.
apply below_l.
right; assumption.
Qed.
intros l a b c i below_abc below_l.
elim below_abc; clear below_abc.
intros below_b below_c.
unfold below_list in |- *.
intros x in_x.
inversion_clear in_x.
rewrite <- H; assumption.
inversion_clear H.
rewrite <- H0; assumption.
apply below_l.
right; assumption.
apply below_l.
left; trivial.
Qed.
(********************************************************************)
intros i g a; elim a; clear a.
trivial.
intros j.
simpl in |- *.
intros less_j.
elim (equal_dec i j).
intros equal_j.
elimtype False.
apply less_irrefl with i.
apply equal_less_less with j; assumption.
trivial.
simpl in |- *.
intros a ih_a b ih_b below_ab.
rewrite ih_a.
rewrite ih_b.
trivial.
elim below_ab; trivial.
elim below_ab; trivial.
simpl in |- *.
intros a ih_a b ih_b below_ab.
rewrite ih_a.
rewrite ih_b.
trivial.
elim below_ab; trivial.
elim below_ab; trivial.
simpl in |- *.
intros a ih_a b ih_b below_ab.
rewrite ih_a.
rewrite ih_b.
trivial.
elim below_ab; trivial.
elim below_ab; trivial.
Qed.
intros i g l; elim l; clear l.
trivial.
simpl in |- *; intros a l ih below_l.
rewrite ih.
rewrite (subst_form_below i g a).
trivial.
apply (below_l a).
left; trivial.
unfold below_list in |- *.
intros b in_l.
apply (below_l b).
right; assumption.
Qed.
intros j l.
elim l; clear l.
intros a b below_ab below_a.
apply below_ab; assumption.
simpl in |- *; intros i l ih a b below_ab below_a.
apply ih with (a := Imp (Atom i) a); try assumption.
intros j' below_ia.
elim below_ia; clear below_ia; intros below_i below_a0.
split.
assumption.
apply below_ab; assumption.
Qed.
intros k l.
elim l; clear l.
intros a b c below_abc below_a below_b.
apply below_abc; assumption.
simpl in |- *; intros i l ih a b c below_abc below_a below_b.
apply ih with (a := Imp (Atom i) a) (b := Imp (Atom i) b); try assumption.
intros j' below_ia below_ib.
elim below_ia; clear below_ia; intros below_i below_a0.
elim below_ib; clear below_ib; intros below_i0 below_b0.
split.
assumption.
apply below_abc; assumption.
Qed.
intros j l; elim l; clear l.
intros a below_la; assumption.
intros i l ih a below_la.
elim (ih (Imp (Atom i) a)); clear ih.
intros; assumption.
assumption.
Qed.
intros j l; elim l; clear l.
intros; assumption.
intros i l ih a below_i below_a.
apply ih with (a := Imp (Atom i) a).
intros i0 in0.
apply below_i.
right; assumption.
split.
simpl in |- *.
apply below_i.
left; trivial.
assumption.
Qed.
intros j l; elim l; clear l.
intros a below_la i0 in0; inversion_clear in0.
simpl in |- *; intros i l ih a below_la i0 in0.
inversion_clear in0.
rewrite <- H; clear H i0.
elim (below_vimp_head j l (Imp (Atom i) a) below_la).
intros; assumption.
apply ih with (a := Imp (Atom i) a); assumption.
Qed.

Lemma subst_vimp_head :
forall (j : Int) (a : form) (l : list Int) (b : form),
(forall i : Int, In i l -> Less i j) ->
subst_form j a (vimp l b) = vimp l (subst_form j a b).