From 0ac14e20acac4b670d0b65b47a9b412504ac4916 Mon Sep 17 00:00:00 2001
From: Sergey Bozhko <sbozhko@mpi-sws.org>
Date: Tue, 24 Sep 2019 17:06:36 +0200
Subject: [PATCH] Shorten a few long proofs

---
 scripts/known-long-proofs.json |  9 ------
 util/list.v                    | 54 ++++++++++++++++------------------
 util/step_function.v           | 33 ++++++++-------------
 util/sum.v                     | 19 ++++--------
 4 files changed, 44 insertions(+), 71 deletions(-)

diff --git a/scripts/known-long-proofs.json b/scripts/known-long-proofs.json
index ad88b329a..af7f5e796 100644
--- a/scripts/known-long-proofs.json
+++ b/scripts/known-long-proofs.json
@@ -300,15 +300,6 @@
         },
         "./util/div_mod.v": {
             "divSn_cases": 54
-        },
-        "./util/list.v": {
-            "subseq_leq_size": 52
-        },
-        "./util/step_function.v": {
-            "exists_intermediate_point": 43
-        },
-        "./util/sum.v": {
-            "sum_majorant_eqn": 40
         }
     }
 }
diff --git a/util/list.v b/util/list.v
index e822d2314..db5ef24df 100644
--- a/util/list.v
+++ b/util/list.v
@@ -748,6 +748,22 @@ End Order.
 (* In this section we prove some additional lemmas about sequences. *)
 Section AdditionalLemmas.
 
+  (* First, we prove that x ∈ xs implies that xs can be split 
+     into two parts such that xs = xsl ++ [::x] ++ xsr. *)
+  Lemma in_cat:
+    forall {X : eqType} (x : X) (xs : list X),
+      x \in xs -> exists xsl xsr, xs = xsl ++ [::x] ++ xsr.
+  Proof.
+    intros ? ? ? SUB.
+    induction xs; first by done.
+    move: SUB; rewrite in_cons; move => /orP [/eqP EQ|IN].
+    - by subst; exists [::], xs.
+    - feed IHxs; first by done.
+      clear IN; move: IHxs => [xsl [xsr EQ]].
+        by subst; exists (a::xsl), xsr.
+  Qed.
+  
+
   (* We define a local function max over lists using foldl and maxn. *)
   Let max := foldl maxn 0.
   
@@ -769,41 +785,24 @@ Section AdditionalLemmas.
   (* We prove that for any two sequences xs and ys the fact that xs is a subsequence 
      of ys implies that the size of xs is at most the size of ys. *)
   Lemma subseq_leq_size:
-    forall {T: eqType} (xs ys: seq T),
+    forall {X : eqType} (xs ys: seq X),
       uniq xs ->
       (forall x, x \in xs -> x \in ys) ->
       size xs <= size ys.
   Proof.
     clear; intros ? ? ? UNIQ SUB.
-    have Lem:
-      forall a ys,
-        (a \in ys) -> 
-        exists ysl ysr, ys = ysl ++ [::a] ++ ysr.
-    { clear; intros ? ? ? SUB.
-      induction ys; first by done.
-      move: SUB; rewrite in_cons; move => /orP [/eqP EQ|IN].
-      - by subst; exists [::], ys.
-      - feed IHys; first by done.
-        clear IN; move: IHys => [ysl [ysr EQ]].
-          by subst; exists(a0::ysl), ysr.
-    }
-    have EXm: exists m, size ys <= m.
-    { by exists (size ys). }
+    have EXm: exists m, size ys <= m; first by exists (size ys).
     move: EXm => [m SIZEm].
     move: SIZEm UNIQ SUB; move: xs ys.
