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).

(* Specifications: *)
Lemma snap_snap_max : forall v1 v2 p, ghost_snap v1 p * ghost_snap v2 p = ghost_snap v1 p * ghost_snap (Z.max v1 v2) p.
Lemma snaps_snaps_max : forall {cs : compspecs} (v1 v2 : Z) lg, @view_shift cs (fold_right sepcon emp (map (ghost_snap v1) lg) * fold_right sepcon emp (map (ghost_snap v2) lg)) (fold_right sepcon emp (map (ghost_snap v1) lg) * fold_right sepcon emp (map (ghost_snap (Z.max v1 v2)) lg)).
Lemma land_1 : forall i, Z.land i 1 = i mod 2.
Lemma round_down_mono : forall v1 v2, v1 <= v2 -> round_down v1 <= round_down v2.
Lemma round_up_max_distr : forall v1 v2, round_up (Z.max v1 v2) = Z.max (round_up v1) (round_up v2).
Lemma body_read : semax_body Vprog Gprog f_read read_spec.
Lemma ver_R_precise : forall g gsh gv lg v, precise (EX h : _, ver_R g gsh gv lg h v).
Lemma loc_R_precise : forall g gsh gl gv v, precise (EX h : _, loc_R g gsh gl gv h v).
Lemma body_write : semax_body Vprog Gprog f_write write_spec.