Fixpoint s_produit (s0 s1 : state) {struct s1} : state :=
match s0, s1 with
| M0, M0 => M0 prec_list
| M0, M1 a1 p1 => M0 prec_list
| M0, M2 s10 s11 => M0 prec_list
| M1 a0 p0, M0 => M0 prec_list
| M1 a0 p0, M1 a1 p1 => s_produit_l a0 p0 (M1 prec_list a1 p1)
| M1 a0 p0, M2 s10 s11 => s_produit_l a0 p0 (M2 prec_list s10 s11)
| M2 s00 s01, M0 => M0 prec_list
| M2 s00 s01, M1 a1 p1 => s_produit_r a1 p1 (M2 prec_list s00 s01)
| M2 s00 s01, M2 s10 s11 =>
M2 prec_list (s_produit s00 s10) (s_produit s01 s11)
end.

(* Specifications: *)
Lemma s_produit_0 :
forall (s0 s1 : state) (c : ad) (p0 p1 : prec_list),
MapGet prec_list s0 c = Some p0 ->
MapGet prec_list s1 c = Some p1 ->
MapGet prec_list (s_produit s0 s1) c = Some (pl_produit p0 p1).
Lemma s_produit_1 :
forall (s0 s1 : state) (c : ad) (p : prec_list),
MapGet prec_list (s_produit s0 s1) c = Some p ->
exists p0 : prec_list,
(exists p1 : prec_list,
MapGet prec_list s0 c = Some p0 /\
MapGet prec_list s1 c = Some p1).