Section FUNSPEC.
Definition genviron := Map.t block.
Definition venviron := Map.t (block * type).
Definition tenviron := Map.t val.
Inductive environ : Type :=
mkEnviron: forall (ge: genviron) (ve: venviron) (te: tenviron), environ.
Definition ge_of (rho: environ) : genviron :=
match rho with mkEnviron ge ve te => ge end.
Definition ve_of (rho: environ) : venviron :=
match rho with mkEnviron ge ve te => ve end.
Definition te_of (rho: environ) : tenviron :=
match rho with mkEnviron ge ve te => te end.
Definition any_environ : environ :=
mkEnviron (fun _ => None)  (Map.empty _) (Map.empty _).
Definition mpred := pred rmap.
Definition AssertTT (A: TypeTree): TypeTree :=
ArrowType A (ArrowType (ConstType environ) Mpred).
Definition SpecTT (A: TypeTree): TypeTree :=
ArrowType A (ArrowType (ConstType bool) (ArrowType (ConstType environ) Mpred)).
Definition super_non_expansive {A: TypeTree}
(P: forall ts, dependent_type_functor_rec ts (AssertTT A) mpred): Prop :=
forall n ts
(x: functors.MixVariantFunctor._functor
(rmaps.dependent_type_functor_rec ts A) mpred)
(rho: environ),
approx n (P ts x rho) = approx n (P ts (fmap _ (approx n) (approx n) x) rho).
Definition const_super_non_expansive: forall (T: Type) P,
@super_non_expansive (ConstType T) P :=
fun _ _ _ _ _ _ => eq_refl.
(*Potential alternative that does not use Ctypes Inductive funspec := mk_funspec: AST.signature -> forall (A: TypeTree) (P Q: forall ts, dependent_type_functor_rec ts (AssertTT A) mpred) (P_ne: super_non_expansive P) (Q_ne: super_non_expansive Q), funspec. *)
Inductive funspec :=
mk_funspec: funsig -> calling_convention -> forall (A: TypeTree)
(P Q: forall ts, dependent_type_functor_rec ts (AssertTT A) mpred)
(P_ne: super_non_expansive P) (Q_ne: super_non_expansive Q),
funspec.
Definition varspecs : Type := list (ident * type).
Definition funspecs := list (ident * funspec).
End FUNSPEC.
(*Lenb: moved here from mapsto_memory_block.v*)
Definition assert := environ -> mpred.  (* Unfortunately
can't export this abbreviation through SeparationLogic.v because
it confuses the Lift system *)
(*Lenb: moved packPQ here from res_predicates.v*)
Definition packPQ {A: rmaps.TypeTree}
(P Q: forall ts, dependent_type_functor_rec ts (AssertTT A) (pred rmap)):
forall ts, dependent_type_functor_rec ts (SpecTT A) (pred rmap) :=
fun ts a b => if b then P ts a else Q ts a.
(*moved here from Clight_lemmas*)
Definition int_range (sz: intsize) (sgn: signedness) (i: int) :=
match sz, sgn with
| I8, Signed => -128 <= Int.signed i < 128
| I8, Unsigned => 0 <= Int.unsigned i < 256
| I16, Signed => -32768 <= Int.signed i < 32768
| I16, Unsigned => 0 <= Int.unsigned i < 65536
| I32, Signed => -2147483648 <= Int.signed i < 2147483648
| I32, Unsigned => 0 <= Int.unsigned i < 4294967296
| IBool, _ => 0 <= Int.unsigned i < 256
end.
Definition in_members i (m: members): Prop :=
In i (map fst m).
Definition members_no_replicate (m: members) : bool :=
compute_list_norepet (map fst m).
Definition compute_in_members id (m: members): bool :=
id_in_list id (map fst m).
Ltac destruct_in_members i m :=
let H := fresh "H" in
destruct (compute_in_members i m) eqn:H;
[apply compute_in_members_true_iff in H |
apply compute_in_members_false_iff in H].

Lemma in_members_dec: forall i m, {in_members i m} + {~ in_members i m}.