From fcde91efbdef1762165d0ca91242025a474fd184 Mon Sep 17 00:00:00 2001
From: Sergei Bozhko <sbozhko@mpi-sws.org>
Date: Mon, 20 Sep 2021 10:50:35 +0200
Subject: [PATCH] clean up in util/nondecreasing.v

---
 util/nondecreasing.v | 387 +++++++++++++++++++------------------------
 1 file changed, 169 insertions(+), 218 deletions(-)

diff --git a/util/nondecreasing.v b/util/nondecreasing.v
index 722f172ce..1462134ca 100644
--- a/util/nondecreasing.v
+++ b/util/nondecreasing.v
@@ -14,7 +14,7 @@ Section NondecreasingSequence.
   Section Definitions. 
     
     (** We say that a sequence [xs] is non-decreasing iff for any two indices [n1] and [n2] 
-       such that [n1 <= n2 < size [xs]] condition [[xs][n1] <= [xs][n2]] holds. *)
+        such that [n1 <= n2 < size [xs]] condition [[xs][n1] <= [xs][n2]] holds. *)
     Definition nondecreasing_sequence (xs : seq nat) :=
       forall n1 n2,
         n1 <= n2 < size xs ->
@@ -49,29 +49,29 @@ Section NondecreasingSequence.
     Proof.
       clear; intros ? ? ?.
       have EX : exists k, b - a <= k.
