Ltac gvar_headptr_intro_case1 gv H i :=
match goal with
| _ := gv i |- _ => fail 1
| H: isptr (gv i), H': headptr (gv i) |- _ => fail 1
| _ => generalize (H i _ ltac:(first[reflexivity | eassumption])); fancy_intro true
end.
Ltac gvar_headptr_intro_case2 gv H x i :=
match goal with
| H: isptr x, H': headptr x |- _ => fail 1
| _ => generalize ((H i _ ltac:(first[reflexivity | eassumption])): headptr x); fancy_intro true
end.
Ltac gvar_headptr_intro gv H:=
repeat
match goal with
| x:= gv ?i |- _ =>
gvar_headptr_intro_case2 gv H x i
| |- context [gv ?i] =>
gvar_headptr_intro_case1 gv H i
| _: context [gv ?i] |- _ =>
gvar_headptr_intro_case1 gv H i
| x:= context [gv ?i] |- _ =>
gvar_headptr_intro_case1 gv H i
end.
Fixpoint remove_localdef (x: localdef) (l: list localdef) : list localdef :=
match l with
| nil => nil
| y :: l0 =>
match x, y with
| temp i u, temp j v =>
if Pos.eqb i j
then remove_localdef x l0
else y :: remove_localdef x l0
| lvar i ti u, lvar j tj v =>
if Pos.eqb i j
then remove_localdef x l0
else y :: remove_localdef x l0
| _, _ => y :: remove_localdef x l0
end
end.
Definition localdef_tc (Delta: tycontext) (gvar_idents: list ident) (x: localdef): list Prop :=
match x with
| temp i v =>
match (temp_types Delta) ! i with
| Some t => tc_val t v :: nil
| _ => nil
end
| lvar _ _ v =>
isptr v :: headptr v :: nil
| gvars gv =>
VST_floyd_map (fun id => headptr (gv id)) gvar_idents
end.
Definition legal_glob_ident (Delta: tycontext) (i: ident): bool :=
match (glob_types Delta) ! i with
| Some _ => true
| _ => false
end.

(* Specifications: *)
Lemma localdef_local_facts: forall Delta gvar_ident x,
fold_right andb true (map (legal_glob_ident Delta) gvar_ident) = true ->
local (tc_environ Delta) && local (locald_denote x) |-- !! fold_right and True (localdef_tc Delta gvar_ident x).
Lemma go_lower_localdef_one_step_canon_left: forall Delta Ppre l Qpre Rpre post gvar_ident
(LEGAL: fold_right andb true (map (legal_glob_ident Delta) gvar_ident) = true),
local (tc_environ Delta) && PROPx (Ppre ++ localdef_tc Delta gvar_ident l) (LOCALx (l :: Qpre) (SEPx Rpre)) |-- post ->
local (tc_environ Delta) && PROPx Ppre (LOCALx (l :: Qpre) (SEPx Rpre)) |-- post.