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.

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.