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

Lemma pl_ess_invar_0 : forall pl0 pl1 : prec_list, 1 <= pl_essence pl0 pl1.