(* union de deux états dans un meme preDTA *)

(* définition d'un état *)

Fixpoint union_pl (pl0 : prec_list) : prec_list -> prec_list :=
  fun pl1 : prec_list =>
  match pl0 with
  | prec_empty => pl1
  | prec_cons a pl00 pl01 => prec_cons a pl00 (union_pl pl01 pl1)
  end.Fixpoint union_mpl_0 (c : ad) (pl : prec_list) (s : state) {struct s} :
 state :=
  match s with
  | M0 => M1 prec_list c pl
  | M1 c0 pl0 =>
      if Neqb c c0
      then M1 prec_list c (union_pl pl pl0)
      else MapMerge prec_list (M1 prec_list c pl) (M1 prec_list c0 pl0)
  | M2 s0 s1 =>
      match c with
      | N0 => M2 prec_list (union_mpl_0 N0 pl s0) s1
      | Npos p =>
          match p with
          | xH => M2 prec_list s0 (union_mpl_0 N0 pl s1)
          | xO p' => M2 prec_list (union_mpl_0 (Npos p') pl s0) s1
          | xI p' => M2 prec_list s0 (union_mpl_0 (Npos p') pl s1)
          end
      end
  end.Fixpoint union_mpl (s0 : state) : state -> state :=
  fun s1 : state =>
  match s0, s1 with
  | M0, M0 => M0 prec_list
  | M0, M2 s10 s11 => M2 prec_list s10 s11
  | _, M1 c1 pl1 => union_mpl_0 c1 pl1 s0
  | M1 c0 pl0, _ => union_mpl_0 c0 pl0 s1
  | M2 s00 s01, M0 => M2 prec_list s00 s01
  | M2 s00 s01, M2 s10 s11 =>
      M2 prec_list (union_mpl s00 s10) (union_mpl s01 s11)
  end.

(* Specifications: *)
Lemma union_pl_0 : forall pl : prec_list, union_pl pl prec_empty = pl.
Lemma union_pl_1 : forall pl : prec_list, union_pl prec_empty pl = pl.
Lemma union_pl_2 : forall pl0 pl1 : prec_list, union_pl pl0 pl1 = prec_empty -> pl0 = prec_empty.
Lemma union_pl_3 : forall pl0 pl1 : prec_list, pl0 <> prec_empty -> union_pl pl0 pl1 <> prec_empty.
Lemma union_pl_0d_0 : forall (d : preDTA) (pl0 : prec_list) (tl : term_list), liste_reconnait d pl0 tl -> liste_reconnait d (union_pl pl0 prec_empty) tl.
Lemma union_pl_0d_1 : forall (d : preDTA) (pl0 : prec_list) (tl : term_list) (a : ad) (la ls : prec_list), liste_reconnait d pl0 tl -> pl0 <> prec_empty -> liste_reconnait d (union_pl pl0 (prec_cons a la ls)) tl.
Lemma union_pl_0d : forall (d : preDTA) (pl0 pl1 : prec_list) (tl : term_list), pl_compat pl0 pl1 -> liste_reconnait d pl0 tl -> liste_reconnait d (union_pl pl0 pl1) tl.
Lemma union_pl_1d_0 : forall (d : preDTA) (pl1 : prec_list) (tl : term_list), liste_reconnait d pl1 tl -> liste_reconnait d (union_pl prec_empty pl1) tl.
Lemma union_pl_1d_1 : forall (d : preDTA) (pl1 : prec_list) (tl : term_list) pl0, liste_reconnait d pl1 tl -> pl1 <> prec_empty -> liste_reconnait d (union_pl pl0 pl1) tl.
Lemma union_pl_1d : forall (d : preDTA) (pl0 pl1 : prec_list) (tl : term_list), pl_compat pl0 pl1 -> liste_reconnait d pl1 tl -> liste_reconnait d (union_pl pl0 pl1) tl.
Lemma union_pl_r_0 : forall (d : preDTA) (pl0 pl1 : prec_list) (hd : term) (tl : term_list), liste_reconnait d (union_pl pl0 pl1) (tcons hd tl) -> liste_reconnait d pl0 (tcons hd tl) \/ liste_reconnait d pl1 (tcons hd tl).
Lemma union_pl_r_1 : forall (d : preDTA) (pl0 pl1 : prec_list), pl_compat pl0 pl1 -> liste_reconnait d (union_pl pl0 pl1) tnil -> liste_reconnait d pl0 tnil \/ liste_reconnait d pl1 tnil.
Lemma union_pl_r : forall (d : preDTA) (pl0 pl1 : prec_list) (tl : term_list), pl_compat pl0 pl1 -> liste_reconnait d (union_pl pl0 pl1) tl -> liste_reconnait d pl0 tl \/ liste_reconnait d pl1 tl.