Fixpoint update_tree {X} (o : tree X) (stop : nat) (x : X) :
  path -> tree X :=
  match o in tree _ return path -> tree X with
  | leaf => fun _ => leaf
  | node d_o o_l o_r =>
      fun p =>
        match stop with
        | O => node x o_l o_r
        | S stop' =>
            match p with
            | [] => node d_o o_l o_r
            | b :: xs =>
                match b with
                | true => node d_o (update_tree o_l stop' x xs ) o_r
                | false => node d_o o_l(update_tree o_r stop' x xs)
                end
            end
        end
  end.Fixpoint lookup_tree {X} (o : tree X) (lvl : nat) : path -> option X:=
  match o with
  | leaf => fun _ => None
  | node d o_l o_r =>
      fun p =>
        match lvl with
        | O => Some d
        | S lv =>
            match p with
            | [] => None
            | x :: xs =>
                match x with
                | true => lookup_tree o_l lv xs
                | false => lookup_tree o_r lv xs
                end
            end
        end
  end.

(* Specifications: *)
Lemma lookup_tree_update_tree {X} (o : tree X) : forall (lvl lvl' : nat) (p p' : path) (x : X), lvl < lvl' -> lookup_tree (update_tree o lvl x p') lvl' p = lookup_tree o lvl' p.
Lemma update_tree_preserves_pb {X} (o : tree X) : forall n lvl x p, is_p_b_tr o n -> is_p_b_tr (update_tree o lvl x p) n.
Lemma lookup_tree_update_tree {X} (o : tree X) : forall (lvl lvl' : nat) (p p' : path) (x : X), lvl < lvl' -> lookup_tree (update_tree o lvl x p') lvl' p = lookup_tree o lvl' p.
Lemma update_tree_preserves_pb {X} (o : tree X) : forall n lvl x p, is_p_b_tr o n -> is_p_b_tr (update_tree o lvl x p) n.