(* définition des adresses d'états produits *)

Fixpoint iad_conv_aux_0 (p : positive) : positive :=
  match p with
  | xH => 2%positive
  | xO p' => xO (xO (iad_conv_aux_0 p'))
  | xI p' => xO (xI (iad_conv_aux_0 p'))
  end.Fixpoint iad_conv_aux_1 (p : positive) : positive :=
  match p with
  | xH => 1%positive
  | xO p' => xO (xO (iad_conv_aux_1 p'))
  | xI p' => xI (xO (iad_conv_aux_1 p'))
  end.Fixpoint iad_conv_aux_2 (p0 p1 : positive) {struct p1} : positive :=
  match p0, p1 with
  | xH, xH => 3%positive
  | xH, xO p1' => xI (xO (iad_conv_aux_0 p1'))
  | xH, xI p1' => xI (xI (iad_conv_aux_0 p1'))
  | xO p0', xH => xO (xI (iad_conv_aux_1 p0'))
  | xO p0', xO p1' => xO (xO (iad_conv_aux_2 p0' p1'))
  | xO p0', xI p1' => xO (xI (iad_conv_aux_2 p0' p1'))
  | xI p0', xH => xI (xI (iad_conv_aux_1 p0'))
  | xI p0', xO p1' => xI (xO (iad_conv_aux_2 p0' p1'))
  | xI p0', xI p1' => xI (xI (iad_conv_aux_2 p0' p1'))
  end.Definition iad_conv (a0 a1 : ad) : ad :=
  match a0, a1 with
  | N0, N0 => N0
  | N0, Npos p1 => Npos (iad_conv_aux_0 p1)
  | Npos p0, N0 => Npos (iad_conv_aux_1 p0)
  | Npos p0, Npos p1 => Npos (iad_conv_aux_2 p0 p1)
  end.

Lemma iad_conv_inj : forall a0 a1 a2 a3 : ad, iad_conv a0 a1 = iad_conv a2 a3 -> a0 = a2 /\ a1 = a3.