(************************************************************************)
(*									*)
(*  La concatenation de 2 langages reguliers est un langage regulier.	*)
(*									*)
(************************************************************************)

(*  On definit (pont qa1 qd2) comme l'ensemble des transitions		*)
(*  (e,epsilon,e') avec e dans qa1 et e' dans qd2.			*)

Definition transition_pont (x : Elt) : Elt :=
  match x return Elt with
  | natural n =>
      (* natural *)  zero
      (* couple  *) 
  | couple e e' =>
      couple (couple e zero) (couple epsilon (couple e' un))
      (* up      *) 
  | up e => zero
      (* word    *) 
  | word w => zero
  end.Definition pont (qa1 qd2 : Ensf) : Ensf :=
  map transition_pont (prodcart qa1 qd2).

(* Specifications: *)
Lemma automate_lconc_isgood : forall q1 qd1 qa1 d1 q2 qd2 qa2 d2 : Ensf, automate q1 qd1 qa1 d1 -> automate q2 qd2 qa2 d2 -> automate_A (union_disj q1 q2) (map injgauche qd1) (map injdroite qa2) (union (pont qa1 qd2) (union (injg_d1 q1 d1) (injd_d2 q2 d2))).
Lemma transition_a_gauche : forall (q1 qa1 d1 q2 qd2 d2 : Ensf) (e0 x e : Elt), dans e0 (map injgauche q1) -> dans x alph -> dans (couple e0 (couple x e)) (union (pont qa1 qd2) (union (injg_d1 q1 d1) (injd_d2 q2 d2))) -> dans e (map injgauche q1).
Lemma transition_a_gauche_2 : forall (q1 qa1 d1 q2 qd2 d2 : Ensf) (e0 x e : Elt), dans e0 (map injgauche q1) -> dans x alph -> dans (couple e0 (couple x e)) (union (pont qa1 qd2) (union (injg_d1 q1 d1) (injd_d2 q2 d2))) -> dans (couple (first e0) (couple x (first e))) d1.