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.
End IterTreeSepCon2.
(* X_DEFS *)
Inductive XTree: Type :=
| XLeaf: XTree
| XNode: list XTree -> Z -> XTree.
Fixpoint xtree_rep (t: XTree) (p: val): mpred :=
match t with
| XLeaf =>
!!(p = nullval) && emp
| XNode tl v =>
EX q: val,
data_at Tsh t_struct_Xnode (q, Vint (Int.repr v)) p *
EX r: list val,
list_rep (fun (p: val) (n: val) (q: val) => data_at Tsh t_struct_Xlist (p, n) q) r q *
iter_sepcon2 xtree_rep tl r
end.
Hint Resolve xtree_rep_valid_pointer: valid_pointer.
Hint Resolve xtree_rep_local_facts: saturate_local.
Hint Resolve list_rep_Xlist_valid_pointer: valid_pointer.
Hint Resolve list_rep_Xlist_local_facts: saturate_local.
Hint Resolve xtree_rep_nullval: saturate_local.
(* X_DEFS ends. *)
(* Y_DEFS *)
Inductive YTree: Type :=
| YLeaf: YTree
| YNode: list (tree (unit * YTree) * unit) -> Z -> YTree.
Definition y_tree_rep (t: tree val) (p: val): mpred :=
tree_rep (fun q L R p: val => data_at Tsh t_struct_Ytree (q, (L, R)) p) t p.
Definition y_list_rep (l: list val) (p: val): mpred :=
list_rep (fun q n p: val => data_at Tsh t_struct_Ylist (q, n) p) l p.
Fixpoint ytree_rep (t: YTree) (p: val): mpred :=
match t with
| YLeaf =>
!!(p = nullval) && emp
| YNode ttl v =>
let rep1 (t: unit * YTree) p := ytree_rep (snd t) p in
let rep2 (t: tree (unit * YTree) * unit) p :=
EX s: tree val, y_tree_rep s p * iter_tree_sepcon2 rep1 (fst t) s in
let rep3 (t: list (tree (unit * YTree) * unit)) p :=
EX r: list val, y_list_rep r p * iter_sepcon2 rep2 t r in
EX q: val,
data_at Tsh t_struct_Ynode (q, Vint (Int.repr v)) p * rep3 ttl q
end.
Definition t_ytree_rep (t: tree (unit * YTree)) (p: val): mpred :=
EX s: tree val, y_tree_rep s p * iter_tree_sepcon2 (fun t p => ytree_rep (snd t) p) t s.
Definition lt_ytree_rep (t: list (tree (unit * YTree) * unit)) (p: val): mpred :=
EX r: list val, y_list_rep r p * iter_sepcon2 (fun t p => t_ytree_rep (fst t) p) t r.

Theorem ytree_rep_spec: forall t p,
ytree_rep t p =
match t with
| YLeaf =>
!!(p = nullval) && emp
| YNode ttl v =>
EX q: val,
data_at Tsh t_struct_Ynode (q, Vint (Int.repr v)) p * lt_ytree_rep ttl q
end.