End TREES.
Arguments E {V}.
Arguments T {V} _ _ _.
Arguments tree_rep {V} _ _ _.
Arguments tree_rep_valid_pointer {V} _ _ _ _ _ _.
Arguments tree_rep_local_facts {V} _ _ _ _ _ _.
Definition map_tree {V1 V2: Type} (f: V1 -> V2): tree V1 -> tree V2 :=
fix map_tree (t: tree V1) :=
match t with
| E => E
| T t1 x t2 => T (map_tree t1) (f x) (map_tree t2)
end.
Section IterTreeSepCon.
Context {A : Type}.
Context {B : Type}.
Context {ND : NatDed A}.
Context {SL : SepLog A}.
Context {ClS: ClassicalSep A}.
Context {CoSL: CorableSepLog A}.
Context (p : B -> A).
Fixpoint iter_tree_sepcon (t1 : tree B) : A :=
match t1 with
| E => emp
| T a x b => p x * iter_tree_sepcon a * iter_tree_sepcon b
end.
End IterTreeSepCon.
Section IterTreeSepCon2.
Context {A : Type}.
Context {B1 B2 : Type}.
Context {ND : NatDed A}.
Context {SL : SepLog A}.
Context {ClS: ClassicalSep A}.
Context {CoSL: CorableSepLog A}.
Context (p : B1 -> B2 -> A).
Fixpoint iter_tree_sepcon2 (t1 : tree B1) : tree B2 -> A :=
match t1 with
| E => fun t2 =>
match t2 with
| E => emp
| _ => FF
end
| T xa x xb => fun t2 =>
match t2 with
| E => FF
| T ya y yb => p x y * iter_tree_sepcon2 xa ya * iter_tree_sepcon2 xb yb
end
end.

Lemma iter_tree_sepcon2_spec: forall tl1 tl2,
iter_tree_sepcon2 tl1 tl2 =
EX tl: tree (B1 * B2),
!! (tl1 = map_tree fst tl /\ tl2 = map_tree snd tl) &&
iter_tree_sepcon (uncurry p) tl.