End MEMORY_BLOCK_AGGREGATE.
Module aggregate_pred.
Open Scope Z.
Open Scope logic.
Definition array_pred: forall {A: Type}{d: Inhabitant A} (lo hi: Z) (P: Z -> A -> val -> mpred) (v: list A),
val -> mpred := @array_pred.
Definition struct_pred: forall (m: members) {A: ident * type -> Type} (P: forall it, A it -> val -> mpred) (v: compact_prod (map A m)) (p: val), mpred := @struct_pred.
Definition union_pred: forall (m: members) {A: ident * type -> Type} (P: forall it, A it -> val -> mpred) (v: compact_sum (map A m)) (p: val), mpred := @union_pred.
Definition array_Prop: forall {A: Type} (d:A) (lo hi: Z) (P: Z -> A -> Prop) (v: list A), Prop := @array_Prop.
Definition struct_Prop: forall (m: members) {A: ident * type -> Type} (P: forall it, A it -> Prop) (v: compact_prod (map A m)), Prop := @struct_Prop.
Definition union_Prop: forall (m: members) {A: ident * type -> Type} (P: forall it, A it -> Prop) (v: compact_sum (map A m)), Prop := union_Prop.
Definition array_pred_len_0: forall {A}{d: Inhabitant A} lo hi P p,
hi = lo ->
array_pred lo hi P nil p = emp
:= @array_pred_len_0.
Definition array_pred_len_1: forall {A}{d: Inhabitant A} i P v p,
array_pred i (i + 1) P (v :: nil) p =  P i v p
:= @array_pred_len_1.
Definition split_array_pred: forall  {A}{d: Inhabitant A} lo mid hi P v p,
lo <= mid <= hi ->
Zlength v = (hi-lo) ->
array_pred lo hi P v p =
array_pred lo mid P (sublist 0 (mid-lo) v) p *
array_pred mid hi P (sublist (mid-lo) (hi-lo) v) p
:= @split_array_pred.
Definition array_pred_shift: forall {A} {d: Inhabitant A} lo hi lo' hi' mv
P' P v p,
lo - lo' = mv ->
hi - hi' = mv ->
(forall i i', lo <= i < hi -> i - i' = mv ->
P' i' (Znth (i - lo) v) p = P i (Znth (i - lo) v) p) ->
array_pred lo' hi' P' v p = array_pred lo hi P v p
:= @array_pred_shift.
Definition array_pred_ext_derives:
forall {A B} {dA: Inhabitant A} {dB: Inhabitant B} lo hi P0 P1
(v0: list A) (v1: list B) p,
(Zlength v0 = hi - lo -> Zlength v1 = hi - lo) ->
(forall i, lo <= i < hi ->
P0 i (Znth (i-lo) v0) p |-- P1 i (Znth (i-lo) v1) p) ->
array_pred lo hi P0 v0 p |-- array_pred lo hi P1 v1 p
:= @array_pred_ext_derives.
Definition array_pred_ext:
forall {A B} {dA: Inhabitant A} {dB: Inhabitant B} lo hi P0 P1 (v0: list A) (v1: list B)  p,
Zlength v0 = Zlength v1 ->
(forall i, lo <= i < hi ->
P0 i (Znth (i - lo) v0) p = P1 i (Znth (i - lo) v1) p) ->
array_pred lo hi P0 v0 p = array_pred lo hi P1 v1 p
:= @array_pred_ext.
Definition at_offset_array_pred: forall {A} {d: Inhabitant A} lo hi P v ofs p,
at_offset (array_pred lo hi P v) ofs p = array_pred lo hi (fun i v => at_offset (P i v) ofs) v p
:= @at_offset_array_pred.
Definition array_pred_sepcon: forall  {A} {d: Inhabitant A} lo hi P Q v p,
array_pred lo hi P v p * array_pred lo hi Q v p = array_pred lo hi (P * Q) v p
:= @array_pred_sepcon.
Definition struct_pred_ramif: forall m {A} (P: forall it, A it -> val -> mpred) (i: ident) v p d,
in_members i m ->
members_no_replicate m = true ->
struct_pred m P v p |--
P _ (proj_struct i m v d) p *
allp ((fun v0: _ => P _ v0 p) -* (fun v0: _ => struct_pred m P (upd_struct i m v v0) p))
:= @struct_pred_ramif.
Definition struct_pred_ext_derives:
forall m {A0 A1} (P0: forall it, A0 it -> val -> mpred) (P1: forall it, A1 it -> val -> mpred) v0 v1 p,
members_no_replicate m = true ->
(forall i d0 d1, in_members i m ->
P0 _ (proj_struct i m v0 d0) p |-- P1 _ (proj_struct i m v1 d1) p) ->
struct_pred m P0 v0 p |-- struct_pred m P1 v1 p
:= @struct_pred_ext_derives.
Definition struct_pred_ext:
forall m {A0 A1} (P0: forall it, A0 it -> val -> mpred) (P1: forall it, A1 it -> val -> mpred) v0 v1 p,
members_no_replicate m = true ->
(forall i d0 d1, in_members i m ->
P0 _ (proj_struct i m v0 d0) p = P1 _ (proj_struct i m v1 d1) p) ->
struct_pred m P0 v0 p = struct_pred m P1 v1 p
:= @struct_pred_ext.
Definition at_offset_struct_pred: forall m {A} (P: forall it, A it -> val -> mpred) v p ofs,
at_offset (struct_pred m P v) ofs p = struct_pred m (fun it v => at_offset (P it v) ofs) v p
:= @at_offset_struct_pred.
Definition andp_struct_pred: forall m {A} (P: forall it, A it -> val -> mpred) v p Q,
corable Q ->
Q && struct_pred m P v p =
match m with
| nil => Q && emp
| _ => struct_pred m (fun it v p => Q && P it v p) v p
end
:= @corable_andp_struct_pred.
Definition struct_pred_sepcon: forall m {A} (P Q: forall it, A it -> val -> mpred) v p,
struct_pred m P v p * struct_pred m Q v p = struct_pred m (fun it => P it * Q it) v p
:= @struct_pred_sepcon.
Definition union_pred_ramif: forall m {A} (P: forall it, A it -> val -> mpred) (i: ident) v p d,
(forall i' (v': A (i', field_type i' m)), in_members i' m -> P _ v' p |-- P _ d p) ->
in_members i m ->
members_no_replicate m = true ->
union_pred m P v p |--
P _ (proj_union i m v d) p *
allp ((fun v0: _ => P _ v0 p) -* (fun v0 =>union_pred m P (upd_union i m v v0) p))
:= @union_pred_ramif.
Definition union_pred_ext_derives:
forall m {A0 A1} (P0: forall it, A0 it -> val -> mpred) (P1: forall it, A1 it -> val -> mpred) v0 v1 p,
members_no_replicate m = true ->
(forall it, members_union_inj v0 it <-> members_union_inj v1 it) ->
(forall i d0 d1, members_union_inj v0 (i, field_type i m) -> members_union_inj v1 (i, field_type i m) ->
P0 _ (proj_union i m v0 d0) p |-- P1 _ (proj_union i m v1 d1) p) ->
union_pred m P0 v0 p |-- union_pred m P1 v1 p
:= @union_pred_ext_derives.
Definition union_pred_ext:
forall m {A0 A1} (P0: forall it, A0 it -> val -> mpred) (P1: forall it, A1 it -> val -> mpred) v0 v1 p,
members_no_replicate m = true ->
(forall it, members_union_inj v0 it <-> members_union_inj v1 it) ->
(forall i d0 d1, members_union_inj v0 (i, field_type i m) -> members_union_inj v1 (i, field_type i m) ->
P0 _ (proj_union i m v0 d0) p = P1 _ (proj_union i m v1 d1) p) ->
union_pred m P0 v0 p = union_pred m P1 v1 p
:= @union_pred_ext.
Definition at_offset_union_pred: forall m {A} (P: forall it, A it -> val -> mpred) v p ofs,
at_offset (union_pred m P v) ofs p = union_pred m (fun it v => at_offset (P it v) ofs) v p
:= at_offset_union_pred.
Definition andp_union_pred: forall m {A} (P: forall it, A it -> val -> mpred) v p Q,
Q && union_pred m P v p =
match m with
| nil => Q && emp
| _ => union_pred m (fun it v p => Q && P it v p) v p
end
:= @andp_union_pred.
Definition union_pred_sepcon: forall m {A} (P Q: forall it, A it -> val -> mpred) v p,
union_pred m P v p * union_pred m Q v p = union_pred m (fun it => P it * Q it) v p
:= @union_pred_sepcon.
Definition struct_Prop_compact_prod_gen: forall m (F: ident * type -> Type) (P: forall it, F it -> Prop) (f: forall it, F it),
members_no_replicate m = true ->
(forall i, in_members i m -> P (i, field_type i m) (f (i, field_type i m))) ->
struct_Prop m P (compact_prod_gen f m)
:= @struct_Prop_compact_prod_gen.
Definition struct_Prop_proj: forall m (F: ident * type -> Type) (P: forall it, F it -> Prop) v i d,
in_members i m ->
struct_Prop m P v ->
P (i, field_type i m) (proj_struct i m v d)
:= @struct_Prop_proj.
Definition union_Prop_compact_sum_gen: forall m (F: ident * type -> Type) (P: forall it, F it -> Prop) (f: forall it, F it),
members_no_replicate m = true ->
(forall i, in_members i m -> P (i, field_type i m) (f (i, field_type i m))) ->
union_Prop m P (compact_sum_gen (fun _ => true) f m)
:= @union_Prop_compact_sum_gen.
Definition union_Prop_proj: forall m (F: ident * type -> Type) (P: forall it, F it -> Prop) v i d,
members_union_inj v (i, field_type i m) ->
union_Prop m P v ->
P (i, field_type i m) (proj_union i m v d)
:= @union_Prop_proj.
Definition array_pred_local_facts: forall {A} {d: Inhabitant A} lo hi P v p Q,
(forall i x, lo <= i < hi -> P i x p |-- !! Q x) ->
array_pred lo hi P v p |-- !! (Zlength v = hi - lo /\ Forall Q v)
:= @array_pred_local_facts.
Definition struct_pred_local_facts: forall m {A} (P: forall it, A it -> val -> mpred)v p (R: forall it, A it -> Prop),
members_no_replicate m = true ->
(forall i v0, in_members i m -> P (i, field_type i m) v0 p |-- !! R _ v0) ->
struct_pred m P v p |-- !! struct_Prop m R v
:= @struct_pred_local_facts.
Definition union_pred_local_facts: forall m {A} (P: forall it, A it -> val -> mpred)v p (R: forall it, A it -> Prop),
members_no_replicate m = true ->
(forall i v0, in_members i m -> P (i, field_type i m) v0 p |-- !! R _ v0) ->
union_pred m P v p |-- !! union_Prop m R v
:= @union_pred_local_facts.
End aggregate_pred.
(******************************************  Auxiliary predicates  ******************************************)
Section AUXILIARY_PRED.
Context {cs: compspecs}.
Variable sh: share.
Definition struct_data_at_rec_aux (m m0: members) (sz: Z) (P: ListType (map (fun it => reptype (field_type (fst it) m0) -> (val -> mpred)) m)) (v: compact_prod (map (fun it => reptype (field_type (fst it) m0)) m)) : (val -> mpred).

(* Specifications: *)
Lemma union_data_at_rec_aux_spec: forall m m0 sz v P,
union_data_at_rec_aux m m0 sz
(ListTypeGen
(fun it => reptype (field_type (fst it) m0) -> val -> mpred)
P m) v =
union_pred m
(fun it v =>
withspacer sh
(sizeof (field_type (fst it) m0))
sz
(P it v)) v.