Library Waterproof.Libs.Analysis.FiniteSums
From Stdlib Require Import Classical.
From Stdlib Require Import Classical_Pred_Type.
From Stdlib Require Export Reals.Reals.
From Stdlib Require Export Reals.Rsigma.
From Stdlib Require Import ClassicalChoice.
From Stdlib Require Import FunctionalExtensionality.
From Stdlib Require Import Arith.
Open Scope R_scope.
Declare Scope sum_scope.
Notation "'Σ' '[' i '=' m ',' n ']' e" :=
(sigma (fun i => e) m n)
(at level 50, i ident)
: sum_scope.
Local Ltac simpl_INR :=
repeat (
rewrite plus_INR ||
rewrite mult_INR ||
rewrite S_INR ||
rewrite INR_0 ||
rewrite INR_1
).
Local Lemma lt_plus_S : forall m k : nat, (m < m + S k)%nat.
Proof.
intros m k.
rewrite <- Nat.add_succ_comm.
apply Nat.lt_lt_add_r.
apply Nat.lt_succ_diag_r.
Qed.
Local Lemma Nat_double_S :
forall n : nat, (2 * S n)%nat = S (S (2 * n))%nat.
Proof.
intro n. unfold Nat.mul. rewrite Nat.add_0_r, Nat.add_0_r, Nat.add_succ_r.
apply Nat.add_succ_l.
Qed.
Local Lemma Nat_pred_double_l :
forall n : nat, (0 < n)%nat ->
(Nat.pred (2 * n))%nat = S (2 * Nat.pred n)%nat.
Proof.
intros n Hn. unfold Nat.mul.
rewrite Nat.add_0_r, Nat.add_0_r.
rewrite <- Nat.add_pred_r.
rewrite <- Nat.add_succ_l.
rewrite Nat.succ_pred. reflexivity.
all: symmetry; apply Nat.lt_neq; assumption.
Qed.
Local Lemma sigma_eq_length :
forall (f g : nat -> R) (m k : nat),
(forall i : nat, (m <= i)%nat -> (i <= m+k)%nat -> f i = g i) ->
sigma f m (m+k)%nat = sigma g m (m+k)%nat.
Proof.
intros f g m. induction k; intro Heq.
- rewrite <- plus_n_O.
rewrite sigma_eq_arg. rewrite sigma_eq_arg. apply Heq.
2: rewrite <- plus_n_O. all: apply Nat.le_refl.
- rewrite (sigma_last f). rewrite (sigma_last g).
rewrite <- Nat.add_succ_comm at 2 4. rewrite Nat.add_succ_l. rewrite Nat.pred_succ.
rewrite IHk. f_equal. apply Heq. apply Nat.le_add_r. apply Nat.le_refl.
{ intros i Hbot Htop. apply Heq. assumption.
rewrite <- Nat.add_succ_comm. apply (Nat.le_le_succ_r _ _ Htop). }
all: apply Nat.lt_add_pos_r; apply Nat.lt_0_succ.
Qed.
Theorem sigma_eq :
forall (f g : nat -> R) (m n : nat), (m <= n)%nat ->
(forall i : nat, (m <= i)%nat -> (i <= n)%nat -> f i = g i) ->
sigma f m n = sigma g m n.
Proof.
intros f g m n Hleq Heq.
rewrite <- (Arith_base.le_plus_minus_r_stt m n).
apply sigma_eq_length.
rewrite Arith_base.le_plus_minus_r_stt.
intros i Hibot Hitop.
apply Heq. all: assumption.
Qed.
Local Lemma sigma_distr_l_len :
forall (f : nat -> R) (c : R) (m k : nat),
sigma (fun i => c * f i) m (m+k) = c * (sigma f m (m+k)).
Proof.
intros f c m. induction k.
- rewrite <- plus_n_O.
rewrite sigma_eq_arg.
rewrite sigma_eq_arg.
reflexivity.
- rewrite (sigma_last f (lt_plus_S _ _)).
rewrite (sigma_last _ (lt_plus_S _ _)).
rewrite Nat.add_succ_r at 2 4. rewrite Nat.pred_succ.
rewrite Rmult_plus_distr_l.
rewrite IHk. reflexivity.
Qed.
Theorem sigma_distr_l :
forall (f : nat -> R) (c : R) (m n : nat), (m <= n)%nat ->
sigma (fun i => c * f(i)) m n = c * (sigma f m n).
Proof.
intros f c m n Hleq.
rewrite <- (Arith_base.le_plus_minus_r_stt m n).
apply sigma_distr_l_len.
assumption.
Qed.
Local Lemma sigma_distr_r_len :
forall (f : nat -> R) (c : R) (m k : nat),
sigma (fun i => f i * c) m (m+k) = c * (sigma f m (m+k)).
Proof.
intros f c m. induction k.
- rewrite <- plus_n_O.
rewrite sigma_eq_arg.
rewrite sigma_eq_arg.
apply Rmult_comm.
- rewrite (sigma_last f (lt_plus_S _ _)).
rewrite (sigma_last _ (lt_plus_S _ _)).
rewrite Nat.add_succ_r at 2 4. rewrite Nat.pred_succ.
rewrite Rmult_plus_distr_l.
rewrite IHk. f_equal. apply Rmult_comm.
Qed.
Theorem sigma_distr_r :
forall (f : nat -> R) (c : R) (m n : nat), (m <= n)%nat ->
sigma (fun i => f(i) * c) m n = c * (sigma f m n).
Proof.
intros f c m n Hleq.
rewrite <- (Arith_base.le_plus_minus_r_stt m n).
apply sigma_distr_r_len.
assumption.
Qed.
Local Lemma sigma_comm_len :
forall (f g : nat -> R) (m k : nat),
sigma f m (m+k) + sigma g m (m+k) = sigma (fun i => f i + g i) m (m+k).
Proof.
intros f g m. induction k.
- rewrite <- plus_n_O.
rewrite sigma_eq_arg.
rewrite sigma_eq_arg.
rewrite sigma_eq_arg.
reflexivity.
- assert (Hleq : (m < m + S k)%nat).
{ apply (lt_plus_S m k). }
rewrite (sigma_last f Hleq).
rewrite (sigma_last g Hleq).
rewrite (sigma_last _ Hleq).
rewrite Nat.add_succ_r at 2 4 7. rewrite Nat.pred_succ.
rewrite <- IHk,
<- Rplus_assoc,
(Rplus_assoc (f (m + S k)%nat)),
(Rplus_comm _ (g (m + S k)%nat)),
<- Rplus_assoc,
<- Rplus_assoc.
reflexivity.
Qed.
Theorem sigma_comm :
forall (f g : nat -> R) (m n : nat), (m <= n)%nat ->
sigma f m n + sigma g m n = sigma (fun i => f i + g i) m n.
Proof.
intros f g m n Hleq.
rewrite <- (Arith_base.le_plus_minus_r_stt m n).
apply sigma_comm_len.
assumption.
Qed.
Theorem sigma_shift_add :
forall (f : nat -> R) (m n s : nat),
sigma f m n = sigma (fun i => f (i - s)%nat) (m+s)%nat (n+s)%nat.
Proof.
intros f m n s. unfold sigma.
rewrite (Nat.add_comm m s) at 1. rewrite Nat.sub_add_distr. rewrite Nat.add_sub.
f_equal. extensionality k. f_equal.
rewrite Nat.add_shuffle0. symmetry. apply Nat.add_sub.
Qed.
Theorem sigma_shift_sub :
forall (f : nat -> R) (m n s : nat), (s <= m)%nat -> (m <= n)%nat ->
sigma f m n = sigma (fun i => f (i + s)%nat) (m-s)%nat (n-s)%nat.
Proof.
intros f m n s H1 H2. unfold sigma.
rewrite <- Nat.sub_add_distr. rewrite Nat.add_sub_assoc.
rewrite Nat.add_comm. rewrite Nat.add_sub.
f_equal. extensionality k. f_equal.
rewrite <- Nat.add_assoc. rewrite (Nat.add_comm k s). rewrite Nat.add_assoc.
rewrite Nat.sub_add. reflexivity. all: assumption.
Qed.
Theorem sigma_rev0 :
forall (f : nat -> R) (k : nat),
sigma f 0 k = sigma (fun i => f (k - i)%nat) 0 k.
Proof.
intro f. induction k.
- rewrite sigma_eq_arg. rewrite sigma_eq_arg.
f_equal.
- rewrite (sigma_last f).
rewrite (@sigma_first _ _ (S k)).
rewrite Nat.pred_succ.
rewrite IHk.
f_equal. all: apply Nat.lt_0_succ.
Qed.
Local Lemma sigma_rev_length :
forall (f : nat -> R) (m k : nat),
sigma f m (m+k) = sigma (fun i => f (m + k - i)%nat) 0 k.
Proof.
intros f m k.
rewrite (sigma_shift_sub _ _ _ m).
rewrite Nat.sub_diag.
rewrite Nat.add_comm. rewrite Nat.add_sub.
rewrite sigma_rev0.
assert (
forall i : nat, (0 <= i)%nat -> (i <= k)%nat ->
f (k - i + m)%nat = f (m + k - i)%nat
) as Heq.
{ intros i Hbot Htop. f_equal.
rewrite <- (Nat.add_sub_swap _ _ _ Htop).
rewrite Nat.add_comm. reflexivity.
}
apply sigma_eq. apply Nat.le_0_l.
intros i Hbot Htop. f_equal. symmetry. apply (Nat.add_sub_swap _ _ _ Htop).
apply Nat.le_refl. apply Nat.le_add_r.
Qed.
Theorem sigma_rev :
forall (f : nat -> R) (m n : nat), (m <= n)%nat ->
sigma f m n = sigma (fun i => f (n - i)%nat) 0 (n-m)%nat.
Proof.
intros f m n Hmn.
rewrite <- (Arith_base.le_plus_minus_r_stt m n).
rewrite (Arith_base.le_plus_minus_r_stt m n) at 2.
apply sigma_rev_length. all: assumption.
Qed.
Local Lemma sigma_telescope_length :
forall (f : nat -> R) (m k : nat),
f (S m + k)%nat - f m = sigma (fun i => f (S i)%nat - f i) m (m + k)%nat.
Proof.
intros f m. induction k.
- rewrite Nat.add_0_r. rewrite Nat.add_0_r.
rewrite sigma_eq_arg. reflexivity.
- rewrite sigma_last.
rewrite (Nat.add_succ_r m) at 3. rewrite Nat.pred_succ.
rewrite Nat.add_succ_l.
rewrite <- IHk.
rewrite Rplus_minus_assoc. f_equal. rewrite <- Rplus_minus_swap.
rewrite Nat.add_succ_comm.
symmetry. apply Rplus_minus_r.
apply lt_plus_S.
Qed.
Theorem sigma_telescope :
forall (f : nat -> R) (m n : nat), (m <= n)%nat ->
f (S n) - f m = sigma (fun i => f (S i) - f i) m n.
Proof.
intros f m n Hmn.
rewrite <- (Arith_base.le_plus_minus_r_stt m n).
apply sigma_telescope_length.
assumption.
Qed.
Theorem sigma_telescope_plus1 :
forall (f : nat -> R) (m n : nat), (m <= n)%nat ->
f (n + 1)%nat - f m = sigma (fun i => f (i + 1)%nat - f i) m n.
Proof.
intros f m n Hmn. rewrite Nat.add_1_r.
rewrite sigma_telescope.
f_equal. extensionality i.
rewrite Nat.add_1_r. reflexivity.
assumption.
Qed.
Local Lemma sigma_zero_to_odd :
forall (f : nat -> R) (t : nat),
sigma f 0 (S (2 * t))
= sigma (fun i => f (2 * i)%nat) 0 t
+ sigma (fun i => f (S (2 * i))%nat) 0 t.
Proof.
intros f. induction t.
- simpl. rewrite sigma_eq_arg. rewrite sigma_eq_arg. reflexivity.
- rewrite sigma_last. rewrite Nat.pred_succ.
rewrite sigma_last.
rewrite Nat_double_S at 3. rewrite Nat.pred_succ.
rewrite (@sigma_last _ _ (S t)). rewrite Nat.pred_succ.
rewrite (@sigma_last _ _ (S t)). rewrite Nat.pred_succ.
rewrite IHt.
rewrite (Rplus_comm (f (S (2 * S t))%nat)).
rewrite Rplus_assoc.
rewrite Rplus_assoc.
rewrite Rplus_assoc.
apply Rplus_eq_compat_l.
apply Rplus_eq_compat_l.
apply Rplus_comm.
3: rewrite Nat_double_S.
all: apply Nat.lt_0_succ.
Qed.
Local Lemma sigma_even_to_odd_length :
forall (f : nat -> R) (s k : nat),
sigma f (2 * s) (S (2 * (s + k)))
= sigma (fun i => f (2 * i)%nat) s (s + k)%nat
+ sigma (fun i => f (S (2 * i))%nat) s (s + k)%nat.
Proof.
intros f s k.
rewrite (sigma_shift_sub _ (2 * s) _ (2 * s)).
rewrite (sigma_shift_sub (fun i => f (2 * i)%nat) s _ s).
rewrite (sigma_shift_sub (fun i => f (S (2 * i))) s _ s).
rewrite Nat.sub_diag. rewrite Nat.sub_diag.
rewrite Nat.sub_succ_l. rewrite <- Nat.mul_sub_distr_l.
rewrite Nat.add_comm. rewrite Nat.add_sub.
rewrite sigma_zero_to_odd.
assert (
sigma (fun i => f (2 * i + 2 * s)%nat) 0 k =
sigma (fun i => f (2 * (i + s))%nat) 0
k) as H. {
f_equal. extensionality i. f_equal.
symmetry. apply Nat.mul_add_distr_l.
}
rewrite H. apply Rplus_eq_compat_l.
f_equal. extensionality i. f_equal.
rewrite Nat.add_succ_l. f_equal.
symmetry. apply Nat.mul_add_distr_l.
apply Nat.mul_le_mono_l.
1,3,5: apply Nat.le_add_r. 1,2,3: apply Nat.le_refl.
apply le_S_n. rewrite <- Nat_double_S.
unfold Nat.mul. rewrite Nat.add_0_r, Nat.add_0_r.
rewrite <- Nat.add_succ_l. rewrite (Nat.add_comm s k) at 2.
rewrite <- Nat.add_succ_l. rewrite Nat.add_shuffle0.
rewrite <- Nat.add_succ_l. rewrite Nat.add_assoc.
rewrite (Nat.add_shuffle0 (S s) (S k) s).
rewrite <- Nat.add_assoc. apply Nat.le_add_r.
Qed.
Theorem sigma_even_to_odd :
forall (f : nat -> R) (s t : nat), (s <= t)%nat ->
sigma f (2 * s) (S (2 * t))
= sigma (fun i => f (2 * i)%nat) s t
+ sigma (fun i => f (S (2 * i))%nat) s t.
Proof.
intros f s t Hst.
rewrite <- (Arith_base.le_plus_minus_r_stt s t).
apply sigma_even_to_odd_length.
assumption.
Qed.
Corollary sigma_even_to_odd2 :
forall (f : nat -> R) (m n : nat), (m < n)%nat -> Nat.Even m -> Nat.Odd n ->
sigma f m n
= sigma (fun i => f (2 * i)%nat) (Nat.div2 m) (Nat.div2 n)
+ sigma (fun i => f (S (2 * i))%nat) (Nat.div2 m) (Nat.div2 n).
Proof.
unfold Nat.Odd, Nat.Even.
intros f m n Hmn [m' Hm] [n' Hn].
assert (Hm2 : Nat.div2 m = m'). { subst m. apply Nat.div2_even. }
assert (Hn2 : Nat.div2 n = n'). { subst n. apply Nat.div2_odd'. }
rewrite Hm2, Hn2, Hm, Hn, Nat.add_1_r.
apply sigma_even_to_odd.
rewrite (Nat.mul_le_mono_pos_l m' n' 2).
apply Arith_base.lt_n_Sm_le_stt.
rewrite <- (Nat.add_1_r (2 * n')), <- Hm, <- Hn.
assumption. apply Nat.lt_0_succ.
Qed.
Corollary sigma_even_to_odd_auto :
forall (f : nat -> R) (m n : nat), (m < n)%nat ->
Nat.even m = true -> Nat.odd n = true ->
sigma f m n
= sigma (fun i => f (2 * i)%nat) (Nat.div2 m) (Nat.div2 n)
+ sigma (fun i => f (S (2 * i))%nat) (Nat.div2 m) (Nat.div2 n).
Proof.
intros f m n Hmn Hm Hn.
apply sigma_even_to_odd2. assumption.
rewrite <- Nat.even_spec; assumption.
rewrite <- Nat.odd_spec; assumption.
Qed.
Theorem sigma_odd_to_even :
forall (f : nat -> R) (s t : nat), (s < t)%nat ->
sigma f (S (2 * s)) (2 * t)%nat
= sigma (fun i => f (2 * i)%nat) (S s) t
+ sigma (fun i => f (Nat.pred (2 * i))%nat) (S s) t.
Proof.
intros f s t Hst.
destruct (Nat.eq_dec (S s) t) as [H | H].
- subst t.
rewrite sigma_first. rewrite Nat_double_S.
rewrite sigma_eq_arg. rewrite sigma_eq_arg. rewrite sigma_eq_arg.
rewrite Nat_double_S. rewrite Nat.pred_succ. apply Rplus_comm.
rewrite Nat_double_S. apply Nat.lt_succ_diag_r.
- assert (S s < t)%nat as HSst. {
destruct (Nat.lt_trichotomy (S s) t) as [H1 | [H1 | H1]].
- assumption.
- exfalso. apply H. assumption.
- exfalso.
apply (Arith_base.lt_not_le_stt _ _ Hst).
apply Arith_base.lt_n_Sm_le_stt. assumption.
}
rewrite (sigma_shift_sub (fun i => f (Nat.pred (2 * i)%nat)) _ _ 1).
rewrite Nat.sub_1_r. rewrite Nat.sub_1_r. rewrite Nat.pred_succ.
rewrite sigma_first. rewrite sigma_last.
rewrite (@sigma_last _ (S s)).
rewrite (@sigma_first _ s).
rewrite Nat.add_1_r. rewrite Nat_double_S. rewrite Nat.pred_succ.
rewrite Rplus_comm.
rewrite (Rplus_comm (f (S (2 * s)))).
rewrite <- Rplus_assoc. apply Rplus_eq_compat_r.
rewrite Rplus_assoc. apply Rplus_eq_compat_l.
rewrite Nat_pred_double_l.
rewrite <- Nat_double_S.
rewrite sigma_even_to_odd.
f_equal. f_equal. extensionality i. f_equal.
rewrite Nat.add_1_r. rewrite Nat_double_S. apply Nat.pred_succ.
rewrite Nat.succ_le_mono. rewrite Nat.succ_pred.
apply Arith_base.lt_le_S_stt. assumption.
symmetry. apply Arith_base.lt_0_neq_stt.
1,2: apply (Nat.lt_trans _ (S s) _ (Nat.lt_0_succ _) HSst).
apply Nat.lt_le_pred.
1,2: assumption.
2: apply Nat.lt_succ_l.
1,2: rewrite <- Nat_double_S;
rewrite <- (Nat.mul_lt_mono_pos_l _ _ _ (Nat.lt_0_succ 1%nat));
assumption. apply Nat.le_1_succ. apply Nat.lt_le_incl. assumption.
Qed.
Corollary sigma_odd_to_even2 :
forall (f : nat -> R) (m n : nat), (m < n)%nat -> Nat.Odd m -> Nat.Even n ->
sigma f m n
= sigma (fun i => f (2 * i)%nat) (S (Nat.div2 m)) (Nat.div2 n)
+ sigma (fun i => f (Nat.pred (2 * i))%nat) (S (Nat.div2 m)) (Nat.div2 n).
Proof.
unfold Nat.Odd, Nat.Even.
intros f m n Hmn [m' Hm] [n' Hn].
assert (Hm2 : Nat.div2 m = m'). { subst m. apply Nat.div2_odd'. }
assert (Hn2 : Nat.div2 n = n'). { subst n. apply Nat.div2_even. }
rewrite Hm2, Hn2, Hm, Hn, Nat.add_1_r.
apply sigma_odd_to_even.
rewrite (Nat.mul_lt_mono_pos_l 2 m' n').
apply Nat.lt_succ_l.
rewrite <- Nat.add_1_r, <- Hm, <- Hn. assumption.
apply Nat.lt_0_succ.
Qed.
Corollary sigma_odd_to_even_auto :
forall (f : nat -> R) (m n : nat), (m < n)%nat ->
Nat.odd m = true -> Nat.even n = true ->
sigma f m n
= sigma (fun i => f (2 * i)%nat) (S (Nat.div2 m)) (Nat.div2 n)
+ sigma (fun i => f (Nat.pred (2 * i))%nat) (S (Nat.div2 m)) (Nat.div2 n).
Proof.
intros f m n Hmn Hm Hn.
apply sigma_odd_to_even2. assumption.
rewrite <- Nat.odd_spec; assumption.
rewrite <- Nat.even_spec; assumption.
Qed.
Close Scope R_scope.
Require Import Tactics.
Require Import Automation.
Require Import Notations.Common.
Require Import Notations.Reals.
Require Import Chains.
Require Import Notations.Sets.
Create HintDb wp_finite_sums.
Waterproof Set Main Databases FiniteSums wp_finite_sums.
Waterproof Set Shorten Databases FiniteSums wp_finite_sums.
#[export] Hint Resolve sigma_first : wp_finite_sums.
#[export] Hint Resolve sigma_last : wp_finite_sums.
#[export] Hint Resolve sigma_split : wp_finite_sums.
#[export] Hint Resolve sigma_diff : wp_finite_sums.
#[export] Hint Resolve sigma_diff_neg : wp_finite_sums.
#[export] Hint Resolve sigma_eq_arg : wp_finite_sums.
#[export] Hint Resolve sigma_eq : wp_finite_sums.
#[export] Hint Resolve sigma_distr_l : wp_finite_sums.
#[export] Hint Resolve sigma_distr_r : wp_finite_sums.
#[export] Hint Resolve sigma_comm : wp_finite_sums.
#[export] Hint Resolve sigma_shift_add : wp_finite_sums.
#[export] Hint Resolve sigma_shift_sub : wp_finite_sums.
#[export] Hint Resolve sigma_rev0 : wp_finite_sums.
#[export] Hint Resolve sigma_rev : wp_finite_sums.
#[export] Hint Resolve sigma_telescope : wp_finite_sums.
#[export] Hint Resolve sigma_even_to_odd : wp_finite_sums.
#[export] Hint Resolve sigma_odd_to_even : wp_finite_sums.
#[export] Hint Resolve sigma_even_to_odd_auto : wp_finite_sums.
#[export] Hint Resolve sigma_odd_to_even_auto : wp_finite_sums.
#[export] Hint Extern 1 (@eq R (Rplus _ (sigma ?f ?l' ?h')) (sigma ?f ?l ?h)) =>
rewrite <- sigma_first : wp_finite_sums.
#[export] Hint Extern 1 (@eq R (Rplus (sigma ?f ?l' ?h') _) (sigma ?f ?l ?h)) =>
rewrite Rplus_comm; rewrite <- sigma_first : wp_finite_sums.
#[export] Hint Extern 1 (@eq R (sigma ?f ?l ?h) (Rplus _ (sigma ?f ?l' ?h')) (sigma ?f ?l ?h)) =>
rewrite <- sigma_first : wp_finite_sums.
#[export] Hint Extern 1 (@eq R (sigma ?f ?l ?h) (Rplus (sigma ?f ?l' ?h') _)) =>
rewrite Rplus_comm; rewrite <- sigma_first : wp_finite_sums.
#[export] Hint Extern 1 (@eq R (Rplus _ (sigma ?f ?l' ?h')) (sigma ?f ?l ?h)) =>
rewrite sigma_last : wp_finite_sums.
#[export] Hint Extern 1 (@eq R (Rplus (sigma ?f ?l' ?h') _) (sigma ?f ?l ?h)) =>
rewrite Rplus_comm; rewrite <- sigma_last : wp_finite_sums.
#[export] Hint Extern 1 (@eq R (sigma ?f ?l ?h) (Rplus _ (sigma ?f ?l' ?h'))) =>
rewrite sigma_last : wp_finite_sums.
#[export] Hint Extern 1 (@eq R (sigma ?f ?l ?h) (Rplus (sigma ?f ?l' ?h') _)) =>
rewrite Rplus_comm; rewrite <- sigma_last : wp_finite_sums.
#[export] Hint Extern 1 (@eq R (sigma ?f ?l ?h) (sigma ?g ?l ?h)) =>
(apply sigma_eq; auto) : wp_finite_sums.
#[export] Hint Extern 1 (@eq R (Rplus (sigma ?f1 ?l ?h) (sigma ?f2 ?l ?h)) (sigma ?f3 ?l ?h)) =>
rewrite sigma_comm : wp_finite_sums.
#[export] Hint Extern 1 (@eq R (sigma ?f1 ?l ?h) (Rplus (sigma ?f2 ?l ?h) (sigma ?f3 ?l ?h))) =>
rewrite sigma_comm : wp_finite_sums.
#[export] Hint Extern 1 (@eq R (Rminus (?g ?x) (?g ?l)) (sigma ?f ?l ?h)) =>
rewrite sigma_telescope : wp_finite_sums.
#[export] Hint Extern 1 (@eq R (sigma ?f ?l ?h) (Rminus (?g ?x) (?g ?l))) =>
rewrite sigma_telescope : wp_finite_sums.
#[export] Hint Extern 1 (@eq R (Rminus (?g ?x) (?g ?l)) (sigma ?f ?l ?h)) =>
rewrite sigma_telescope_plus1 : wp_finite_sums.
#[export] Hint Extern 1 (@eq R (sigma ?f ?l ?h) (Rminus (?g ?x) (?g ?l))) =>
rewrite sigma_telescope_plus1 : wp_finite_sums.