-      { exists (b-a); now simpl. } destruct EX as [k BO].
+      { by exists (b-a). } destruct EX as [k BO].
       revert a b P BO; induction k.
       { move => a b P BO n1 n2.
         move: BO; rewrite leqn0; move => /eqP BO.
         rewrite /index_iota BO; simpl.
-          by move => /andP [_ F].
+        by move => /andP [_ F].
       } 
       { move => a b P BO n1 n2 /andP [GE LT].
         case: (leqP b a) => [N|N].
         - move: N; rewrite -subn_eq0; move => /eqP EQ.
-          rewrite /index_iota EQ //= in LT.
+          by rewrite /index_iota EQ //= in LT.
         - rewrite index_iota_lt_step; last by done.
           simpl; destruct (P a) eqn:PA.
           + destruct n1, n2; try done; simpl.
             * apply iota_filter_gt; first by done.
-              rewrite index_iota_lt_step // //= PA //= in LT.
+              by rewrite index_iota_lt_step // //= PA //= in LT.
             * apply IHk; try ssrlia.
               apply/andP; split; first by done.
-              rewrite index_iota_lt_step // //= PA //= in LT.
+              by rewrite index_iota_lt_step // //= PA //= in LT.
           + apply IHk; try ssrlia.
             apply/andP; split; first by done.
-            rewrite index_iota_lt_step // //= PA //= in LT.
-      } 
+            by rewrite index_iota_lt_step // //= PA //= in LT.
+      }
     Qed.
 
     (** We prove that any increasing sequence is also a non-decreasing
@@ -81,8 +81,7 @@ Section NondecreasingSequence.
         increasing_sequence xs ->
         nondecreasing_sequence xs.
     Proof.
-      intros ? INC.
-      intros n1 n2.
+      intros ? INC n1 n2.
       move => /andP; rewrite leq_eqVlt; move => [/orP [/eqP EQ| LT1] LT2].
       - by subst.
       - by apply ltnW; apply INC; apply/andP; split.
@@ -111,7 +110,7 @@ Section NondecreasingSequence.
       feed ND.      
       { apply/andP; split; first by done.      
           by simpl; rewrite ltnS index_mem. }
-        by simpl in ND; rewrite NTH in ND.
+      by simpl in ND; rewrite NTH in ND.
     Qed.
     
     (** If [x1::x2::xs] is a non-decreasing sequence, then either 
@@ -124,7 +123,7 @@ Section NondecreasingSequence.
       intros ? ? ? ND.
       destruct (ltngtP x1 x2) as [LT | GT | EQ]; auto.
       move_neq_down GT.
-        by specialize (ND 0 1); apply ND.
+      by specialize (ND 0 1); apply ND.
     Qed.
     
     (** We prove that if [x::xs] is a non-decreasing sequence,
@@ -153,14 +152,13 @@ Section NondecreasingSequence.
         nondecreasing_sequence (x :: xs).
     Proof.
       intros x xs MIN ND [ |n1] [ | n2]; try done.
-      - move => /andP [_ S]; simpl.
+      - move => /andP [_ S] //=.
         apply leq_trans with (xs [| 0 |]).
         + apply MIN; apply mem_nth.
-          simpl in *. rewrite ltnS in S.
-            by apply leq_ltn_trans with n2.
+          simpl in *; rewrite ltnS in S.
+          by apply leq_ltn_trans with n2.
         + apply ND; apply/andP; split; auto.
-      - simpl; rewrite !ltnS.
-          by apply ND.
+      - by rewrite //= !ltnS; apply ND.
     Qed.
 
     (** We prove that if [x::xs] is a non-decreasing sequence,
@@ -172,13 +170,12 @@ Section NondecreasingSequence.
     Proof.
       intros ? ? ND.
       move => [ | n1] [ | n2] /andP [LT1 LT2]; try done.
-      - specialize (ND 0 n2); simpl in ND.
-        apply ND.
-          by simpl in LT2; rewrite ltnS in LT2.
+      - specialize (ND 0 n2).
+        by apply ND; rewrite //= ltnS in LT2.
       - apply ND.
         apply/andP; split.
         + by rewrite ltnS in LT1.
-        + by simpl in LT2; rewrite ltnS in LT2.
+        + by rewrite //= ltnS in LT2.
     Qed.
     
     (** We prove that if [x::xs] is a non-decreasing sequence,
@@ -193,11 +190,9 @@ Section NondecreasingSequence.
       specialize (ND 0 (index y xs).+1).
       move: (IN) => IDL; rewrite -index_mem in IDL.
       feed ND.
-      { apply/andP; split; first by done.
-          by simpl; rewrite ltnS.
-      }
+      { by apply/andP; split; last rewrite //= ltnS. }
       eapply leq_trans; first by apply ND.
-        by simpl; rewrite IDX.
+      by rewrite //= IDX.
     Qed.
 
     (** We also prove a similar lemma for strict minimum. *)
@@ -211,7 +206,7 @@ Section NondecreasingSequence.
       eapply leq_trans; first by apply LT.
       apply nondecreasing_sequence_cons in ND.
       eapply nondecreasing_sequence_cons_min; last by apply IN.
-        by apply nondecreasing_sequence_cons_double.
+      by apply nondecreasing_sequence_cons_double.
     Qed.
     
     (** Next, we prove that no element can lie strictly between two 
@@ -230,32 +225,34 @@ Section NondecreasingSequence.
       destruct (n.+1 < size xs) eqn:Bt; last first.
       { move: Bt => /negP /negP; rewrite -leqNgt; move => Bt.
         apply nth_default with (x0 := 0) in Bt. 
-        rewrite Bt in H; by move: H => /andP [_ T]. }
+        by rewrite Bt in H; move: H => /andP [_ T]. }
       have B1: n.+1 < size xs; first by done. clear Bt.
       have B2: n < size xs; first by apply leq_ltn_trans with n.+1.          
       have GT: n < x.
       { move: H => /andP [T _].
         rewrite ltnNge; apply/negP; intros CONTR.
         specialize (STR x n).
-        feed STR. by apply/andP; split.
-          by move: STR; rewrite leqNgt; move => /negP STR; apply: STR.
+        feed STR.
+        { by apply/andP; split. }
+        by move: STR; rewrite leqNgt; move => /negP STR; apply: STR.
       }
       have LT: x < n.+1.
       { clear GT.
         move: H => /andP [_ T].
         rewrite ltnNge; apply/negP; intros CONTR.
         move: CONTR; rewrite leq_eqVlt; move => /orP [/eqP EQ | CONTR].
-        { by subst; rewrite ltnn in T. }
-        specialize (STR n.+1 x).
-        feed STR. by apply/andP; split; [ apply ltnW | done].
+        - by subst; rewrite ltnn in T.
+        - specialize (STR n.+1 x).
+          feed STR.
+          { by apply/andP; split; first apply ltnW. } 
           by move: STR; rewrite leqNgt; move => /negP STR; apply: STR.
       }
-        by move: LT; rewrite ltnNge; move => /negP LT; apply: LT.
+      by move: LT; rewrite ltnNge; move => /negP LT; apply: LT.
     Qed.
     
-    (** Alternatively, consider an arbitrary natural number x that is 
-       bounded by the first and the last element of a sequence [xs]. Then 
-       there is an index n such that [xs[n] <= x < x[n+1]]. *)
+    (** Alternatively, consider an arbitrary natural number x that is
+        bounded by the first and the last element of a sequence
+        [xs]. Then there is an index n such that [xs[n] <= x < x[n+1]]. *)
     Lemma belonging_to_segment_of_seq_is_total:
       forall (xs : seq nat) (x : nat), 
         2 <= size xs -> 
@@ -272,17 +269,17 @@ Section NondecreasingSequence.
       induction n; intros.
       { by destruct xs; [ | destruct xs; [ | destruct xs; [exists 0 | ] ] ]. }
       { destruct xs; [ | destruct xs; [ | ]]; try by done. 
-        destruct xs.
-        { by exists 0; simpl in *. }
+        destruct xs; first by (exists 0).
         destruct (leqP n1 x) as [NEQ|NEQ]; last first.
-        { exists 0; split; auto. move: LAST => /andP [LAST _]. by apply/andP; split. } 
+        { exists 0; split; auto. move: LAST => /andP [LAST _].
+          by apply/andP; split. } 
         { specialize (IHn [:: n1, n2 & xs]).
           feed_n 3 IHn.
           { by done. } 
           { move: LAST => /andP [LAST1 LAST2].
             apply/andP; split; first by done.
             apply leq_trans with (last0 [:: n0, n1, n2 & xs]); first by done.
-              by rewrite /last0 !last_cons.
+            by rewrite /last0 !last_cons.
           }
           { by rewrite -(ltn_add2r 1) !addn1. }
           move: IHn => [idx [SI /andP [G L]]].
@@ -300,26 +297,27 @@ Section NondecreasingSequence.
         (x \in xs) -> 
         x <= last0 xs.
     Proof.
-      clear; intros ? ? STR IN. 
+      intros ? ? STR IN. 
       have NEQ: forall x y, x = y \/ x != y.
-      { clear. intros.
+      { clear; intros.
         destruct (x == y) eqn:EQ.
         - by left; apply/eqP.
         - by right.
       }
       move: (NEQ _ x (last0 xs)); clear NEQ; move => [EQ|NEQ].
       { by subst x. }
-      move: IN => /nthP EX.
-      specialize (EX 0). 
-      move: EX => [id SIZE EQ].
-      rewrite /last0 -nth_last -EQ; subst x.      
-      rewrite -addn1 in SIZE.
-      apply STR; apply/andP.
-      have POS: 0 < size xs.
-      { by apply leq_trans with (id + 1); [rewrite addn1| done]. }
-      split.
-      - by rewrite -(leq_add2r 1) !addn1 prednK // -addn1.
-      - by rewrite prednK.
+      { move: IN => /nthP EX.
+        specialize (EX 0). 
+        move: EX => [id SIZE EQ].
+        rewrite /last0 -nth_last -EQ; subst x.      
+        rewrite -addn1 in SIZE.
+        apply STR; apply/andP.
+        have POS: 0 < size xs.
+        { by apply leq_trans with (id + 1); first rewrite addn1. } 
+        split.
+        - by rewrite -(leq_add2r 1) !addn1 prednK // -addn1.
+        - by rewrite prednK.
+      } 
     Qed.
     
   End NonDecreasingSequence.
@@ -327,7 +325,7 @@ Section NondecreasingSequence.
   (** * Properties of [Undup] of Non-Decreasing Sequence *)
   (** In this section we prove a few lemmas about [undup] of non-decreasing sequences. *)
   Section Undup.
-
+    
     (** First we prove that [undup x::x::xs] is equal to [undup x::xs]. *)
     Remark nodup_sort_2cons_eq:
       forall {X : eqType} (x : X) (xs : seq X),
@@ -335,7 +333,7 @@ Section NondecreasingSequence.
     Proof.
       intros; rewrite {2 3}[cons] lock //= -lock.
       rewrite in_cons eq_refl; simpl.
-        by destruct (x \in xs).
+      by destruct (x \in xs).
     Qed.
 
     (** For non-decreasing sequences we show that the fact that 
@@ -355,8 +353,7 @@ Section NondecreasingSequence.
       apply/eqP; rewrite eqbF_neg.
       apply nondecreasing_sequence_cons in H0.
       apply/negP; intros ?; eauto 2.
-      eapply nondecreasing_sequence_cons_min in H0; eauto 2.
-        by move_neq_down H.
+      by eapply nondecreasing_sequence_cons_min in H0; eauto 2; ssrlia.
     Qed.
 
     (** Next we show that function [undup] doesn't change 
@@ -372,10 +369,10 @@ Section NondecreasingSequence.
       + subst; rename x2 into x.
         rewrite nodup_sort_2cons_eq IHxs.
         rewrite [in X in _ = X]last0_cons //.
-        eapply nondecreasing_sequence_cons; eauto 2.
+        by eapply nondecreasing_sequence_cons; eauto 2.
       + rewrite nodup_sort_2cons_lt // last0_cons.
         rewrite IHxs //; eauto using nondecreasing_sequence_cons.
-          by intros ?; apply undup_nil in H.
+        by intros ?; apply undup_nil in H.
     Qed.
 
     (** Non-decreasing sequence remains non-decreasing after application of [undup]. *)
@@ -386,20 +383,19 @@ Section NondecreasingSequence.
     Proof.
       intros ?.
       have EX: exists len, size xs <= len.
-      { exists (size xs); now simpl. } destruct EX as [n BO].
+      { by exists (size xs). } destruct EX as [n BO].
       revert xs BO; induction n.   
       - by intros xs; rewrite leqn0 size_eq0; move => /eqP EQ; subst xs.
-      - intros [ |x1 [ | x2 xs]]; try done. 
-        intros Size NonDec.        
+      - intros [ |x1 [ | x2 xs]] Size NonDec; try done.
         destruct (nondecreasing_sequence_2cons_leVeq _ _ _ NonDec) as [EQ|LT].
-        * subst; rename x2 into x.
-            by rewrite nodup_sort_2cons_eq; apply IHn; eauto using nondecreasing_sequence_cons.
-        * rewrite nodup_sort_2cons_lt //.
+        + subst; rename x2 into x.
+          by rewrite nodup_sort_2cons_eq; apply IHn; eauto using nondecreasing_sequence_cons.
+        + rewrite nodup_sort_2cons_lt //.
           apply nondecreasing_sequence_add_min.
           intros ? ?.
           eapply nondecreasing_sequence_cons_min with (y := y) in NonDec; auto.
           rewrite -mem_undup; eauto using nondecreasing_sequence_cons.
-            by apply IHn; eauto using nondecreasing_sequence_cons.
+          by apply IHn; eauto using nondecreasing_sequence_cons.
     Qed.
     
     (** We also show that the penultimate element of a sequence [undup xs] 
@@ -411,34 +407,31 @@ Section NondecreasingSequence.
     Proof.
       Opaque undup.
       intros ?.
-      have EX: exists len, size xs <= len.
-      { exists (size xs); now simpl. } destruct EX as [n BO].
+      have EX: exists len, size xs <= len by (exists (size xs)).
+      destruct EX as [n BO].
       revert xs BO; induction n.   
       - by intros xs; rewrite leqn0 size_eq0; move => /eqP EQ; subst xs.
-      - intros [ |x1 [ | x2 xs]]; try done. 
-        intros Size NonDec.          
+      - intros [ |x1 [ | x2 xs]] Size NonDec; try done.
         destruct (nondecreasing_sequence_2cons_leVeq _ _ _ NonDec) as [EQ|LT].
         * subst; rename x2 into x.        
           rewrite nodup_sort_2cons_eq //.
           eapply leq_trans. apply IHn. by done. eapply nondecreasing_sequence_cons; eauto.
           destruct xs as [ | x1 xs]; first by done. 
-            by rewrite [in X in _ <= X]nth0_cons //. 
+          by rewrite [in X in _ <= X]nth0_cons //. 
         * rewrite nodup_sort_2cons_lt //; simpl.
           case (posnP (size (undup (x2 :: xs))).-1) as [Z|POS].
           -- rewrite Z; simpl.
              apply leq_trans with ([:: x1, x2 & xs] [|0|]); first by done.
-               by apply NonDec; apply/andP; split; simpl.
+             by apply NonDec; apply/andP; split; simpl.
           -- rewrite nth0_cons //.
              eapply leq_trans; first apply IHn; eauto using nondecreasing_sequence_cons.
              destruct xs.
              ++ by exfalso. 
              ++ destruct xs; simpl in *; auto.
-                Transparent undup.
     Qed.
     
   End Undup.
 
-
   (** * Properties of Distances *)
   (** In this section we prove a few lemmas about function [distances]. *)
   Section Distances.
@@ -448,7 +441,7 @@ Section NondecreasingSequence.
     Lemma distances_unfold_2cons:
       forall x0 x1 xs, 
         distances (x0::x1::xs) = (x1 - x0) :: distances (x1::xs).
-    Proof. by intros; unfold distances; simpl; rewrite drop0. Qed.  
+    Proof. by intros; rewrite /distances //= drop0. Qed.  
 
     (** Similarly, we prove a lemma stating that two consecutive
         appends to a sequence in [distances] function ([distances(xs
@@ -459,8 +452,9 @@ Section NondecreasingSequence.
         distances (xs ++ [:: a; b])
         = distances (xs ++ [:: a]) ++ [:: b - a].
     Proof.
-      clear; intros.
-      have EX: exists n, size xs <= n. exists (size xs); by done. destruct EX as [n LE].
+      intros.
+      have EX: exists n, size xs <= n by (exists (size xs)).
+      destruct EX as [n LE].
       revert xs LE; induction n; intros.
       - by move: LE; rewrite leqn0 size_eq0; move => /eqP LE; subst.
       - destruct xs as [ | x0]; first by unfold distances.
@@ -468,21 +462,21 @@ Section NondecreasingSequence.
         have -> : distances ([:: x0, x1 & xs] ++ [:: a; b]) =  x1 - x0 :: distances ((x1 :: xs) ++ [:: a; b]).
         { by simpl; rewrite distances_unfold_2cons. }
         rewrite IHn; last by simpl in *; rewrite -(leq_add2r 1) !addn1.
-        have -> : distances ([:: x0, x1 & xs] ++ [:: a]) = x1 - x0 :: distances ((x1 :: xs) ++ [:: a]).
-        { by simpl; rewrite distances_unfold_2cons. }
-          by done.
+        have -> : distances ([:: x0, x1 & xs] ++ [:: a]) = x1 - x0 :: distances ((x1 :: xs) ++ [:: a]); last by done.
+        by rewrite //= distances_unfold_2cons.  
     Qed.
 
     (** We also prove a lemma stating that _one_ append to a sequence
-        in the [distances] function ([distances(xs ++ [:: x])]) can
-        be rewritten as [distances xs ++ [:: x - last0 xs]]. *)
+        in the [distances] function (i.e., [distances(xs ++ [:: x])])
+        can be rewritten as [distances xs ++ [:: x - last0 xs]]. *)
     Lemma distances_unfold_1app_last:
       forall x xs,
         size xs >= 1 ->
         distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs].
     Proof.
-      clear. intros x xs POS.
-      have EX: exists n, size xs <= n. exists (size xs); by done. destruct EX as [n LE].
+      intros x xs POS.
+      have EX: exists n, size xs <= n by (exists (size xs)).
+      destruct EX as [n LE].
       revert x xs LE POS; induction n; intros.
       - by move: LE; rewrite leqn0 size_eq0; move => /eqP LE; subst.
       - move: LE; rewrite leq_eqVlt; move => /orP [/eqP LEN' | LE]; last first.
@@ -499,131 +493,104 @@ Section NondecreasingSequence.
     Qed.
 
     (** We prove that the difference between any two neighboring elements is
-       bounded by the max element of the distances-sequence. *)
+        bounded by the max element of the distances-sequence. *)
     Lemma distance_between_neighboring_elements_le_max_distance_in_seq:
       forall (xs : seq nat) (n : nat),
         xs[|n.+1|] - xs[|n|] <= max0 (distances xs).
     Proof.
-      clear; intros xs id.
+      intros xs id.
       apply leq_trans with (distances xs [| id |]).
       rewrite leq_eqVlt; apply/orP; left; apply/eqP.
-      have EX: exists n, size xs <= n. { by exists (size xs). } move: EX => [n LE].
-      generalize dependent xs; generalize dependent id.
-      induction n. 
-      { intros.
-        move: LE; rewrite leqn0 size_eq0; move => /eqP EQ; subst.
-          by rewrite !nth_default.
+      have EX: exists n, size xs <= n by (exists (size xs)).
+      move: EX => [n LE]; move: xs id LE.
+      induction n; intros.
+      { move: LE; rewrite leqn0 size_eq0; move => /eqP EQ; subst.
+        by rewrite !nth_default.
       }
-      { intros. 
-        move: LE; rewrite leq_eqVlt; move => /orP [/eqP EQ|LT]; last first.
+      { move: LE; rewrite leq_eqVlt; move => /orP [/eqP EQ|LT]; last first.
         { by apply IHn; rewrite ltnS in LT. }
         destruct xs; first by done.
         destruct xs; first by destruct id; [simpl |rewrite !nth_default]. 
-        have Fact: distances [:: n0, n1 & xs] = (n1 - n0) :: distances [:: n1 & xs].
-        { by rewrite /distances; simpl; rewrite drop0. } 
-        rewrite Fact; clear Fact.
+        have ->: distances [:: n0, n1 & xs] = (n1 - n0) :: distances [:: n1 & xs].
+        { by rewrite /distances //= drop0. } 
         destruct id; first by done.
-        simpl.
-        rewrite -IHn. simpl. by done.
-          by move: EQ => /eqP; simpl; rewrite eqSS; move => /eqP EQ; rewrite -EQ.
+        rewrite //= -IHn //=. 
+        by move: EQ => /eqP; rewrite //= eqSS => /eqP EQ; rewrite -EQ.
       }
-      { have Lem: forall x xs, x \in xs -> x <= max0 xs.
-        { clear; intros.
-          generalize dependent x.
-          induction xs; first by done.
-          intros ? IN; rewrite max0_cons leq_max; apply/orP.
+      { have Lem: forall xs x, x \in xs -> x <= max0 xs.
+        { clear; induction xs; intros ? IN; first by done.
+          rewrite max0_cons leq_max; apply/orP.
           move: IN; rewrite in_cons; move => /orP [/eqP EQ| IN].
           - by left; subst.
           - by right; apply IHxs.
         }
         destruct (size (distances xs) <= id) eqn:SIZE.
-        { by rewrite nth_default. }
-        { apply Lem; rewrite mem_nth //.
+        - by rewrite nth_default.
+        - apply Lem; rewrite mem_nth //.
           move: SIZE => /negP /negP.
-            by rewrite ltnNge.
-        } 
+          by rewrite ltnNge.
       }              
     Qed.
 
     (** Note that the distances-function has the expected behavior indeed. I.e. an element 
-       on the position [n] of the distance-sequence is equal to the difference between
-       elements on positions [n+1] and [n]. *)
+        on the position [n] of the distance-sequence is equal to the difference between
+        elements on positions [n+1] and [n]. *)
     Lemma function_of_distances_is_correct:
       forall (xs : seq nat) (n : nat),
         (distances xs)[|n|] = xs[|n.+1|] - xs[|n|].
     Proof.
       intros xs.
-      have EX: exists len, size xs <= len.
-      { by exists (size xs). } move: EX => [len LE].
-      generalize dependent xs.
+      have EX: exists len, size xs <= len by (exists (size xs)).
+      move: EX => [len LE]; move: xs LE.
       induction len; intros.
-      { move: LE; rewrite leqn0 size_eq0; move => /eqP EQ; subst.
-        unfold distances. simpl.
-          by destruct n; simpl.
-      } 
+      { by move: LE; rewrite leqn0 size_eq0; move => /eqP EQ; subst; destruct n. } 
       move: LE; rewrite leq_eqVlt; move => /orP [/eqP EQ| LE]; last by apply IHlen.
       destruct xs as [ | x1 xs]; first by done.
-      destruct xs as [ | x2 xs].
-      { by destruct n as [ | [ | ]]. }
+      destruct xs as [ | x2 xs]; first by destruct n as [ | [ | ]].
       destruct n; first by done. 
-      have F: distances [:: x1, x2 & xs] [|n.+1|] = distances [::x2 & xs] [| n |].
-      { have EQ': distances [:: x1, x2 & xs] = (x2 - x1) :: distances [::x2 & xs].
-        { by unfold distances; simpl; rewrite drop0. } 
-          by rewrite EQ'.
+      have ->: distances [:: x1, x2 & xs] [|n.+1|] = distances [::x2 & xs] [| n |].
+      { have ->: distances [:: x1, x2 & xs] = (x2 - x1) :: distances [::x2 & xs]; last by done.
+        { by rewrite /distances //= drop0. } 
       }
-      have F2: [:: x1, x2 & xs] [|n.+2|] - [:: x1, x2 & xs] [|n.+1|] = [:: x2 & xs] [|n.+1|] - [:: x2 & xs] [|n|]; first by done.
-      rewrite F F2. 
+      have ->: [:: x1, x2 & xs] [|n.+2|] - [:: x1, x2 & xs] [|n.+1|] = [:: x2 & xs] [|n.+1|] - [:: x2 & xs] [|n|] by done.
       apply IHlen.
-      move: EQ => /eqP; simpl; rewrite eqSS; move => /eqP EQ.
-        by rewrite -EQ. 
+      by move: EQ => /eqP; rewrite //= eqSS => /eqP <-.
     Qed.
 
     (** We show that the size of a distances-sequence is one less 
-       than the size of the original sequence. *)
+        than the size of the original sequence. *)
     Lemma size_of_seq_of_distances:
       forall (xs : seq nat),
         2 <= size xs ->
         size xs = size (distances xs) + 1.
     Proof.
-      clear.
       intros xs.
-      have EX: exists len, size xs <= len.
-      { exists (size xs). by done. } 
-      move: EX => [len LE].
-      generalize dependent xs.
-      induction len.
-      { intros.
-        move: LE; rewrite leqn0 size_eq0; move => /eqP EQ; subst.
-          by done.
+      have EX: exists len, size xs <= len by (exists (size xs)).
+      move: EX => [len LE]; move: xs LE.
+      induction len; intros * LE SIZE.
+      { by move: LE; rewrite leqn0 size_eq0; move => /eqP EQ; subst. } 
+      { move: LE; rewrite leq_eqVlt; move => /orP [/eqP EQ| LE]; last by apply IHlen.
+        destruct xs as [ | x1 xs]; first by inversion EQ.
+        destruct xs as [ | x2 xs]; first by inversion SIZE.
+        destruct xs as [ | x3 xs]; first by done.
+        clear SIZE.
+        have ->: size [:: x1, x2, x3 & xs] = size [:: x2, x3 & xs] + 1 by rewrite addn1.
+        have ->: size (distances [:: x1, x2, x3 & xs]) = size (distances [:: x2, x3 & xs]) + 1 by rewrite addn1.
+        apply/eqP; rewrite eqn_add2r; apply/eqP.
+        apply IHlen; last by done.
+        by move: EQ => /eqP; rewrite //= eqSS => /eqP <-.
       }
-      intros ? ? SIZE.
-      move: LE; rewrite leq_eqVlt; move => /orP [/eqP EQ| LE]; last first.
-      { by apply IHlen. }
-      destruct xs as [ | x1 xs]; first by inversion EQ.
-      destruct xs as [ | x2 xs]; first by inversion SIZE.
-      destruct xs as [ | x3 xs]; first by done.
-      clear SIZE.
-      have F1: size [:: x1, x2, x3 & xs] = size [:: x2, x3 & xs] + 1.
-      { by rewrite addn1. } 
-      have F2: size (distances [:: x1, x2, x3 & xs]) = size (distances [:: x2, x3 & xs]) + 1.
-      { by rewrite addn1. }
-      rewrite F1 F2; clear F1 F2.
-      apply/eqP; rewrite eqn_add2r; apply/eqP.
-      apply IHlen; last by done.
-      move: EQ => /eqP. simpl. rewrite eqSS; move => /eqP EQ.
-        by rewrite -EQ.
     Qed.
 
     (** We prove that [index_iota 0 n] produces a sequence of numbers
-        with which are always one unit apart each other. *)
+        which are always one unit apart each other. *)
     Lemma distances_of_iota_ε:
       forall n x, x \in distances (index_iota 0 n) -> x = ε.
     Proof.
-      clear; intros n x IN.
-      induction n.
+      intros n x IN; induction n.
       - by unfold index_iota, distances in IN.
       - destruct n; first by unfold distances, index_iota in IN. 
-        rewrite -addn1 /index_iota subn0 iota_add in IN .
+        rewrite -addn1 /index_iota subn0 iota_add in IN.
         rewrite add0n in IN. 
         rewrite distances_unfold_1app_last in IN; last by rewrite size_iota. 
         move: IN; rewrite mem_cat; move => /orP [IN|IN].
@@ -647,8 +614,8 @@ Section NondecreasingSequence.
         (exists x y, x \in xs /\ y \in xs /\ x <> y) -> 
         0 < max0 (distances xs).
     Proof.
-      move => xs SIZE SMI. move: SMI => [x [y [INx [INy NEQ]]]].
-      move: INx INy => /nthP INx /nthP INy. specialize (INx 0); specialize (INy 0).
+      move => xs SIZE [x [y [INx [INy NEQ]]]].
+      move: INx INy => /nthP INx /nthP INy; specialize (INx 0); specialize (INy 0).
       move: INx INy => [indx SIZEx EQx] [indy SIZEy EQy].
       have L: forall (x y indx indy : nat),
           indx < size xs -> indy < size xs ->
@@ -659,8 +626,8 @@ Section NondecreasingSequence.
         have LTind: indx < indy. 
         { rewrite ltnNge; apply/negP; intros CONTR.
           subst x y; move: LT; rewrite ltnNge; move => /negP T; apply: T.
-            by apply SIZE; apply/andP. } 
-        have EQ: exists Δ, indy = indx + Δ. exists (indy - indx); ssrlia. move: EQ => [Δ EQ]; subst indy.
+          by apply SIZE; apply/andP. } 
+        have EQ: exists Δ, indy = indx + Δ; [by exists (indy - indx); ssrlia | move: EQ => [Δ EQ]; subst indy].
         have F: exists ind, indx <= ind < indx + Δ /\ xs[|ind|] < xs[|ind.+1|].
         { subst x y; clear SIZEx SIZEy; revert xs indx LTind SIZE LT.
           induction Δ; intros; first by ssrlia.
@@ -671,56 +638,47 @@ Section NondecreasingSequence.
             apply SIZE; apply/andP; split; first by done.
             rewrite ltnNge; apply/negP; intros CONTR.
             move: LT; rewrite ltnNge; move => /negP LT; apply: LT.
-              by rewrite nth_default ?addnS. }                    
+            by rewrite nth_default ?addnS. }                    
           move: ALT => [/eqP EQ|LT'].
           - edestruct (IHΔ) as [ind [B UP]]; eauto 5 using addn1, leq_add2l.
             exists ind; split; last by done.
             move: B => /andP [B1 B2]; apply/andP; split; first by done.
-              by rewrite addnS ltnS ltnW. 
+            by rewrite addnS ltnS ltnW. 
           - exists (indx + Δ); split; last by rewrite -addnS.
-              by apply/andP; split; [rewrite leq_addr | rewrite addnS].  }
+            by apply/andP; split; [rewrite leq_addr | rewrite addnS].  }
         move: F => [ind [/andP [B1 B2] UP]].
         apply leq_trans with (xs [|ind.+1|] - xs [|ind|]).
         - by rewrite subn_gt0.
         - by apply distance_between_neighboring_elements_le_max_distance_in_seq.
       }
       move: NEQ => /eqP; rewrite neq_ltn; move => /orP [LT|LT].
-      - eapply L with (indx := indx) (x := x) (y := y); eauto.
-      - eapply L with (indx := indy) (indy := indx) (x := y) (y := x); eauto. 
+      - by eapply L with (indx := indx) (x := x) (y := y); eauto.
+      - by eapply L with (indx := indy) (indy := indx) (x := y) (y := x); eauto. 
     Qed.  
 
-    (** Given a non-decreasing sequence [xs] with length n, we show that the difference 
-       between the last element of [xs] and the last element of the distances-sequence 
-       of [xs] is equal to [xs[n-2]]. *)
+    (** Given a non-decreasing sequence [xs] with length [n], we show that the difference 
+        between the last element of [xs] and the last element of the distances-sequence 
+        of [xs] is equal to [xs[n-2]]. *)
     Lemma last_seq_minus_last_distance_seq:
       forall (xs : seq nat),
         nondecreasing_sequence xs ->
         last0 xs - last0 (distances xs) = xs [| (size xs).-2 |].
     Proof.
-      clear.
+      unfold nondecreasing_sequence in *.
       intros xs SIS.
-      destruct xs as [ | x1 xs]. by done.
-      destruct xs as [ | x2 xs]. by rewrite subn0.
-      rewrite {2}/last0 -[in X in _ - X]nth_last function_of_distances_is_correct prednK;
-        last by done.
+      destruct xs as [ | x1 xs]; first by done.
+      destruct xs as [ | x2 xs]; first by rewrite subn0.
+      rewrite {2}/last0 -[in X in _ - X]nth_last function_of_distances_is_correct prednK; last by done.
       set [:: x1, x2 & xs] as X.
-      rewrite /last0 -nth_last.
-      rewrite size_of_seq_of_distances; last by done.
-      rewrite !addn1.
-      rewrite -pred_Sn.
-      rewrite subKn; first by done.
-      unfold X.
-      unfold nondecreasing_sequence in *.
-      apply SIS.
-      apply/andP; split.
-      simpl; by done.
-      rewrite [in X in _ < X]size_of_seq_of_distances; last by done.
-        by rewrite addn1.
+      rewrite /last0 -nth_last size_of_seq_of_distances; last by done.
+      rewrite !addn1 -pred_Sn subKn; first by done.
+      rewrite /X; apply SIS; apply/andP; split; first by simpl.
+      by rewrite [in X in _ < X]size_of_seq_of_distances; first rewrite addn1.
     Qed.
 
-    (** The max element of the distances-sequence of a sequence [xs] is bounded 
-       by the last element of [xs]. Note that all elements of [xs] are positive.
-       Thus they all lie within the interval [0, last xs]. *)
+    (** The max element of the distances-sequence of a sequence [xs]
+        is bounded by the last element of [xs]. Since all elements of
+        [xs] are non-negative, they all lie within the interval [0, last xs]. *)
     Lemma max_distance_in_seq_le_last_element_of_seq:
       forall (xs : seq nat),
         nondecreasing_sequence xs ->
@@ -739,11 +697,10 @@ Section NondecreasingSequence.
         + by apply H; rewrite in_cons; apply/orP; left.
         + by apply IHxs; intros; apply H; rewrite in_cons; apply/orP; right.
       }
-      apply F; clear F; intros d IN. 
+      apply: F => d IN. 
       move: IN => /nthP T; specialize (T 0); move: T => [idx IN DIST].
       rewrite function_of_distances_is_correct in DIST.
-      rewrite -DIST.
-      rewrite leq_sub //.
+      rewrite -DIST leq_sub //.
       { destruct (xs [|idx.+1|] == last0 xs) eqn:EQ.
         - by rewrite leq_eqVlt; apply/orP; left.
         - rewrite /last0 -nth_last. apply H. 
@@ -761,7 +718,7 @@ Section NondecreasingSequence.
           rewrite -(ltn_add2r 1) addn1 -size_of_seq_of_distances in IN; last by done.
           destruct idx; first by move: EQ; rewrite /first0 -nth0; move => /eqP.
           apply/andP; split; first by done.
-            by apply ltn_trans with idx.+2.
+          by apply ltn_trans with idx.+2.
       }
     Qed.
 
@@ -775,23 +732,20 @@ Section NondecreasingSequence.
         distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] = [seq x <- distances xs | 0 < x]. 
     Proof.
       intros xs.
-      have EX: exists len, size xs <= len.
-      { exists (size xs); now simpl. } destruct EX as [n BO].
-      revert xs BO; induction n.
-      { intros ? Len k Bound NonDec.
-        move: Len; rewrite leqn0 size_eq0; move => /eqP T; subst.
-          by rewrite filter_pred0.
+      have EX: exists len, size xs <= len by (exists (size xs)).
+      destruct EX as [n BO].
+      revert xs BO; induction n; intros ? Len k Bound NonDec.
+      { move: Len; rewrite leqn0 size_eq0; move => /eqP T; subst.
+        by rewrite filter_pred0.
       }
-      { intros ? Len k Bound NonDec.
-        destruct xs as [ |x1 [ |x2 xs]].
+      { destruct xs as [ |x1 [ |x2 xs]].
         - by rewrite filter_pred0.
         - by rewrite index_iota_filter_singl; last (rewrite ltnS; apply Bound; rewrite in_cons; apply/orP; left).
         - have LEx1: x1 <= k. by apply Bound; rewrite in_cons eq_refl.
           have LEx2: x2 <= k. by apply Bound; rewrite !in_cons eq_refl orbT.
           have M1: forall y : nat, y \in x2 :: xs -> x1 <= y. by apply nondecreasing_sequence_cons_min.
           have M2: forall x : nat, x \in x2 :: xs -> x <= k. by intros; apply Bound; rewrite in_cons; apply/orP; right.
-          have M3: forall y : nat, y \in xs -> x2 <= y
-              by apply nondecreasing_sequence_cons in NonDec; apply nondecreasing_sequence_cons_min.
+          have M3: forall y : nat, y \in xs -> x2 <= y by apply nondecreasing_sequence_cons in NonDec; apply nondecreasing_sequence_cons_min.
           destruct (nondecreasing_sequence_2cons_leVeq _ _ _ NonDec).
           + subst; rewrite distances_unfold_2cons.
             replace ((@filter nat (fun x : nat => leq (S O) x) (@cons nat (subn x2 x2) (distances (@cons nat x2 xs)))))
@@ -806,7 +760,7 @@ Section NondecreasingSequence.
             { simpl; replace (0 < x2 - x1) with true; first by done.
                 by apply/eqP; rewrite eq_sym; rewrite eqb_id subn_gt0. }
             rewrite -(IHn _ _ k) //; last eapply nondecreasing_sequence_cons; eauto 2.
-            rewrite {1}range_iota_filter_step //. rewrite distances_unfold_2cons. rewrite {1}range_iota_filter_step //. 
+            by rewrite {1}range_iota_filter_step // distances_unfold_2cons {1}range_iota_filter_step //. 
       }
     Qed.
     
@@ -824,8 +778,7 @@ Section NondecreasingSequence.
       have EX: exists len, size xs <= len.
       { exists (size xs); now simpl. } destruct EX as [n BO].
       revert xs NonDec BO; induction n.
-      - intros xs _; rewrite leqn0 size_eq0; move => /eqP EQ; subst xs.
-          by rewrite filter_pred0.
+      - by intros xs _; rewrite leqn0 size_eq0 => /eqP ->; rewrite filter_pred0.
       - intros [ |x1 [ | x2 xs]].
         + by rewrite filter_pred0.
         + by rewrite index_iota_filter_singl ?L02 //; apply/andP; split; [ done | destruct x1].  
@@ -833,23 +786,23 @@ Section NondecreasingSequence.
           destruct (nondecreasing_sequence_2cons_leVeq _ _ _ NonDec) as [EQ|LT].
           * subst; rename x2 into x.
             rewrite nodup_sort_2cons_eq range_filter_2cons max0_2cons_eq.
-              by apply IHn; [ eapply nondecreasing_sequence_cons; eauto | by done]. 
+            by apply IHn; [ eapply nondecreasing_sequence_cons; eauto | by done]. 
           * rewrite nodup_sort_2cons_lt // max0_2cons_le; last by rewrite ltnW.
             rewrite index_iota_filter_step; [ | | by apply nondecreasing_sequence_cons_min]; last first.
             { apply/andP; split; first by done.
               eapply leq_trans; first by eassumption.
               rewrite ltnW // ltnS; apply in_max0_le.
-                by rewrite in_cons eq_refl.
+              by rewrite in_cons eq_refl.
             }
             rewrite rem_lt_id //; last by apply nondecreasing_sequence_cons_smin.
-            rewrite IHn //; eauto using nondecreasing_sequence_cons.
+            by rewrite IHn //; eauto using nondecreasing_sequence_cons.
     Qed.
 
   
     (** Consider two non-decreasing sequences [xs] and [ys] and assume that 
-       (1) first element of [xs] is at most the first element of [ys] and 
-       (2) distances-sequences of [xs] is dominated by distances-sequence of 
-       [ys]. Then [xs] is dominated by [ys].  *)
+        (1) first element of [xs] is at most the first element of [ys] and 
+        (2) distances-sequences of [xs] is dominated by distances-sequence of 
+        [ys]. Then [xs] is dominated by [ys].  *)
     Lemma domination_of_distances_implies_domination_of_seq:
       forall (xs ys : seq nat),
         first0 xs <= first0 ys ->
@@ -864,13 +817,11 @@ Section NondecreasingSequence.
       intros xs ys.
       have EX: exists len, size xs <= len /\ size ys <= len.
       { exists (maxn (size xs) (size ys)).
-          by split; rewrite leq_max; apply/orP; [left | right].
+        by split; rewrite leq_max; apply/orP; [left | right].
       } move: EX => [len [LE1 LE2]]. 
       generalize dependent xs; generalize dependent ys. 
       induction len.
-      { intros; move: LE1 LE2; rewrite !leqn0 !size_eq0; move => /eqP E1 /eqP E2.
-          by subst.
-      }
+      { by intros; move: LE1 LE2; rewrite !leqn0 !size_eq0 => /eqP -> /eqP ->.  } 
       { intros ? LycSIZE ? LxSIZE FLE Sxs Sys SIZEEQ STRxs STRys LE n.
         destruct xs as [ | x1 xs], ys as [ | y1 ys]; try by done.
         destruct xs as [ | x2 xs], ys as [ | y2 ys]; try by done.
@@ -897,7 +848,7 @@ Section NondecreasingSequence.
           apply (STRys m1.+1 m2.+1); apply/andP; split.
           + by rewrite ltnS.
           + by rewrite -(ltn_add2r 1) !addn1 in B2. 
-        - intros. specialize (LE n0.+1). simpl in LE. by done.
+        - by intros; specialize (LE n0.+1); simpl in LE.
       }
     Qed.
 
-- 
GitLab