Section gram4.
Variable X V1 R1 : Ensf.
Variable S1 : Elt.
Variable V2 R2 : Ensf.
Variable S2 : Elt.
Variable S : Elt.
Let C := Gunion_disj_p V1 R1 S1 V2 R2 S2 S.
Let Vu := fst C.
Let C' := snd C.
Let Ru := fst C'.
Let Su := snd C'.
prolog [ isGram2 union_inter ] 5.
(*Intro G1. Intro G2. Apply union_inter. Apply isGram2 with R1 S1; Assumption. Apply isGram2 with R2 S2; Assumption.*)
Qed.
intros G_1 G_2 N_dans_S_X.
unfold inter in |- *.
split.
auto.
split.
auto.
intros x dans_x_X dans_x_Vu.
absurd (dans x X).
cut (S = x :>Elt \/ dans x (union V1 V2)). (**)
intro temp; elim temp; clear temp.
intros egal_S_x.
rewrite <- egal_S_x; assumption.
intro dans_x_V1_u_V2.
prolog [ inter_X_V1_u_V2 sym_inter inter_dans ] 4.
(*Apply inter_dans with (union V1 V2). Apply sym_inter. Apply inter_X_V1_u_V2;Assumption.  Assumption.*)
(**)auto.  assumption. Qed.  Lemma Gunion_disj_Regles : isGram X V1 R1 S1 -> isGram X V2 R2 S2 -> Regles X Vu Ru. intros. unfold Vu, Ru in |- *; simpl in |- *. apply Regles_add. apply Regles_add. apply Regles_add2. change (Regles X (fst (Gunion V1 R1 V2 R2)) (snd (Gunion V1 R1 V2 R2))) in |- *. prolog [ Gunion_Regles ] 2. (*Apply Gunion_Regles with S1 S2;Auto.*)
auto.
apply inmonoid_cons.
trivial.
cut (dans S2 V2);
[ auto
| prolog [ isGram3 ] 2(*Apply isGram3 with X R2;Assumption*) ].
auto.
apply inmonoid_cons.
trivial.
cut (dans S1 V1);
[ auto
| prolog [ isGram3 ] 2 (*Apply isGram3 with X R1;Assumption*) ].
Qed.
intros N_dans_X N_dans_V1 N_dans_V2 Re_1 Re_2 inter_X_V1_V2_empty u v
Der_Ru_u.
elim Der_Ru_u.
intros u0 v0 A dans_couple_Ru inmon_cons_A_v0.
apply Derive1.
cut
(couple S (word (cons S1 nil)) = couple A (word u0) :>Elt \/
dans (couple A (word u0))
(add (couple S (word (cons S2 nil))) (union R1 R2))). (**)
intro temp; elim temp; clear temp.
intro egal_S.
absurd (dans S X \/ dans S V1).
red in |- *.
intro temp; elim temp; clear temp.
exact N_dans_X.
exact N_dans_V1.
apply dans_union.
replace S with A.
prolog [ inmonoid_cons_inv2 ] 2.
(*Apply inmonoid_cons_inv2 with v0;Assumption.*)
injection egal_S; auto.
intro dans_couple_add.
cut
(couple S (word (cons S2 nil)) = couple A (word u0) :>Elt \/
dans (couple A (word u0)) (union R1 R2)). (***)
intro temp; elim temp; clear temp.
intro egal_S.
absurd (dans S X \/ dans S V1).
red in |- *.
intro temp; elim temp; auto.
apply dans_union.
replace S with A.
prolog [ inmonoid_cons_inv2 ] 2.
(*Apply inmonoid_cons_inv2 with v0;Assumption.*)
injection egal_S; auto.
intro dans_couple_union.
cut (dans (couple A (word u0)) R1 \/ dans (couple A (word u0)) R2). (****)
(*Intuition.*)intro temp; elim temp; clear temp. auto. intro dans_R2. absurd (inter (union X V1) V2 empty). red in |- *. unfold inter in |- *. (*Intuition.*)intro temp; elim temp; clear temp. intros HH temp; elim temp; clear temp; intros HHH HHHH. (*Intros.*)
prolog [ Regles_inv1 inmonoid_cons_inv2 dans_empty_imp_P ] 4.
(*Intro temp;Elim temp;Clear temp. Intros incl_empty_X_V1 temp;Elim temp;Clear temp. Intros incl_empty_V2 imp.  Apply dans_empty_imp_P with A. Apply imp. Apply inmonoid_cons_inv2 with v0;Assumption. Apply Regles_inv1 with X R2 (word u0); Assumption.*)
assumption.
(****)auto.  (***)auto.  (**)auto.  prolog [ inmonoid_cons_inv Derive2 ] 10. (*Intros u0 v0 x Der_Ru imp inmon_cons_x_u0. Apply Derive2. Apply imp. Apply inmonoid_cons_inv with x. Assumption.*)
Qed.
prolog [ in_mon_X_Der_imp_inmon_X ] 7.
(*Intros. Apply in_mon_X_Der_imp_inmon_X with R1 u;Assumption.*)
Qed.
prolog
[ isGram2 isGram4 inter_union inmon_Der_imp_Der_d inmon_Der_imp_inmon_R1_d ]
15.
(*Intros N_dans_X N_dans_V1 N_dans_V2 u v G_R1 G_R2 inter_V1_V2_empty inmon_X_V1_u Der_Ru_u_v. Apply inmon_Der_imp_inmon_R1_d with u. Apply isGram4 with S1;Assumption.  Apply inmon_Der_imp_Der_d.  Assumption.  Assumption.  Assumption.  Apply isGram4 with S1;Assumption.  Apply isGram4 with S2;Assumption.  Apply inter_union. Apply isGram2 with R2 S2; Assumption. Assumption.  Assumption.  Assumption.  Assumption.*)
Qed.
unfold Derivestar in |- *.
intros N_dans_X N_dans_V1 N_dans_V2 G_1 G_2 inter_V1_V2_empty u v
Derivestar_Ru.
pattern u, v in |- *.
apply Derivestar_Ru.
auto.
intros u0 v0 w Der_Ru inmon_v0_imp_Rstar_R1_v0 inmon_u0.
apply Rstar_R with v0;
prolog
[ isGram2 inter_union isGram4 inmon_Der_imp_Der_d inmon_Der_imp_inmon_d ]
4.
(*Apply Rstar_R with v0 inmon_v0_imp_Rstar_R1_v0 inmon_Der_imp_inmon_d. Apply inmon_Der_imp_Der_d. Assumption. Assumption. Assumption. Apply isGram4 with S1;Assumption. Apply isGram4 with S2;Assumption. Apply inter_union. Apply isGram2 with R2 S2; Assumption. Assumption. Assumption. Assumption.  Apply inmon_v0_imp_Rstar_R1_v0. Apply inmon_Der_imp_inmon_d with u0;Assumption.*)
Qed.
intros N_dans_X N_dans_V1 N_dans_V2 Re_1 Re_2 inter_X_V2_V1_empty u v
Der_Ru_u.
elim Der_Ru_u.
intros u0 v0 A dans_couple_Ru inmon_cons_A_v0.
apply Derive1.
cut
(couple S (word (cons S1 nil)) = couple A (word u0) :>Elt \/
dans (couple A (word u0))
(add (couple S (word (cons S2 nil))) (union R1 R2))). (**)
intro temp; elim temp; clear temp.
intro egal_S.
absurd (dans S X \/ dans S V2).
red in |- *.
intuition.
apply dans_union.
replace S with A.
prolog [ inmonoid_cons_inv2 ] 2.
(*Apply inmonoid_cons_inv2 with v0;Assumption.*)
injection egal_S; auto.
intro dans_couple_add.
cut
(couple S (word (cons S2 nil)) = couple A (word u0) :>Elt \/
dans (couple A (word u0)) (union R1 R2)). (***)
intro temp; elim temp; clear temp.
intro egal_S.
absurd (dans S X \/ dans S V2).
red in |- *.
intuition.
apply dans_union.
replace S with A.
prolog [ inmonoid_cons_inv2 ] 2.
(*Apply inmonoid_cons_inv2 with v0;Assumption.*)
injection egal_S; auto.
intro dans_couple_union.
cut (dans (couple A (word u0)) R1 \/ dans (couple A (word u0)) R2). (****)
(*Intuition.*) intro temp; elim temp; clear temp. intro dans_R1. absurd (inter (union X V2) V1 empty). red in |- *. unfold inter in |- *. (*Intuition.*) intro temp; elim temp; clear temp. intros inc_empt temp; elim temp; clear temp. intros incl_empty_V1 imp_dans_empty. apply dans_empty_imp_P with A. apply imp_dans_empty; prolog [ Regles_inv1 inmonoid_cons_inv2 ] 4. (*Intro temp;Elim temp;Clear temp. Intros incl_empty_X_V2 temp;Elim temp;Clear temp. Intros incl_empty_V1 imp. Apply dans_empty_imp_P with A. Apply imp. Apply inmonoid_cons_inv2 with v0;Assumption. Apply Regles_inv1 with X R1 (word u0); Assumption.*)
assumption.
trivial.
(****)auto.  (***)auto.  (**)auto.  prolog [ inmonoid_cons_inv Derive2 ] 10. (*Intros u0 v0 x Der_Ru imp inmon_cons_x_u0. Apply Derive2. Apply imp. Apply inmonoid_cons_inv with x. Assumption.*)
Qed.
prolog [ in_mon_X_Der_imp_inmon_X ] 10.
(*Intros. Apply in_mon_X_Der_imp_inmon_X with R2 u;Assumption.*)
Qed.
prolog
[ sym_inter isGram2 inter_union isGram4 inmon_Der_imp_Der_d2
inmon_Der_imp_inmon_R2_d ] 15.
(*Intros N_dans_X N_dans_V1 N_dans_V2 u v G_R1 G_R2 inter_V1_V2_empty inmon_X_V2_u Der_Ru_u_v. Apply inmon_Der_imp_inmon_R2_d with u. Apply isGram4 with S2;Assumption.  Apply inmon_Der_imp_Der_d2.  Assumption.  Assumption.  Assumption.  Apply isGram4 with S1;Assumption.  Apply isGram4 with S2;Assumption.  Apply inter_union. Apply isGram2 with R1 S1; Assumption. Apply sym_inter;Assumption.  Assumption.  Assumption.  Assumption.*)
Qed.
unfold Derivestar in |- *.
intros N_dans_X N_dans_V1 N_dans_V2 G_1 G_2 inter_V1_V2_empty u v
Derivestar_Ru.
pattern u, v in |- *.
apply Derivestar_Ru.
auto.
intros u0 v0 w Der_Ru inmon_v0_imp_Rstar_R2_v0 inmon_u0.
apply Rstar_R with v0.
prolog [ sym_inter isGram2 inter_union isGram4 inmon_Der_imp_Der_d2 ] 4.
(*Apply inmon_Der_imp_Der_d2. Assumption. Assumption. Assumption. Apply isGram4 with S1;Assumption. Apply isGram4 with S2;Assumption. Apply inter_union. Apply isGram2 with R1 S1; Assumption. Apply sym_inter;Assumption. Assumption. Assumption.*)
prolog [ inmon_Der_imp_inmon_d2 ] 3.
(*Apply inmon_v0_imp_Rstar_R2_v0. Apply inmon_Der_imp_inmon_d2 with u0;Assumption.*)
Qed.

Lemma Gunion_disj_Derive1 :
~ dans S X ->
~ dans S V1 ->
~ dans S V2 ->
isGram X V1 R1 S1 ->
isGram X V2 R2 S2 ->
forall u : Word,
Derive Ru (cons S nil) u -> cons S1 nil = u :>Word \/ cons S2 nil = u :>Word.