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].
Definition composite_legal_fieldlist (co: composite): Prop :=
members_no_replicate (co_members co) = true.
Definition composite_env_legal_fieldlist env :=
forall (id : positive) (co : composite),
env ! id = Some co -> composite_legal_fieldlist co.
Class compspecs := mkcompspecs {
cenv_cs : composite_env;
cenv_consistent: composite_env_consistent cenv_cs;
cenv_legal_fieldlist: composite_env_legal_fieldlist cenv_cs;
cenv_legal_su: composite_env_complete_legal_cosu_type cenv_cs;
ha_env_cs: PTree.t Z;
ha_env_cs_consistent: hardware_alignof_env_consistent cenv_cs ha_env_cs;
ha_env_cs_complete: hardware_alignof_env_complete cenv_cs ha_env_cs;
la_env_cs: PTree.t legal_alignas_obs;
la_env_cs_consistent: legal_alignas_env_consistent cenv_cs ha_env_cs la_env_cs;
la_env_cs_complete: legal_alignas_env_complete cenv_cs la_env_cs;
la_env_cs_sound: legal_alignas_env_sound cenv_cs ha_env_cs la_env_cs
}.
Existing Class composite_env.
Existing Instance cenv_cs.
Arguments sizeof {env} !t / .
Arguments alignof {env} !t / .
Arguments sizeof_pos {env} t _.
Arguments alignof_pos {env} t.
Arguments complete_legal_cosu_type {cenv} !t / .
(* TODO: handle other part of compspecs like this. *)
Goal forall {cs: compspecs} t, sizeof t >= 0.
Hint Rewrite eval_id_same : normalize.

Lemma eval_id_other: forall rho id id' v,
id<>id' -> eval_id id' (env_set rho id v) = eval_id id' rho.