Module PTree <: TREE.
Definition elt := positive.
Definition elt_eq := peq.
Inductive tree (A : Type) : Type :=
| Leaf : tree A
| Node : tree A -> option A -> tree A -> tree A.
Arguments Leaf [A].
Arguments Node [A].
Scheme tree_ind := Induction for tree Sort Prop.
Definition t := tree.
Definition empty (A : Type) := (Leaf : t A).
Fixpoint get (A : Type) (i : positive) (m : t A) {struct i} : option A :=
match m with
| Leaf => None
| Node l o r =>
match i with
| xH => o
| xO ii => get ii l
| xI ii => get ii r
end
end.
Fixpoint set (A : Type) (i : positive) (v : A) (m : t A) {struct i} : t A :=
match m with
| Leaf =>
match i with
| xH => Node Leaf (Some v) Leaf
| xO ii => Node (set ii v Leaf) None Leaf
| xI ii => Node Leaf None (set ii v Leaf)
end
| Node l o r =>
match i with
| xH => Node l (Some v) r
| xO ii => Node (set ii v l) o r
| xI ii => Node l o (set ii v r)
end
end.
Fixpoint remove (A : Type) (i : positive) (m : t A) {struct i} : t A :=
match i with
| xH =>
match m with
| Leaf => Leaf
| Node Leaf o Leaf => Leaf
| Node l o r => Node l None r
end
| xO ii =>
match m with
| Leaf => Leaf
| Node l None Leaf =>
match remove ii l with
| Leaf => Leaf
| mm => Node mm None Leaf
end
| Node l o r => Node (remove ii l) o r
end
| xI ii =>
match m with
| Leaf => Leaf
| Node Leaf None r =>
match remove ii r with
| Leaf => Leaf
| mm => Node Leaf None mm
end
| Node l o r => Node l o (remove ii r)
end
end.

Theorem gsspec:
forall (A: Type) (i j: positive) (x: A) (m: t A),
get i (set j x m) = if peq i j then Some x else get i m.