(* Compute all the leaves *)
Fixpoint all_pbleaves (t : pbtree) : list A :=
  match t with
  | pbleaf a => a :: nil
  | pbleft t1 => all_pbleaves t1
  | pbright t1 => all_pbleaves t1
  | pbnode t1 t2 => all_pbleaves t1 ++ all_pbleaves t2
  end.

(* Specifications: *)
Theorem all_pbleaves_in : forall t a, inpb (pbleaf a) t -> In a (all_pbleaves t).
Theorem all_pbleaves_inpb : forall t a, In a (all_pbleaves t) -> inpb (pbleaf a) t.
Theorem all_pbleaves_unique : forall t, ulist (all_pbleaves t) -> distinct_pbleaves t.
Theorem all_pbleaves_ulist : forall t, distinct_pbleaves t -> ulist (all_pbleaves t).
Theorem all_pbleaves_pbadd : forall l1 a1 a2 l, In a2 (all_pbleaves (pbadd a1 l l1)) -> a2 = a1 \/ In a2 (all_pbleaves l).
Theorem all_pbleaves_pbleaf : forall l a1 a2, all_pbleaves (pbadd a1 (pbleaf a2) l) = a1 :: nil.
Theorem ulist_pbadd_prop2 : forall a1 l1 t, ~ inpb (pbleaf a1) t -> ulist (all_pbleaves t) -> ulist (all_pbleaves (pbadd a1 t l1)).
Theorem distinct_pbleaves_pbadd_prop2 : forall a1 l1 l, ~ inpb (pbleaf a1) l -> distinct_pbleaves l -> distinct_pbleaves (pbadd a1 l l1).
Theorem fold_pbadd_prop_left : forall l a, l <> nil -> fold_right (fun a (c : pbtree) => pbadd (fst a) c (snd a)) (pbleaf a) (map (fun v => match v with | (a1, b1) => (a1, false :: b1) end) l) = pbleft (fold_right (fun a (c : pbtree) => pbadd (fst a) c (snd a)) (pbleaf a) l).
Theorem fold_pbadd_prop_right : forall l a, l <> nil -> fold_right (fun a (c : pbtree) => pbadd (fst a) c (snd a)) (pbleaf a) (map (fun v => match v with | (a1, b1) => (a1, true :: b1) end) l) = pbright (fold_right (fun a (c : pbtree) => pbadd (fst a) c (snd a)) (pbleaf a) l).
Theorem fold_pbadd_prop_node : forall l a, l <> nil -> fold_right (fun a (c : pbtree) => pbadd (fst a) c (snd a)) (pbright a) (map (fun v => match v with | (a1, b1) => (a1, false :: b1) end) l) = pbnode (fold_right (fun a (c : pbtree) => pbadd (fst a) c (snd a)) (pbleaf empty) l) a.