Require Export VST.veric.base.
Require Export VST.veric.shares.
Local Open Scope pred.
Definition func_at (f: funspec): address -> pred rmap :=
match f with
| mk_funspec fsig cc A P Q _ _ => pureat (SomeP (SpecTT A) (packPQ P Q)) (FUN fsig cc)
end.
Definition func_at' (f: funspec) (loc: address) : pred rmap :=
match f with
| mk_funspec fsig cc _ _ _ _ _ => EX pp:_, pureat pp (FUN fsig cc) loc
end.
Definition func_ptr (f: funspec) (v: val): mpred :=
EX b: block, !! (v = Vptr b Ptrofs.zero) && func_at f (b, 0).
Definition NDmk_funspec (f: funsig) (cc: calling_convention)
(A: Type) (Pre Post: A -> environ -> mpred): funspec :=
mk_funspec f cc (rmaps.ConstType A) (fun _ => Pre) (fun _ => Post)
(const_super_non_expansive _ _) (const_super_non_expansive _ _).
(* Definition assert: Type := environ -> pred rmap. *)
Bind Scope pred with assert.
Local Open Scope pred.
Definition closed_wrt_vars {B} (S: ident -> Prop) (F: environ -> B) : Prop :=
forall rho te',
(forall i, S i \/ Map.get (te_of rho) i = Map.get te' i) ->
F rho = F (mkEnviron (ge_of rho) (ve_of rho) te').
Definition closed_wrt_lvars {B} (S: ident -> Prop) (F: environ -> B) : Prop :=
forall rho ve',
(forall i, S i \/ Map.get (ve_of rho) i = Map.get ve' i) ->
F rho = F (mkEnviron (ge_of rho) ve' (te_of rho)).
Definition not_a_param (params: list (ident * type)) (i : ident) : Prop :=
~ In i (map (@fst _ _) params).
Definition is_a_local (vars: list (ident * type)) (i: ident) : Prop :=
In  i (map (@fst _ _) vars) .
Fixpoint sepcon_list {A}{JA: Join A}{PA: Perm_alg A}{SA: Sep_alg A}{AG: ageable A} {AgeA: Age_alg A}
(p: list (pred A)) : pred A :=
match p with nil => emp | h::t => h * sepcon_list t end.
Definition typed_true (t: type) (v: val)  : Prop := strict_bool_val v t
= Some true.
Definition typed_false (t: type)(v: val) : Prop := strict_bool_val v t =
Some false.
Definition subst {A} (x: ident) (v: val) (P: environ -> A) : environ -> A :=
fun s => P (env_set s x v).

Lemma approx_func_ptr: forall (A: Type) fsig0 cc (P Q: A -> environ -> mpred) (v: val) (n: nat),
approx n (func_ptr (NDmk_funspec fsig0 cc A P Q) v) = approx n (func_ptr (NDmk_funspec fsig0 cc A (fun a rho => approx n (P a rho)) (fun a rho => approx n (Q a rho))) v).