Instance CompSpecs : compspecs.Definition Vprog : varspecs.(*Definition release2_spec := DECLARE _release2 release2_spec.
Definition freelock2_spec := DECLARE _freelock2 (freelock2_spec _).
Definition spawn_spec := DECLARE _spawn spawn_spec.*)

Definition tnode := Tstruct _node noattr.Definition make_loads lv := map (fun v => Load (vint v)) lv.(* Invariant for version number: Every write increases it, and the version of each data location is at least the
   most recently read version. *)
(* Invariant for each location: The "rounded up" version number is at least the location's version. *)

Definition round_up i := i + i mod 2.Definition round_down i := i - i mod 2.(* Do we really need the hists? *)
(* Ghost vars act as write permissions. *)
Definition ver_R g gsh gv lg (h : list hist_el) v := ghost_master v g * ghost_var gsh v gv *
  fold_right sepcon emp (map (ghost_snap (round_down v)) lg).Notation "'WITH'  x1 : t1 , x2 : t2 , x3 : t3 , x4 : t4 , x5 : t5 , x6 : t6 , x7 : t7 , x8 : t8 , x9 : t9 , x10 : t10 , x11 : t11 , x12 : t12 , x13 : t13 , x14 : t14 , x15 : t15 , x16 : t16 , x17 : t17 'PRE'  [ u , .. , v ] P 'POST' [ tz ] Q" :=
     (NDmk_funspec ((cons u%formals .. (cons v%formals nil) ..), tz) cc_default (t1*t2*t3*t4*t5*t6*t7*t8*t9*t10*t11*t12*t13*t14*t15*t16*t17)
           (fun x => match x with (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17) => P%assert end)
           (fun x => match x with (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17) => Q%assert end))
            (at level 200, x1 at level 0, x2 at level 0, x3 at level 0, x4 at level 0,
             x5 at level 0, x6 at level 0, x7 at level 0, x8 at level 0, x9 at level 0,
              x10 at level 0, x11 at level 0, x12 at level 0,  x13 at level 0, x14 at level 0,
               x15 at level 0, x16 at level 0, x17 at level 0,
             P at level 100, Q at level 100).

Lemma body_read : semax_body Vprog Gprog f_read read_spec.