Section Easy_lemma_isGram.
Variable X V R : Ensf.
Variable S : Elt.
Let H := isGram X V R S.
intro H1.
elim H1.
trivial.
Qed.
intro H1.
elim H1.
intuition.
Qed.
intro H1.
elim H1.
intuition.
Qed.
intro H1.
elim H1.
intuition.
Qed.
intros.
red in |- *; red in |- *.
auto.
Qed.
End Easy_lemma_isGram.
(*--------*)
unfold Regles in |- *.
auto.
Qed.
unfold Regles in |- *.
intros X V R V' inclus_V_V' Regles_X_V_R x dans_x_R.
elim (Regles_X_V_R x dans_x_R).
intros A dans_A_V temp; elim temp; clear temp.
intros B egal_B inmonoid_B.
exists A.
auto.
exists B.
assumption.
apply inmonoid_inclus with (union X V); auto.
Qed.
intros X V R a u R_R dans_a_V inmonoid_u_X_V_u.
red in |- *.
intros x dans_x_R'.
cut (couple a (word u) = x :>Elt \/ dans x R). (**)
intuition.
(*	Intro egal_x_couple.*)
exists a.
assumption.
exists u; auto.
(**)apply dans_add; assumption. Qed.  Lemma Regles_add2 : forall (X V R : Ensf) (a : Elt), Regles X V R -> Regles X (add a V) R. intros. apply Regles_V with V; auto. Qed.   Lemma Regles_union : forall X V R R' : Ensf, Regles X V R -> Regles X V R' -> Regles X V (union R R').  unfold Regles in |- *. intros X V R R' R_R R_R' x dans_x_union. cut (dans x R \/ dans x R'); auto. intros [HR| HR']; auto. Qed.  Lemma isGram_inclus2 : forall (X V R R' : Ensf) (S : Elt), inclus R' R -> isGram X V R S -> isGram X V R' S. prolog [ isGram4 Regles_R isGram3 isGram2 isGram1 isGram5 ] 11.  (*Intros X V R R' S incl isGram_X_V_R_S. Apply isGram5 . Apply isGram1 with V R S; Assumption. Apply isGram2 with R S; Assumption. Apply isGram3 with X R; Assumption. Apply Regles_R with R. Assumption. Apply isGram4 with S; Assumption.*)
Qed.
intros X V R S a isGram_X_V_a_R_S.
apply isGram_inclus2 with (add a R); auto.
Qed.
(*--------------------------*)
(* (Derive R u v) signifie "u se recrit en v par une production de R" *)
Inductive Derive (R : Ensf) : Word -> Word -> Prop :=
(*si A -R-> u alors Av -G-> uv *)
| Derive1 :
forall (u v : Word) (A : Elt),
dans (couple A (word u)) R ->
Derive R (cons A v) (Append u v)
(*si u -G-> v alors x::u -G-> x::v*)
| Derive2 :
forall (u v : Word) (x : Elt),
Derive R u v -> Derive R (cons x u) (cons x v).
Hint Resolve Derive1.
Hint Resolve Derive2.
intros R1 R2 u v inclus_R1_R2 Der_R1.
elim Der_R1; auto.
Qed.
Definition Derive_inv (R : Ensf) (x y : Word) :=
match x return Prop with
| nil =>
(* nil  *)  False (* cons *)
| cons A w =>
ex2 (fun u : Word => dans (couple A (word u)) R)
(fun u : Word =>
ex2 (fun v : Word => cons A v = x :>Word)
(fun v : Word => Append u v = y :>Word)) \/
ex2 (fun v : Word => Derive R w v)
(fun v : Word => cons A v = y :>Word)
end.
intros R x y Der_x_y.
unfold Derive_inv in |- *.
elim Der_x_y; prolog [ ex_intro2 refl_equal or_intror or_introl ] 8.
(* Intros u v A dans_couple. Left. Exists u; [Assumption | Exists v; Apply refl_equal].  Intros u v x0 Der_u_v Der_inv_u_v. Simpl; Right. Exists v; Trivial .*)
Qed.
Hint Resolve Derive_inv1.
intros R x y.
elim x.
unfold Derive_inv in |- *.
intuition.
(*Intro temp; Elim temp; Clear temp.*)
intros x0 w Hyp_rec.
unfold Derive_inv in |- *.
(*Simpl.*)
exists x0.
exists w; trivial.
Qed.
(* Proof [R:Ensf][x,y:Word][D : (Derive R x y)] (Derive_inv2 R x y (Derive_inv1 R x y D)). *)
prolog [ Derive_inv1 Derive Derive_inv2 ] 7.
Qed.
intros X V1 R1 u v Regles_R1 Der_R1.
elim Der_R1;
prolog
[ Regles_inv2 inmonoid_cons_inv inmonoid_cons_inv2 inmonoid_cons
inmonoid_Append ] 10.
(*Intros u0 v0 A dans_R1 inmonoid_cons_A_v0. Apply inmonoid_Append. Apply Regles_inv2 with R1 A;Assumption. Apply inmonoid_cons_inv with A; Assumption.  Intros u0 v0 x Der_R1_u0 imp inmon_cons_x_u0. Apply inmonoid_cons. Apply imp. Apply inmonoid_cons_inv with x;Assumption.  Apply inmonoid_cons_inv2 with u0;Assumption.*)
Qed.
(*  (Derivestar R u v) signifie "u se recrit en v par zero ou plusieurs productions de R" *)
Definition Derivestar (R : Ensf) := Rstar Word (Derive R).
Hint Unfold Derivestar.
auto.
Qed.
Hint Resolve Derivestar_refl.

Lemma Derivestar_R :
forall (R : Ensf) (u v w : Word),
Derive R u v -> Derivestar R v w -> Derivestar R u w.