(* This program is free software; you can redistribute it and/or      *)
(* modify it under the terms of the GNU Lesser General Public License *)
(* as published by the Free Software Foundation; either version 2.1   *)
(* of the License, or (at your option) any later version.             *)
(*                                                                    *)
(* This program is distributed in the hope that it will be useful,    *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of     *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *)
(* GNU General Public License for more details.                       *)
(*                                                                    *)
(* You should have received a copy of the GNU Lesser General Public   *)
(* License along with this program; if not, write to the Free         *)
(* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *)
(* 02110-1301 USA                                                     *)
(* Contribution to the Coq Library   V6.3 (July 1999)                    *)
(****************************************************************************)
(*                 The Calculus of Inductive Constructions                  *)
(*                                                                          *)
(*                                Projet Coq                                *)
(*                                                                          *)
(*                     INRIA                        ENS-CNRS                *)
(*              Rocquencourt                        Lyon                    *)
(*                                                                          *)
(*                                Coq V5.10                                 *)
(*                              Nov 25th 1994                               *)
(*                                                                          *)
(****************************************************************************)
(*                                 RatReg.v                                 *)
(****************************************************************************)
(*              Formal Language Theory                                      *)
(*                                                                          *)
(*              Judicael Courant - Jean-Christophe Filliatre                *)
(*                                                                          *)
(*              Developped in V5.8  June-July 1993                          *)
(*              Ported     to V5.10 October 1994                            *)
(****************************************************************************)
(************************************************************************)
(*									*)
(*            Un langage reduit a un mot est regulier.			*)
(*									*)
(************************************************************************)
(*  Le mot vide est reconnu par un automate reduit a un etat (zero)	*)
(*  et sans transition.							*)
unfold reconnait at 1 in |- *.
split.
apply inmonoid_nil.
exists zero; exists zero.
auto.
Qed.
(* Seul le mot vide est reconnu par l'automate ci-dessus.		*)
unfold reconnait at 1 in |- *.
simple induction w.
auto.
intros x w0 H H0.
clear H.
elim H0; intros; clear H0.
elim H1; intros; clear H1.
elim H0; intros; clear H0.
elim H1; intros; clear H1.
elim H2; intros; clear H2.
cut
(Chemin x0 x1 (singleton zero) (prodcart empty (prodcart alph empty))
(cons x w0)).
2: auto.
unfold Chemin in |- *; simpl in |- *.
intro H2.
absurd (dans x0 empty).
auto.
elim H2; intros; clear H2.
elim H4; intros; clear H4.
elim H5; intros; clear H5.
elim H6; intros; clear H6.
cut (dans x0 empty /\ dans (couple x x2) (prodcart alph empty)).
2: apply coupl2; assumption.
tauto.
Qed.
(*									*)
(*  Pour pouvoir construire un automate qui reconnait (cons a w) a	*)
(*  partir d'un automate qui reconnait w, il faut un resultat un peu	*)
(*  plus precis que "il existe un automate tel que...".			*)
(*									*)
(*  On precise que cet automate a un unique etat de depart.		*)
(*									*)
exists (singleton zero).
exists zero.
exists (singleton zero).
exists (prodcart empty (prodcart alph empty)).
split.
red in |- *; auto.
red in |- *; split.
red in |- *.
symmetry  in |- *; apply lwordnil_is_reg2.
assumption.
intro.
compute in H.
rewrite <- H.
apply lwordnil_is_reg1.
Qed.
(*  D'ou bien sur...							*)
cut
(exists q : Ensf,
(exists e : Elt,
(exists qa : Ensf,
(exists d : Ensf,
automate q (singleton e) qa d /\
eqwordset (reconnait q (singleton e) qa d) (lword nil))))).
2: apply lwordnil_is_regS; auto.
intro H; elim H; clear H.
intros q H; elim H; clear H.
intros e H; elim H; clear H.
intros qa H; elim H; clear H.
intros d H; elim H; clear H.
intros.
red in |- *.
exists q.
exists (singleton e).
exists qa.
exists d.
auto.
Qed.
(*  Le gros morceau...							*)
(*  On commence par montrer que si on a un chemin pour w alors on	*)
(*  toujours ce chemin en rajoutant un etat et une transition.		*)
simple induction w.
intros.
cut (Chemin e1 e2 q d nil); auto.
intro.
cut (dans e1 q /\ e1 = e2 :>Elt); auto.
intro H1; elim H1; auto.
intros x w0 H e0 e1 e2 e3 a q d H0.
cut (Chemin e1 e2 q d (cons x w0)); auto.
intro.
cut
(exists e : Elt,
chemin e e2 q d w0 /\
dans e1 q /\ dans x alph /\ dans (couple e1 (couple x e)) d);
auto.
intro H2; elim H2; clear H2.
intros e H2; elim H2; clear H2.
intros H2 H3; elim H3; clear H3.
intros H3 H4; elim H4; clear H4.
intros H4 H5.
apply (chemin_cons e e2 (add e0 q) (add (couple e0 (couple a e3)) d) w0 e1 x);
auto.
Qed.
(*  Si un automate reconnait un mot w sans utiliser l'etat e0 alors	*)
(*  l'automate obtenu en supprimant cet etat ainsi que la transition	*)
(*  correspondante reconnait toujours w.				*)

Lemma restriction_aut :
forall (w : Word) (e0 e e2 e3 a : Elt) (q d : Ensf),
~ dans e0 q ->
dans e q ->
inclus d (prodcart q (prodcart alph q)) ->
chemin e e2 (add e0 q) (add (couple e0 (couple a e3)) d) w ->
chemin e e2 q d w.