From 1b64ec084566c4ec3248d37d1c3c70d25eb2616b Mon Sep 17 00:00:00 2001 From: Sergey Bozhko <sbozhko@sws-mpi.org> Date: Thu, 20 Sep 2018 16:04:41 +0200 Subject: [PATCH] Update util files --- util/all.v | 3 +- util/minmax.v | 55 ++++++++++++-- util/sum.v | 202 +++++++++++++++++++++++++++++--------------------- 3 files changed, 169 insertions(+), 91 deletions(-) diff --git a/util/all.v b/util/all.v index 25acc36ba..892aad02c 100644 --- a/util/all.v +++ b/util/all.v @@ -1,6 +1,7 @@ Require Export rt.util.tactics. Require Export rt.util.notation. Require Export rt.util.bigcat. +Require Export rt.util.pick. Require Export rt.util.bigord. Require Export rt.util.counting. Require Export rt.util.div_mod. @@ -16,4 +17,4 @@ Require Export rt.util.sum. Require Export rt.util.minmax. Require Export rt.util.seqset. Require Export rt.util.step_function. -Require Export rt.util.pick. \ No newline at end of file +Require Export rt.util.epsilon. diff --git a/util/minmax.v b/util/minmax.v index ea69b93b3..5d8e673ee 100644 --- a/util/minmax.v +++ b/util/minmax.v @@ -514,14 +514,55 @@ End MinMaxSeq. (* Additional lemmas about max. *) Section ExtraLemmas. - - Lemma leq_big_max I r (P : pred I) (E1 E2 : I -> nat) : - (forall i, P i -> E1 i <= E2 i) -> - \max_(i <- r | P i) E1 i <= \max_(i <- r | P i) E2 i. + + Lemma leq_bigmax_cond_seq (T : eqType) (P : pred T) (r : seq T) F i0 : + i0 \in r -> P i0 -> F i0 <= \max_(i <- r | P i) F i. + Proof. + intros IN0 Pi0; by rewrite (big_rem i0) //= Pi0 leq_maxl. + Qed. + + Lemma bigmax_sup_seq: + forall (T: eqType) (i: T) r (P: pred T) m F, + i \in r -> P i -> m <= F i -> m <= \max_(i <- r| P i) F i. + Proof. + intros. + induction r. + - by rewrite in_nil in H. + move: H; rewrite in_cons; move => /orP [/eqP EQA | IN]. + { + clear IHr; subst a. + rewrite (big_rem i) //=; last by rewrite in_cons; apply/orP; left. + apply leq_trans with (F i); first by done. + by rewrite H0 leq_maxl. + } + { + apply leq_trans with (\max_(i0 <- r | P i0) F i0); first by apply IHr. + rewrite [in X in _ <= X](big_rem a) //=; last by rewrite in_cons; apply/orP; left. + + have Ob: a == a; first by done. + by rewrite Ob leq_maxr. + } + Qed. + + Lemma bigmax_leq_seqP (T : eqType) (P : pred T) (r : seq T) F m : + reflect (forall i, i \in r -> P i -> F i <= m) + (\max_(i <- r | P i) F i <= m). + Proof. + apply: (iffP idP) => leFm => [i IINR Pi|]; + first by apply: leq_trans leFm; apply leq_bigmax_cond_seq. + rewrite big_seq_cond; elim/big_ind: _ => // m1 m2. + by intros; rewrite geq_max; apply/andP; split. + by move: m2 => /andP [M1IN Pm1]; apply: leFm. + Qed. + + Lemma leq_big_max (T : eqType) (P : pred T) (r : seq T) F1 F2 : + (forall i, i \in r -> P i -> F1 i <= F2 i) -> + \max_(i <- r | P i) F1 i <= \max_(i <- r | P i) F2 i. Proof. - move => leE12; elim/big_ind2 : _ => // m1 m2 n1 n2. - intros LE1 LE2; rewrite leq_max; unfold maxn. - by destruct (m2 < n2) eqn:LT; [by apply/orP; right | by apply/orP; left]. + intros; apply /bigmax_leq_seqP; intros. + specialize (H i); feed_n 2 H; try(done). + rewrite (big_rem i) //=; rewrite H1. + by apply leq_trans with (F2 i); [ | rewrite leq_maxl]. Qed. Lemma bigmax_ord_ltn_identity n : diff --git a/util/sum.v b/util/sum.v index 7980bd4c2..af03f4b52 100644 --- a/util/sum.v +++ b/util/sum.v @@ -1,88 +1,7 @@ Require Import rt.util.tactics rt.util.notation rt.util.sorting rt.util.nat. From mathcomp Require Import ssreflect ssrbool eqtype ssrnat seq fintype bigop path. -(* Lemmas about arithmetic with sums. *) -Section SumArithmetic. - - (* Inequality with sums is monotonic with their functions. *) - Lemma sum_diff_monotonic : - forall n G F, - (forall i : nat, i < n -> G i <= F i) -> - (\sum_(0 <= i < n) (G i)) <= (\sum_(0 <= i < n) (F i)). - Proof. - intros n G F ALL. - rewrite big_nat_cond [\sum_(0 <= i < n) F i]big_nat_cond. - apply leq_sum; intros i LT; rewrite andbT in LT. - move: LT => /andP LT; des. - by apply ALL, leq_trans with (n := n); ins. - Qed. - - Lemma sum_diff : - forall n F G, - (forall i (LT: i < n), F i >= G i) -> - \sum_(0 <= i < n) (F i - G i) = - (\sum_(0 <= i < n) (F i)) - (\sum_(0 <= i < n) (G i)). - Proof. - intros n F G ALL. - induction n; ins; first by rewrite 3?big_geq. - assert (ALL': forall i, i < n -> G i <= F i). - by ins; apply ALL, leq_trans with (n := n); ins. - rewrite 3?big_nat_recr // IHn //; simpl. - rewrite subh1; last by apply sum_diff_monotonic. - rewrite subh2 //; try apply sum_diff_monotonic; ins. - rewrite subh1; ins; apply sum_diff_monotonic; ins. - by apply ALL; rewrite ltnS leqnn. - Qed. - - Lemma telescoping_sum : - forall (T: Type) (F: T->nat) r (x0: T), - (forall i, i < (size r).-1 -> F (nth x0 r i) <= F (nth x0 r i.+1)) -> - F (nth x0 r (size r).-1) - F (nth x0 r 0) = - \sum_(0 <= i < (size r).-1) (F (nth x0 r (i.+1)) - F (nth x0 r i)). - Proof. - intros T F r x0 ALL. - have ADD1 := big_add1. - have RECL := big_nat_recl. - specialize (ADD1 nat 0 addn 0 (size r) (fun x => true) (fun i => F (nth x0 r i))). - specialize (RECL nat 0 addn (size r).-1 0 (fun i => F (nth x0 r i))). - rewrite sum_diff; last by ins. - rewrite addmovr; last by rewrite -[_.-1]add0n; apply prev_le_next; try rewrite add0n leqnn. - rewrite subh1; last by apply sum_diff_monotonic. - rewrite addnC -RECL //. - rewrite addmovl; last by rewrite big_nat_recr // -{1}[\sum_(_ <= _ < _) _]addn0; apply leq_add. - by rewrite addnC -big_nat_recr. - Qed. - - Lemma leq_sum_sub_uniq : - forall (T: eqType) (r1 r2: seq T) F, - uniq r1 -> - {subset r1 <= r2} -> - \sum_(i <- r1) F i <= \sum_(i <- r2) F i. - Proof. - intros T r1 r2 F UNIQ SUB; generalize dependent r2. - induction r1 as [| x r1' IH]; first by ins; rewrite big_nil. - { - intros r2 SUB. - assert (IN: x \in r2). - by apply SUB; rewrite in_cons eq_refl orTb. - simpl in UNIQ; move: UNIQ => /andP [NOTIN UNIQ]; specialize (IH UNIQ). - destruct (splitPr IN). - rewrite big_cat 2!big_cons /= addnA [_ + F x]addnC -addnA leq_add2l. - rewrite mem_cat in_cons eq_refl in IN. - rewrite -big_cat /=. - apply IH; red; intros x0 IN0. - rewrite mem_cat. - feed (SUB x0); first by rewrite in_cons IN0 orbT. - rewrite mem_cat in_cons in SUB. - move: SUB => /orP [SUB1 | /orP [/eqP EQx | SUB2]]; - [by rewrite SUB1 | | by rewrite SUB2 orbT]. - by rewrite -EQx IN0 in NOTIN. - } - Qed. - -End SumArithmetic. - -(* Additional lemmas about sum. *) +(* Lemmas about sum. *) Section ExtraLemmas. Lemma extend_sum : @@ -170,4 +89,121 @@ Section ExtraLemmas. } Qed. -End ExtraLemmas. \ No newline at end of file + Lemma sum_seq_gt0P: + forall (T:eqType) (r: seq T) (F: T -> nat), + reflect (exists i, i \in r /\ 0 < F i) (0 < \sum_(i <- r) F i). + Proof. + intros; apply: (iffP idP); intros. + { + induction r; first by rewrite big_nil in H. + destruct (F a > 0) eqn:POS. + exists a; split; [by rewrite in_cons; apply/orP; left | by done]. + apply negbT in POS; rewrite -leqNgt leqn0 in POS; move: POS => /eqP POS. + rewrite big_cons POS add0n in H. clear POS. + feed IHr; first by done. move: IHr => [i [IN POS]]. + exists i; split; [by rewrite in_cons; apply/orP;right | by done]. + } + { + move: H => [i [IN POS]]. + rewrite (big_rem i) //=. + apply leq_trans with (F i); [by done | by rewrite leq_addr]. + } + Qed. + + Lemma leq_pred_sum: + forall (T:eqType) (r: seq T) (P1 P2: pred T) F, + (forall i, P1 i -> P2 i) -> + \sum_(i <- r | P1 i) F i <= + \sum_(i <- r | P2 i) F i. + Proof. + intros. + rewrite big_mkcond [in X in _ <= X]big_mkcond//= leq_sum //. + intros i _. + destruct P1 eqn:P1a; destruct P2 eqn:P2a; [by done | | by done | by done]. + exfalso. + move: P1a P2a => /eqP P1a /eqP P2a. + rewrite eqb_id in P1a; rewrite eqbF_neg in P2a. + move: P2a => /negP P2a. + by apply P2a; apply H. + Qed. + +End ExtraLemmas. + +(* Lemmas about arithmetic with sums. *) +Section SumArithmetic. + + Lemma sum_seq_diff: + forall (T:eqType) (r: seq T) (F G : T -> nat), + (forall i : T, i \in r -> G i <= F i) -> + \sum_(i <- r) (F i - G i) = \sum_(i <- r) F i - \sum_(i <- r) G i. + Proof. + intros. + induction r; first by rewrite !big_nil subn0. + rewrite !big_cons subh2. + - apply/eqP; rewrite eqn_add2l; apply/eqP; apply IHr. + by intros; apply H; rewrite in_cons; apply/orP; right. + - by apply H; rewrite in_cons; apply/orP; left. + - rewrite big_seq_cond [in X in _ <= X]big_seq_cond. + rewrite leq_sum //; move => i /andP [IN _]. + by apply H; rewrite in_cons; apply/orP; right. + Qed. + + Lemma sum_diff: + forall n F G, + (forall i (LT: i < n), F i >= G i) -> + \sum_(0 <= i < n) (F i - G i) = + (\sum_(0 <= i < n) (F i)) - (\sum_(0 <= i < n) (G i)). + Proof. + intros n F G ALL. + rewrite sum_seq_diff; first by done. + move => i; rewrite mem_index_iota; move => /andP [_ LT]. + by apply ALL. + Qed. + + Lemma telescoping_sum : + forall (T: Type) (F: T->nat) r (x0: T), + (forall i, i < (size r).-1 -> F (nth x0 r i) <= F (nth x0 r i.+1)) -> + F (nth x0 r (size r).-1) - F (nth x0 r 0) = + \sum_(0 <= i < (size r).-1) (F (nth x0 r (i.+1)) - F (nth x0 r i)). + Proof. + intros T F r x0 ALL. + have ADD1 := big_add1. + have RECL := big_nat_recl. + specialize (ADD1 nat 0 addn 0 (size r) (fun x => true) (fun i => F (nth x0 r i))). + specialize (RECL nat 0 addn (size r).-1 0 (fun i => F (nth x0 r i))). + rewrite sum_diff; last by ins. + rewrite addmovr; last by rewrite -[_.-1]add0n; apply prev_le_next; try rewrite add0n leqnn. + rewrite subh1; last by apply leq_sum_nat; move => i /andP [_ LT] _; apply ALL. + rewrite addnC -RECL //. + rewrite addmovl; last by rewrite big_nat_recr // -{1}[\sum_(_ <= _ < _) _]addn0; apply leq_add. + by rewrite addnC -big_nat_recr. + Qed. + + Lemma leq_sum_sub_uniq : + forall (T: eqType) (r1 r2: seq T) F, + uniq r1 -> + {subset r1 <= r2} -> + \sum_(i <- r1) F i <= \sum_(i <- r2) F i. + Proof. + intros T r1 r2 F UNIQ SUB; generalize dependent r2. + induction r1 as [| x r1' IH]; first by ins; rewrite big_nil. + { + intros r2 SUB. + assert (IN: x \in r2). + by apply SUB; rewrite in_cons eq_refl orTb. + simpl in UNIQ; move: UNIQ => /andP [NOTIN UNIQ]; specialize (IH UNIQ). + destruct (splitPr IN). + rewrite big_cat 2!big_cons /= addnA [_ + F x]addnC -addnA leq_add2l. + rewrite mem_cat in_cons eq_refl in IN. + rewrite -big_cat /=. + apply IH; red; intros x0 IN0. + rewrite mem_cat. + feed (SUB x0); first by rewrite in_cons IN0 orbT. + rewrite mem_cat in_cons in SUB. + move: SUB => /orP [SUB1 | /orP [/eqP EQx | SUB2]]; + [by rewrite SUB1 | | by rewrite SUB2 orbT]. + by rewrite -EQx IN0 in NOTIN. + } + Qed. + +End SumArithmetic. \ No newline at end of file -- GitLab