(* Lexicographic ordering doesn't lead to a PCM (it's not associative), so we keep a full log of values. *)
(* In this example, all the resources held in the protocols are snapshots, so the full and read interpretations are equal. *)
(* This is a bit messy to allow the mutually recursive protocol interpretations. *)
Definition version_T_fun version locs g : (Z * Z -> mpred) -> (Z * Z -> mpred) :=
fun R '(s, v) => !!(v = s) && EX L : _,
!!(exists vs, Zlength vs = size /\ log_latest L (if Z.even v then v else v - 1) vs) &&
(if eq_dec v 0 then emp
else fold_right sepcon emp (map (fun i => protocol_R (Znth i locs Vundef) (map_Znth i L 0) map_incl
(data_T' version (fun s v => |>R (s, v)), data_T' version (fun s v => |>R (s, v)))) (upto (Z.to_nat size)))) *
ghost_snap L g.
Definition version_T' version locs g := HORec (version_T_fun version locs g).
Definition version_T version locs g s v := version_T' version locs g (s, v).
Definition data_T version locs g := data_T' version (|>version_T version locs g).

(* Specifications: *)
Lemma version_T'_eq version locs g : version_T' version locs g =
version_T_fun version locs g (version_T' version locs g).
Lemma version_T_eq version locs g s v : version_T version locs g s v = !!(v = s) && EX L : _,
!!(exists vs, Zlength vs = size /\ log_latest L (if Z.even v then v else v - 1) vs) &&
(if eq_dec v 0 then emp
else fold_right sepcon emp (map (fun i => protocol_R (Znth i locs Vundef) (map_Znth i L 0) map_incl
(data_T version locs g, data_T version locs g)) (upto (Z.to_nat size)))) * ghost_snap L g.
Lemma data_T_eq version locs g s v : data_T version locs g s v =
EX ver : Z, !!(Z.even ver = true /\ log_latest s ver v) &&
protocol_R version (ver - 1) Z.le (|>version_T version locs g, |>version_T version locs g).