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

	ITERATED SUMS
*)

Fixpoint sum_nm (n : nat) : nat -> (nat -> nat) -> nat :=
  fun (m : nat) (f : nat -> nat) =>
  match n with
  | O => f m
  | S n' => f m + sum_nm n' (S m) f
  end.

(* Specifications: *)
Lemma sum_nm_i : forall (m n : nat) (f : nat -> nat), sum_nm (S n) m f = f m + sum_nm n (S m) f.
Lemma sum_nm_f : forall (m n : nat) (f : nat -> nat), sum_nm (S n) m f = sum_nm n m f + f (m + S n).
Lemma sum_nm_ext : forall (m n : nat) (f g : nat -> nat), (forall x : nat, x <= n -> f (m + x) = g (m + x)) -> sum_nm n m f = sum_nm n m g.
Lemma sum_nm_add : forall (m n : nat) (f g : nat -> nat), sum_nm n m f + sum_nm n m g = sum_nm n m (fun i : nat => f i + g i).
Lemma sum_nm_times : forall (m n x : nat) (f : nat -> nat), x * sum_nm n m f = sum_nm n m (fun i : nat => x * f i).
Lemma inv_sum_nm : forall (P : nat -> Prop) (i n : nat) (f : nat -> nat), (forall a b : nat, P a -> P b -> P (a + b)) -> (forall x : nat, x <= n -> P (f (i + x))) -> P (sum_nm n i f).
Lemma t_sum_Svars : forall (n k : nat) (f : nat -> nat), sum_nm k n f = sum_nm k (S n) (fun i : nat => f (pred i)).