(*Definition q_lock_pred' (t : type) P p (vals : list (val * reptype t)) head (addc remc : val) lock gsh h := !!(Zlength vals <= MAX /\ 0 <= head < MAX /\ consistent h [] vals) && (data_at Tsh tqueue (rotate (complete MAX (map fst vals)) head MAX, (vint (Zlength vals), (vint head, (vint ((head + Zlength vals) mod MAX), (addc, remc))))) p * cond_var Tsh addc * cond_var Tsh remc * malloc_token Tsh (sizeof tqueue_t) p * malloc_token Tsh (sizeof tcond) addc * malloc_token Tsh (sizeof tcond) remc * malloc_token Tsh (sizeof tlock) lock * ghost gsh (Tsh, h) p * fold_right sepcon emp (map (fun x => let '(p, v) := x in !!(P v) && (data_at Tsh t v p * malloc_token Tsh (sizeof t) p)) vals)).  Definition q_lock_pred A P p lock gsh := EX vals : list (val * reptype A), EX head : Z, EX addc : val, EX remc : val, EX h : hist _, q_lock_pred' A P p vals head addc remc lock gsh h.*)
Definition node_lock_inv e p := EX n : val, EX l : val,(*EX h : list set_op,*)
field_at Tsh tnode [StructField _val] (vint e) p *
field_at Tsh tnode [StructField _next] n p * field_at Tsh tnode [StructField _lock] l n *
node_lock_inv.
Definition node_pred sh e p := EX l : val,
!!((*sepalg.join gsh1 gsh2 Tsh /\*) repable_signed e /\ field_compatible tnode [] p) &&
(field_at sh tnode [StructField _lock] l p *
lock_inv sh l (node_lock_inv e p) (* * ghost gsh1 (lsh, h) p*)).
Definition new_node_spec :=
DECLARE _new_node
WITH e : Z
PRE [ _e OF tint ]
PROP (repable_signed e)
LOCAL (temp _e (vint e))
SEP ()
POST [ tptr tnode ]
EX p : val,
PROP ()
LOCAL (temp ret_temp p)
SEP (node_pred Tsh e p).
Definition del_node_spec :=
DECLARE _new_node
WITH e : Z, p : val
PRE [ _n OF tptr tnode ]
PROP ()
LOCAL (temp _n p)
SEP (node_pred Tsh e p)
POST [ tvoid ]
PROP ()
LOCAL ()
SEP ().
Definition tnode_pair := Tstruct _node_pair noattr.
Definition list_inv sh H h := node_pred sh Int.min_signed H * ghost_hist h H.
Definition locate_spec :=
DECLARE _locate
WITH e : Z, sh : share, H : val, h : hist
PRE [ _e OF tint ]
PROP (repable_signed e)
LOCAL (temp _e (vint e); gvar _head H)
SEP (list_inv sh H h)
POST [ tptr tnode_pair ]
EX h' : hist, EX p : val, EX n1 : val, EX n2 : val, EX e1 : Z, EX e2 : Z, EX sh : share,
PROP (incl h h'; e1 < e <= e2)
LOCAL ()
SEP (list_inv H h'; data_at Tsh tnode_pair (n1, n2) p; node_pred sh e1 n1;
field_at Tsh tnode [StructField _val] (vint e1) n1; field_at Tsh tnode [StructField _next] n2 n1;
node_pred sh e2 n2; node_lock_inv e2 n2).
Definition add_spec :=
DECLARE _add
WITH e : Z, H : val, h : hist
PRE [ _e OF tint ]
PROP (repable_signed e)
LOCAL (temp _e (vint e); gvar _head H)
SEP (list_inv H h)
POST [ tint ]
EX h' : hist, EX S : list Z, EX t' : nat,
PROP (incl h h'; apply_hist [] h' = S)
LOCAL (temp ret_temp (if in_dec Z_eq_dec e S then 0 else 1))
SEP (list_inv H (h' ++ [(t', Add e)]).
Definition remove_spec :=
DECLARE _remove
WITH e : Z, H : val, h : hist
PRE [ _e OF tint ]
PROP (repable_signed e)
LOCAL (temp _e (vint e); gvar _head H)
SEP (list_inv H h)
POST [ tint ]
EX h' : hist, EX S : list Z, EX t' : nat,
PROP (incl h h'; apply_hist [] h' = S)
LOCAL (temp ret_temp (if in_dec Z_eq_dec e S then 1 else 0))
SEP (list_inv H (h' ++ [(t', Remove e)]).
Definition main_spec :=
DECLARE _main
WITH u : unit
PRE  [] main_pre prog nil u
POST [ tint ] main_post prog nil u.
Definition Gprog : funspecs :=   ltac:(with_library prog [acquire_spec; release_spec; makelock_spec;
freelock_spec; surely_malloc_spec; new_node_spec; del_node_spec; locate_spec; add_spec; remove_spec; main_spec]).

(* Specifications: *)
Lemma body_surely_malloc: semax_body Vprog Gprog f_surely_malloc surely_malloc_spec.
Lemma ctr_inv_precise : forall p,
precise (cptr_lock_inv p).