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).