(* algorithme de calcul d'intersection : calcul de l'état produit *)
(* calcul d'une prec_list produit *)
Fixpoint pl_produit_0 (a : ad) (la pl : prec_list)
(n : nat) {struct n} : prec_list -> prec_list :=
fun l : prec_list =>
match n with
| O => prec_empty
| S m =>
match pl with
| prec_empty => l
| prec_cons a0 la0 ls0 =>
prec_cons (iad_conv a a0) (pl_produit_1 la m la0)
(pl_produit_0 a la ls0 m l)
end
end
with pl_produit_1 (pl0 : prec_list) (n : nat) {struct n} :
prec_list -> prec_list :=
fun pl1 : prec_list =>
match n with
| O => prec_empty
| S m =>
match pl0, pl1 with
| prec_empty, prec_empty => prec_empty
| prec_empty, prec_cons a1 la1 ls1 => prec_empty
| prec_cons a0 la0 ls0, prec_empty => prec_empty
| prec_cons a0 la0 ls0, prec_cons a1 la1 ls1 =>
pl_produit_0 a0 la0 (prec_cons a1 la1 ls1) m
(pl_produit_1 ls0 m (prec_cons a1 la1 ls1))
end
end.
Fixpoint pl_card (pl : prec_list) : nat :=
match pl with
| prec_empty => 1
| prec_cons a la ls => S (pl_card la + pl_card ls)
end.
(* terminaison des fonctions précédantes *)
Definition pl_essence (pl0 pl1 : prec_list) : nat :=
pl_card pl0 + pl_card pl1.
Definition pl_produit (pl0 pl1 : prec_list) : prec_list :=
pl_produit_1 pl0 (pl_essence pl0 pl1) pl1.

(* Specifications: *)
Lemma pl_card_0 : forall pl : prec_list, 1 <= pl_card pl.
Lemma pl_ess_aux_0 : forall pl : prec_list, 1 <= pl_card pl.
Lemma pl_ess_aux_1 :
forall (a : ad) (la ls : prec_list),
S (pl_card la) <= pl_card (prec_cons a la ls).
Lemma pl_ess_aux_2 :
forall (a : ad) (la ls : prec_list),
S (pl_card ls) <= pl_card (prec_cons a la ls).
Lemma pl_ess_invar_0 : forall pl0 pl1 : prec_list, 1 <= pl_essence pl0 pl1.
Lemma pl_ess_invar_1 :
forall (a a' : ad) (la ls la' ls' : prec_list),
S (pl_essence la (prec_cons a' la' ls')) <=
pl_essence (prec_cons a la ls) (prec_cons a' la' ls').
Lemma pl_ess_invar_2 :
forall (a a' : ad) (la ls la' ls' : prec_list),
S (pl_essence ls (prec_cons a' la' ls')) <=
pl_essence (prec_cons a la ls) (prec_cons a' la' ls').
Lemma pl_ess_invar_3 :
forall (a' : ad) (la la' ls' : prec_list),
S (pl_essence la la') <= pl_essence la (prec_cons a' la' ls').
Lemma pl_ess_invar_4 :
forall (a' : ad) (la la' ls' : prec_list),
S (pl_essence la ls') <= pl_essence la (prec_cons a' la' ls').
Lemma pl_ess_invar_5 : forall pl0 pl1 : prec_list, 2 <= pl_essence pl0 pl1.
Fixpoint pl_prof (pl : prec_list) : nat :=
match pl with
| prec_empty => 0
| prec_cons a la ls => S (max (pl_prof la) (pl_prof ls))
end.