(*Require Import VST.floyd.fieldlist.*)
(*Require Import VST.floyd.aggregate_type.*)
Require Export VST.floyd.fieldlist.
Require Export VST.floyd.aggregate_type.
Open Scope Z.
Open Scope logic.
(******************************************  Definition and lemmas about rangespec  ******************************************)
Fixpoint rangespec (lo: Z) (n: nat) (P: Z -> val -> mpred): val -> mpred :=
match n with
| O => fun _ => emp
| S n' => P lo * rangespec (Z.succ lo) n' P
end.
Fixpoint fold_range' {A: Type} (f: Z -> A -> A) (zero: A) (lo: Z) (n: nat) : A :=
match n with
| O => zero
| S n' => f lo (fold_range' f  zero (Z.succ lo) n')
end.
Definition fold_range {A: Type} (f: Z -> A -> A) (zero: A) (lo hi: Z) : A :=
fold_range' f zero lo (Z.to_nat (hi-lo)).

(* Specifications: *)
Lemma rangespec_shift_derives: forall lo lo' len P P' p p',
(forall i i', lo <= i < lo + Z_of_nat len -> i - lo = i' - lo' -> P i p |-- P' i' p') ->
rangespec lo len P p |-- rangespec lo' len P' p'.
Lemma rangespec_ext_derives: forall lo len P P' p,
(forall i, lo <= i < lo + Z_of_nat len -> P i p |-- P' i p) ->
rangespec lo len P p |-- rangespec lo len P' p.
Lemma rangespec_shift: forall lo lo' len P P' p p',
(forall i i', lo <= i < lo + Z_of_nat len -> i - lo = i' - lo' -> P i p = P' i' p') ->
rangespec lo len P p = rangespec lo' len P' p'.
Lemma rangespec_ext: forall lo len P P' p,
(forall i, lo <= i < lo + Z_of_nat len -> P i p = P' i p) ->
rangespec lo len P p = rangespec lo len P' p.
Lemma rangespec_sepcon: forall lo len P Q p,
rangespec lo len P p * rangespec lo len Q p = rangespec lo len (P * Q) p.
Lemma rangespec_elim: forall lo len P i,
lo <= i < lo + Z_of_nat len -> rangespec lo len P |-- P i * TT.