Proof using.
intros t H1; split; try exact (pb_unique_prefix1 t); apply pb_unique_key; auto.
Qed.
(* Predicate that checks if a position (a list of bool) can be safely added (adding an element is done without any removing) *)
Inductive pbfree : list bool -> pbtree -> Prop :=
| pbfree_left1 : forall b l, pbfree (true :: l) (pbleft b)
| pbfree_left2 : forall b l, pbfree l b -> pbfree (false :: l) (pbleft b)
| pbfree_right1 : forall b l, pbfree (false :: l) (pbright b)
| pbfree_right2 : forall b l, pbfree l b -> pbfree (true :: l) (pbright b)
| pbfree_node1 :
forall b c l, pbfree l b -> pbfree (false :: l) (pbnode b c)
| pbfree_node2 :
forall b c l, pbfree l b -> pbfree (true :: l) (pbnode c b).
Hint Constructors pbfree : core.
(* Add an element in a tree at a given position (list of bool) *)
Fixpoint pbadd (a : A) (t : pbtree) (l : list bool) {struct l} : pbtree :=
match l with
| nil => pbleaf a
| false :: l1 =>
match t with
| pbnode t1 t2 => pbnode (pbadd a t1 l1) t2
| pbleft t1 => pbleft (pbadd a t1 l1)
| pbright t2 => pbnode (pbadd a (pbleaf empty) l1) t2
| _ => pbleft (pbadd a (pbleaf empty) l1)
end
| true :: l1 =>
match t with
| pbnode t1 t2 => pbnode t1 (pbadd a t2 l1)
| pbright t2 => pbright (pbadd a t2 l1)
| pbleft t1 => pbnode t1 (pbadd a (pbleaf empty) l1)
| _ => pbright (pbadd a (pbleaf empty) l1)
end
end.

(* Specifications: *)
(* Adding to  a leaf replace it *)
Theorem pbadd_prop1 :
forall a1 a2 l1, compute_pbcode (pbadd a1 (pbleaf a2) l1) = (a1, l1) :: nil.