Notation "'TYPE' A 'WITH'  x1 : t1 , x2 : t2 , x3 : t3 , x4 : t4 , x5 : t5 'PRE'  [ u , .. , v ] P 'POST' [ tz ] Q" :=
(mk_funspec ((cons u%formals .. (cons v%formals nil) ..), tz) cc_default A
(fun (ts: list Type) (x: t1*t2*t3*t4*t5) =>
match x with (x1,x2,x3,x4,x5) => P%assert end)
(fun (ts: list Type) (x: t1*t2*t3*t4*t5) =>
match x with (x1,x2,x3,x4,x5) => 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,
P at level 100, Q at level 100).
Definition lock_sig := (ProdType (ConstType (share * val * val * val)) Mpred).
(* funspecs for acquire and release *)
Program Definition my_acquire_spec :=
DECLARE _my_acquire TYPE lock_sig
WITH sh : share, l : val, p : val, g : val, R : mpred
PRE [ _l OF tptr tint, _ll OF tptr (Tstruct _lock_t noattr) ]
PROP (readable_share sh)
LOCAL (temp _l p; temp _ll l)
SEP (my_lock sh l p g R)
POST [ tvoid ]
PROP ()
LOCAL ()
SEP (my_lock sh l p g R; R).
Next Obligation.
Next Obligation.
Program Definition my_release_spec :=
DECLARE _my_release TYPE lock_sig
WITH sh : share, l : val, p : val, g : val, R : mpred
PRE [ _l OF tptr tint, _ll OF tptr (Tstruct _lock_t noattr) ]
PROP (readable_share sh)
LOCAL (temp _l p; temp _ll l)
SEP (my_lock sh l p g R; R)
POST [ tvoid ]
PROP ()
LOCAL ()
SEP (my_lock sh l p g R).
Next Obligation.
Next Obligation.
Definition Gprog : funspecs := ltac:(with_library prog [acquire_spec; release_spec; atomic_exchange_spec;
my_acquire_spec; my_release_spec]).

Lemma weak_precise_lock_R : forall R h v, predicates_hered.derives
(weak_precise_mpred R && emp) (weak_precise_mpred (lock_R R h v) && emp).