-    induction m.
-    { intros.
-      move: SIZEm; rewrite leqn0 size_eq0; move => /eqP SIZEm; subst ys.
+    induction m; intros.
+    { move: SIZEm; rewrite leqn0 size_eq0; move => /eqP SIZEm; subst ys.
       destruct xs; first by done.
       specialize (SUB s).
-      feed SUB; first by rewrite in_cons; apply/orP; left.
-        by done.
-    }
-    { intros.
-      destruct xs as [ | x xs]; first by done.
-      specialize (@Lem _ x ys).
-      feed Lem.
-      { by apply SUB; rewrite in_cons; apply/orP; left. }
+        by feed SUB; [rewrite in_cons; apply/orP; left | done]. 
+    }
+    { destruct xs as [ | x xs]; first by done.
+      move: (@in_cat _ x ys) => Lem.
+      feed Lem; first by apply SUB; rewrite in_cons; apply/orP; left.
       move: Lem => [ysl [ysr EQ]]; subst ys.
       rewrite !size_cat; simpl; rewrite -addnC add1n addSn ltnS -size_cat.
       eapply IHm.
@@ -817,8 +816,7 @@ Section AdditionalLemmas.
             by subst; move: NIN => /negP NIN; apply: NIN.
         }
         { specialize (SUB a).
-          feed SUB.
-          { by rewrite in_cons; apply/orP; right. }
+          feed SUB; first by rewrite in_cons; apply/orP; right.
           clear IN; move: SUB; rewrite !mem_cat; move => /orP [IN| /orP [IN|IN]].
           - by apply/orP; right.
           - exfalso.
diff --git a/util/step_function.v b/util/step_function.v
index c999715f6..d9ec65b8c 100644
--- a/util/step_function.v
+++ b/util/step_function.v
@@ -37,47 +37,40 @@ Section StepFunction.
       Lemma exists_intermediate_point:
         exists x_mid, x1 <= x_mid < x2 /\ f x_mid = y.
       Proof.
-        unfold is_step_function in *.
-        rename H_is_interval into INT,
-               H_step_function into STEP, H_between into BETWEEN.
+        rename H_is_interval into INT, H_step_function into STEP, H_between into BETWEEN.
         move: x2 INT BETWEEN; clear x2.
         suff DELTA:
           forall delta,
             f x1 <= y < f (x1 + delta) ->
-            exists x_mid, x1 <= x_mid < x1 + delta /\ f x_mid = y.                  {
-          move => x2 LE /andP [GEy LTy].
+            exists x_mid, x1 <= x_mid < x1 + delta /\ f x_mid = y.
+        { move => x2 LE /andP [GEy LTy].
           exploit (DELTA (x2 - x1));
             first by apply/andP; split; last by rewrite addnBA // addKn.
-          by rewrite addnBA // addKn.
+            by rewrite addnBA // addKn.
         }
         induction delta.
-        {
-          rewrite addn0; move => /andP [GE0 LT0].
-          by apply (leq_ltn_trans GE0) in LT0; rewrite ltnn in LT0.
+        { rewrite addn0; move => /andP [GE0 LT0].
+            by apply (leq_ltn_trans GE0) in LT0; rewrite ltnn in LT0.
         }
-        {
-          move => /andP [GT LT].
+        { move => /andP [GT LT].
           specialize (STEP (x1 + delta)); rewrite leq_eqVlt in STEP.
           have LE: y <= f (x1 + delta).
-          {
-            move: STEP => /orP [/eqP EQ | STEP];
+          { move: STEP => /orP [/eqP EQ | STEP];
               first by rewrite !addn1 in EQ; rewrite addnS EQ ltnS in LT.
             rewrite [X in _ < X]addn1 ltnS in STEP.
             apply: (leq_trans _ STEP).
-            by rewrite addn1 -addnS ltnW.
+              by rewrite addn1 -addnS ltnW.
           } clear STEP LT.
           rewrite leq_eqVlt in LE.
           move: LE => /orP [/eqP EQy | LT].
-          {
-            exists (x1 + delta); split; last by rewrite EQy.
-            by apply/andP; split; [by apply leq_addr | by rewrite addnS].
+          { exists (x1 + delta); split; last by rewrite EQy.
+              by apply/andP; split; [by apply leq_addr | by rewrite addnS].
           }
-          {
-            feed (IHdelta); first by apply/andP; split.
+          { feed (IHdelta); first by apply/andP; split.
             move: IHdelta => [x_mid [/andP [GE0 LT0] EQ0]].
             exists x_mid; split; last by done.
             apply/andP; split; first by done.
-            by apply: (leq_trans LT0); rewrite addnS.
+              by apply: (leq_trans LT0); rewrite addnS.
           }  
         }
       Qed.
diff --git a/util/sum.v b/util/sum.v
index 106e89008..1c61c685a 100644
--- a/util/sum.v
+++ b/util/sum.v
@@ -1,4 +1,4 @@
-Require Import rt.util.tactics rt.util.notation rt.util.sorting rt.util.nat.
+From rt.util Require Import tactics notation sorting nat ssromega.
 From mathcomp Require Import ssreflect ssrbool eqtype ssrnat seq fintype bigop path.
 
 (* Lemmas about sum. *)
@@ -41,22 +41,18 @@ Section ExtraLemmas.
     all (fun x => F x == 0) r = (\sum_(i <- r) F i == 0).
   Proof.
     destruct (all (fun x => F x == 0) r) eqn:ZERO.
-    {
-      move: ZERO => /allP ZERO; rewrite -leqn0.
+    - move: ZERO => /allP ZERO; rewrite -leqn0.
       rewrite big_seq_cond (eq_bigr (fun x => 0));
         first by rewrite big_const_seq iter_addn mul0n addn0 leqnn.
       intro i; rewrite andbT; intros IN.
       specialize (ZERO i); rewrite IN in ZERO.
         by move: ZERO => /implyP ZERO; apply/eqP; apply ZERO.
-    }
-    {
-      apply negbT in ZERO; rewrite -has_predC in ZERO.
+    - apply negbT in ZERO; rewrite -has_predC in ZERO.
       move: ZERO => /hasP ZERO; destruct ZERO as [x IN NEQ]; simpl in NEQ.
       rewrite (big_rem x) /=; last by done.
       symmetry; apply negbTE; rewrite neq_ltn; apply/orP; right.
       apply leq_trans with (n := F x); last by apply leq_addr.
         by rewrite lt0n.
-    }
   Qed.
   
   Lemma leq_sum1_smaller_range m n (P Q: pred nat) a b:
@@ -141,7 +137,7 @@ Section ExtraLemmas.
     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].
+    destruct P1 eqn:P1a; destruct P2 eqn:P2a; try done. 
     exfalso.
     move: P1a P2a => /eqP P1a /eqP P2a.
     rewrite eqb_id in P1a; rewrite eqbF_neg in P2a.
@@ -209,7 +205,6 @@ Section ExtraLemmas.
       \sum_(x <- xs | P x) F1 x = \sum_(x <- xs | P x) F2 x ->
       (forall x, x \in xs -> P x -> F1 x = F2 x).
   Proof.
-    clear.      
     intros T xs F1 F2 P H1 H2 x IN PX.
     induction xs; first by done.
     have Fact: \sum_(j <- xs | P j) F1 j <= \sum_(j <- xs | P j) F2 j.
@@ -223,11 +218,7 @@ Section ExtraLemmas.
         by rewrite in_cons; apply/orP; right. }
     rewrite big_cons [RHS]big_cons in H2.
     have EqLeq: forall a b c d, a + b = c + d -> a <= c -> b >= d.
-    { clear; intros.
-      rewrite leqNgt; apply/negP; intros H1.
-      move: H => /eqP; rewrite eqn_leq; move => /andP [LE GE].
-      move: GE; rewrite leqNgt; move => /negP GE; apply: GE.
-        by apply leq_trans with (a + d); [rewrite ltn_add2l | rewrite leq_add2r]. }
+    { clear; intros; ssromega. } 
     move: IN; rewrite in_cons; move => /orP [/eqP EQ | IN]. 
     { subst a.
       rewrite PX in H2.
-- 
GitLab