proposition: Lemma lseg_unfold (ls: listspec list_structid list_link list_token): forall sh contents v1 v2, lseg ls sh contents v1 v2 = match contents with | h::t => !! (~ ptr_eq v1 v2) && EX tail: val, !! is_pointer_or_null tail && list_token sh v1 * list_cell ls sh h v1 * field_at sh list_struct (StructField list_link :: nil) (valinject (nested_field_type list_struct (StructField list_link :: nil)) tail) v1 * lseg ls sh t tail v2 | nil => !! (ptr_eq v1 v2) && emp end.
proof: Proof. intros. unfold lseg. revert v1; induction contents; intros. apply pred_ext. normalize. destruct al; inv H. rewrite LsegGeneral.lseg_nil_eq; auto. apply exp_right with nil. apply derives_extract_prop; intro. normalize. apply pred_ext. apply exp_left; intros [ | [v1' a'] al]. normalize. inv H. apply derives_extract_prop; intro. symmetry in H; inv H. rewrite LsegGeneral.lseg_cons_eq; auto. apply derives_extract_prop; intros [? ?]. simpl in H; subst v1'. apply exp_left; intro y. normalize. apply exp_right with y. normalize. repeat apply sepcon_derives; auto. apply exp_right with al; normalize. normalize. apply exp_right with ((v1,a)::al); normalize. simpl. normalize. apply exp_right with tail. normalize. autorewrite with subst norm1 norm2; normalize. Qed.
imports: VST.floyd.base2 VST.floyd.client_lemmas VST.floyd.closed_lemmas VST.floyd.nested_pred_lemmas VST.floyd.nested_field_lemmas VST.floyd.efield_lemmas VST.floyd.mapsto_memory_block VST.floyd.reptype_lemmas VST.floyd.data_at_rec_lemmas VST.floyd.field_at VST.floyd.nested_loadstore VST.floyd.entailer