Proof using.
induction t using tree_rect with
(P_list := fun l => forall bytes,
ByteListReader.unwrap (deserialize_tree_elements_list (List.map shape l))
(IOStreamWriter.unwrap (serialize_tree_elements_list l) ++ bytes) =
Some (l, bytes));
intros;
cbn [shape map List.map
serialize_tree_shape deserialize_tree_shape
serialize_tree_elements deserialize_tree_elements
serialize_tree_elements_list deserialize_tree_elements_list].
- now cheerios_crush.
- cheerios_crush.
rewrite IHt.
cheerios_crush.
rewrite IHt0.
cheerios_crush.
- now cheerios_crush.
- fold deserialize_tree_elements_list.
fold serialize_tree_elements_list.
cheerios_crush.
now rewrite IHt.
Qed.
(* Now we serialize the tree itself by first serializing the shape, and then a preorder traversal of the elements. *)
Definition tree_serialize (t : tree A) : IOStreamWriter.t :=
IOStreamWriter.append (fun _ => serialize_tree_shape t)
(fun _ => serialize_tree_elements t).
(* To deserialize, we deserialize the shape and the elements, and then fill out the shape with the elements. *)
Definition tree_deserialize : ByteListReader.t (tree A) :=
shape <- deserialize_tree_shape ;;
deserialize_tree_elements shape.

(* To prove this correct, we need to know that serializ-/deserializing the shape of `t` results in `shape t` (`serialize_deserialize_shape_id`), and that filling out a `map f t` with the elements of `preorder t` results in `t` (`fill_preorder`). *)
Lemma tree_serialize_deserialize_id :
serialize_deserialize_id_spec tree_serialize tree_deserialize.