(* Transform a tree in a code *) 
Fixpoint compute_pbcode (a : pbtree) : code A :=
  match a with
  | pbleaf b => (b, nil) :: nil
  | pbleft l1 =>
      map
        (fun v : A * list bool =>
         match v with
         | (a1, b1) => (a1, false :: b1)
         end) (compute_pbcode l1)
  | pbright l1 =>
      map
        (fun v : A * list bool =>
         match v with
         | (a1, b1) => (a1, true :: b1)
         end) (compute_pbcode l1)
  | pbnode l1 l2 =>
      map
        (fun v : A * list bool =>
         match v with
         | (a1, b1) => (a1, false :: b1)
         end) (compute_pbcode l1) ++
      map
        (fun v : A * list bool =>
         match v with
         | (a1, b1) => (a1, true :: b1)
         end) (compute_pbcode l2)
  end.

(* Specifications: *)
Theorem compute_pbcode_not_null : forall p, compute_pbcode p <> nil.
Theorem in_pbcompute_inpb : forall (t : pbtree) (a : A) (l : list bool), In (a, l) (compute_pbcode t) -> inpb (pbleaf a) t.
Theorem inpb_compute_ex : forall a p, inpb (pbleaf a) p -> exists l : _, In (a, l) (compute_pbcode p).
Theorem pb_unique_prefix1 : forall (t : pbtree) (a1 a2 : A) (lb1 lb2 : list bool), In (a1, lb1) (compute_pbcode t) -> In (a2, lb2) (compute_pbcode t) -> is_prefix lb1 lb2 -> a1 = a2 :>A.
Theorem pb_unique_key : forall t, distinct_pbleaves t -> unique_key (compute_pbcode t).
Theorem pb_unique_prefix : forall t : pbtree, distinct_pbleaves t -> unique_prefix (compute_pbcode t).