Module ITree(X: INDEXED_TYPE).
Definition elt := X.t.
Definition elt_eq := X.eq.
Definition t : Type -> Type := PTree.t.
Definition empty (A: Type): t A := PTree.empty A.
Definition get (A: Type) (k: elt) (m: t A): option A := PTree.get (X.index k) m.
Definition set (A: Type) (k: elt) (v: A) (m: t A): t A := PTree.set (X.index k) v m.
Definition remove (A: Type) (k: elt) (m: t A): t A := PTree.remove (X.index k) m.
Definition beq: forall (A: Type), (A -> A -> bool) -> t A -> t A -> bool := PTree.beq.
Definition combine: forall (A B C: Type), (option A -> option B -> option C) -> t A -> t B -> t C := PTree.combine.

Theorem gcombine:
forall (A B C: Type) (f: option A -> option B -> option C),
f None None = None ->
forall (m1: t A) (m2: t B) (i: elt),
get i (combine f m1 m2) = f (get i m1) (get i m2).