Module VerifHeadSwitch.
Definition head_pointer_switch_spec :=
DECLARE _head_pointer_switch
WITH sh : share, l: val, p: val, x: int, s: list int, y: int
PRE [ _l OF (tptr t_struct_list) , _p OF (tptr tint)]
PROP  (writable_share sh)
LOCAL (temp _l l; temp _p p)
SEP   (listrep sh (x :: s) l; data_at sh tint (Vint y) p)
POST [ tvoid ]
PROP  ()
LOCAL ()
SEP   (listrep sh (y :: s) l; data_at sh tint (Vint x) p).
Definition head_head_switch_spec :=
DECLARE _head_head_switch
WITH sh : share, l1: val, l2: val, h1: int, t1: list int, h2: int, t2: list int
PRE [ _l1 OF (tptr t_struct_list) , _l OF (tptr t_struct_list)]
PROP  (writable_share sh)
LOCAL (temp _l1 l1; temp _l2 l2)
SEP   (listrep sh (h1 :: t1) l1; listrep sh (h2 :: t2) l2)
POST [ tvoid ]
PROP  ()
LOCAL ()
SEP   (listrep sh (h2 :: t1) l1; listrep sh (h1 :: t2) l2).
Definition Gprog : funspecs :=
ltac:(with_library prog [ head_pointer_switch_spec; head_head_switch_spec]).

(* TODO: try use sep_apply in this proof instead of cancel, sepcon_comm. *)
Lemma body_head_pointer_switch: semax_body Vprog Gprog f_head_pointer_switch head_pointer_switch_spec.