(* 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.