Local Open Scope logic.
Inductive local2list:
list (environ -> Prop) -> list (ident * val) -> list (ident * (type * val)) -> list (environ -> Prop) -> Prop :=
| local2list_nil:
local2list nil (nil) (nil) nil
| local2list_temp_var: forall v i Q T1 T2 Q',
local2list Q T1 T2 Q'->
local2list (`(eq v) (eval_id i) :: Q) (cons (i, v) T1) T2 Q'
| local2list_gl_var: forall v i t Q T1 T2 Q',
local2list Q T1 T2 Q'->
local2list (`(eq v) (eval_var i t) :: Q) T1 (cons (i, (t, v)) T2) Q'
| local2list_unknown: forall Q0 Q T1 T2 Q',
local2list Q T1 T2 Q'->
local2list (Q0 :: Q) T1 T2 (Q0 :: Q').
(* repeat constructor will try the first succesful tactic. So local2list_temp_ *)
(* var, local2list_gl_var will be used whenever is possible before local2list_*)
(* unknown.                                                                     *)
Module TEST.
Goal False.
evar (T1: list (ident * val)).
evar (T2: list (ident * (type * val))).
evar (Q' : list (environ -> Prop)).
assert (local2list  ((`(eq Vundef) (eval_id 1%positive)) :: (`(eq (Vint (Int.repr 1))) (eval_id 1%positive)) ::
(`(eq 1 3)) :: nil)
T1 T2 Q').
subst T1 T2 Q'.
repeat constructor; repeat simpl; auto.
simpl in H.
Abort.
Goal False.
evar (T1: list (ident * val)).
evar (T2: list (ident * (type * val))).
evar (Q' : list (environ -> Prop)).
assert (local2list ((`(eq Vundef) (eval_id 1%positive))::nil) T1 T2 Q').
subst T1 T2 Q'.
repeat constructor; repeat simpl; auto.
Abort.
End TEST.
Definition localtempD (p : (ident * val)) := let (i, v) := p in `(eq v) (eval_id i).
Definition localvarD (p : ident * (type * val))  := let (i, tv) := p in `(eq (snd tv)) (eval_var i (fst tv)).
Definition LocallistD (T1: list (ident * val)) (T2: list (ident * (type * val))) (Q: list (environ -> Prop)) :=
map localtempD T1 ++ map localvarD T2 ++ Q.

Lemma local2list_soundness: forall P Q R T1 T2 Q',
local2list Q T1 T2 Q' ->
PROPx P (LOCALx Q (SEPx R)) = PROPx P (LOCALx (LocallistD T1 T2 Q') (SEPx R)).