(******************************************

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: 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.