Library prosa.util.nondecreasing


(* ----------------------------------[ coqtop ]---------------------------------

Welcome to Coq 8.13.0 (January 2021)

----------------------------------------------------------------------------- *)


Require Export prosa.util.epsilon.
Require Export prosa.util.nat.
Require Export prosa.util.list.
From mathcomp Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq fintype bigop.

Non-Decreasing Sequence and Distances

In this file we introduce the notion of a non-decreasing sequence.
First, let's introduce the notion of the nth element of a sequence.
  Notation "xs [| n |]" := (nth 0 xs n) (at level 30).

In this section we provide the notion of a non-decreasing sequence.
  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.
    Definition nondecreasing_sequence (xs : seq nat) :=
       n1 n2,
        n1 n2 < size xs
        xs[|n1|] xs[|n2|].

Similarly, we define an increasing sequence.
    Definition increasing_sequence (xs : seq nat) :=
       n1 n2,
        n1 < n2 < size xs
        xs[|n1|] < xs[|n2|].

For a non-decreasing sequence we define the notion of distances between neighboring elements of the sequence. Example: Consider the following sequence of natural numbers: [xs] = [:: 1; 10; 10; 17; 20; 41]. Then [drop 1 xs] is equal to [:: 10; 10; 17; 20; 41]. Then [zip xs (drop 1 xs)] is equal to [:: (1,10); (10,10); (10,17); (17,20); (20,41)] And after the mapping [map (fun '(x1, x2) => x2 - x1)] we end up with [:: 9; 0; 7; 3; 21].
    Definition distances (xs : seq nat) :=
      map (fun '(x1, x2)x2 - x1) (zip xs (drop 1 xs)).

  End Definitions.

Properties of Increasing Sequence

In this section we prove a few lemmas about increasing sequences.
  Section IncreasingSequence.

Note that a filtered iota sequence is an increasing sequence.
    Lemma iota_is_increasing_sequence:
       a b P,
        increasing_sequence [seq x <- index_iota a b | P x].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 24)
  
  ============================
  forall (a b : nat) (P : nat -> bool),
  increasing_sequence [seq x <- index_iota a b | P x]

----------------------------------------------------------------------------- *)


    Proof.
      clear; intros ? ? ?.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 27)
  
  a, b : nat
  P : nat -> bool
  ============================
  increasing_sequence [seq x <- index_iota a b | P x]

----------------------------------------------------------------------------- *)


      have EX : k, b - a k.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 30)
  
  a, b : nat
  P : nat -> bool
  ============================
  exists k : nat, b - a <= k

subgoal 2 (ID 32) is:
 increasing_sequence [seq x <- index_iota a b | P x]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 30)
  
  a, b : nat
  P : nat -> bool
  ============================
  exists k : nat, b - a <= k

----------------------------------------------------------------------------- *)


(b-a); now simpl.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 32) is:
 increasing_sequence [seq x <- index_iota a b | P x]

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 32)
  
  a, b : nat
  P : nat -> bool
  EX : exists k : nat, b - a <= k
  ============================
  increasing_sequence [seq x <- index_iota a b | P x]

----------------------------------------------------------------------------- *)


destruct EX as [k BO].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 40)
  
  a, b : nat
  P : nat -> bool
  k : nat
  BO : b - a <= k
  ============================
  increasing_sequence [seq x <- index_iota a b | P x]

----------------------------------------------------------------------------- *)


      revert a b P BO; induction k.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 46)
  
  ============================
  forall (a b : nat) (P : nat -> bool),
  b - a <= 0 -> increasing_sequence [seq x <- index_iota a b | P x]

subgoal 2 (ID 49) is:
 forall (a b : nat) (P : nat -> bool),
 b - a <= k.+1 -> increasing_sequence [seq x <- index_iota a b | P x]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 46)
  
  ============================
  forall (a b : nat) (P : nat -> bool),
  b - a <= 0 -> increasing_sequence [seq x <- index_iota a b | P x]

----------------------------------------------------------------------------- *)


movea b P BO n1 n2.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 56)
  
  a, b : nat
  P : nat -> bool
  BO : b - a <= 0
  n1, n2 : nat
  ============================
  n1 < n2 < size [seq x <- index_iota a b | P x] ->
  [seq x <- index_iota a b | P x] [|n1|] <
  [seq x <- index_iota a b | P x] [|n2|]

----------------------------------------------------------------------------- *)


        move: BO; rewrite leqn0; move ⇒ /eqP BO.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 94)
  
  a, b : nat
  P : nat -> bool
  n1, n2 : nat
  BO : b - a = 0
  ============================
  n1 < n2 < size [seq x <- index_iota a b | P x] ->
  [seq x <- index_iota a b | P x] [|n1|] <
  [seq x <- index_iota a b | P x] [|n2|]

----------------------------------------------------------------------------- *)


        rewrite /index_iota BO; simpl.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 112)
  
  a, b : nat
  P : nat -> bool
  n1, n2 : nat
  BO : b - a = 0
  ============================
  n1 < n2 < 0 -> [::] [|n1|] < [::] [|n2|]

----------------------------------------------------------------------------- *)


          by move ⇒ /andP [_ F].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 49) is:
 forall (a b : nat) (P : nat -> bool),
 b - a <= k.+1 -> increasing_sequence [seq x <- index_iota a b | P x]

----------------------------------------------------------------------------- *)


      }
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 49)
  
  k : nat
  IHk : forall (a b : nat) (P : nat -> bool),
        b - a <= k -> increasing_sequence [seq x <- index_iota a b | P x]
  ============================
  forall (a b : nat) (P : nat -> bool),
  b - a <= k.+1 -> increasing_sequence [seq x <- index_iota a b | P x]

----------------------------------------------------------------------------- *)



      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 49)
  
  k : nat
  IHk : forall (a b : nat) (P : nat -> bool),
        b - a <= k -> increasing_sequence [seq x <- index_iota a b | P x]
  ============================
  forall (a b : nat) (P : nat -> bool),
  b - a <= k.+1 -> increasing_sequence [seq x <- index_iota a b | P x]

----------------------------------------------------------------------------- *)


movea b P BO n1 n2 /andP [GE LT].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 218)
  
  k : nat
  IHk : forall (a b : nat) (P : nat -> bool),
        b - a <= k -> increasing_sequence [seq x <- index_iota a b | P x]
  a, b : nat
  P : nat -> bool
  BO : b - a <= k.+1
  n1, n2 : nat
  GE : n1 < n2
  LT : n2 < size [seq x <- index_iota a b | P x]
  ============================
  [seq x <- index_iota a b | P x] [|n1|] <
  [seq x <- index_iota a b | P x] [|n2|]

----------------------------------------------------------------------------- *)


        case: (leqP b a) ⇒ [N|N].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 234)
  
  k : nat
  IHk : forall (a b : nat) (P : nat -> bool),
        b - a <= k -> increasing_sequence [seq x <- index_iota a b | P x]
  a, b : nat
  P : nat -> bool
  BO : b - a <= k.+1
  n1, n2 : nat
  GE : n1 < n2
  LT : n2 < size [seq x <- index_iota a b | P x]
  N : b <= a
  ============================
  [seq x <- index_iota a b | P x] [|n1|] <
  [seq x <- index_iota a b | P x] [|n2|]

subgoal 2 (ID 235) is:
 [seq x <- index_iota a b | P x] [|n1|] <
 [seq x <- index_iota a b | P x] [|n2|]

----------------------------------------------------------------------------- *)


        - move: N; rewrite -subn_eq0; move ⇒ /eqP EQ.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 274)
  
  k : nat
  IHk : forall (a b : nat) (P : nat -> bool),
        b - a <= k -> increasing_sequence [seq x <- index_iota a b | P x]
  a, b : nat
  P : nat -> bool
  BO : b - a <= k.+1
  n1, n2 : nat
  GE : n1 < n2
  LT : n2 < size [seq x <- index_iota a b | P x]
  EQ : b - a = 0
  ============================
  [seq x <- index_iota a b | P x] [|n1|] <
  [seq x <- index_iota a b | P x] [|n2|]

subgoal 2 (ID 235) is:
 [seq x <- index_iota a b | P x] [|n1|] <
 [seq x <- index_iota a b | P x] [|n2|]

----------------------------------------------------------------------------- *)


          rewrite /index_iota EQ //= in LT.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 235)
  
  k : nat
  IHk : forall (a b : nat) (P : nat -> bool),
        b - a <= k -> increasing_sequence [seq x <- index_iota a b | P x]
  a, b : nat
  P : nat -> bool
  BO : b - a <= k.+1
  n1, n2 : nat
  GE : n1 < n2
  LT : n2 < size [seq x <- index_iota a b | P x]
  N : a < b
  ============================
  [seq x <- index_iota a b | P x] [|n1|] <
  [seq x <- index_iota a b | P x] [|n2|]

----------------------------------------------------------------------------- *)


        - rewrite index_iota_lt_step; last by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 314)
  
  k : nat
  IHk : forall (a b : nat) (P : nat -> bool),
        b - a <= k -> increasing_sequence [seq x <- index_iota a b | P x]
  a, b : nat
  P : nat -> bool
  BO : b - a <= k.+1
  n1, n2 : nat
  GE : n1 < n2
  LT : n2 < size [seq x <- index_iota a b | P x]
  N : a < b
  ============================
  [seq x <- a :: index_iota a.+1 b | P x] [|n1|] <
  [seq x <- a :: index_iota a.+1 b | P x] [|n2|]

----------------------------------------------------------------------------- *)


          simpl; destruct (P a) eqn:PA.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 332)
  
  k : nat
  IHk : forall (a b : nat) (P : nat -> bool),
        b - a <= k -> increasing_sequence [seq x <- index_iota a b | P x]
  a, b : nat
  P : nat -> bool
  BO : b - a <= k.+1
  n1, n2 : nat
  GE : n1 < n2
  LT : n2 < size [seq x <- index_iota a b | P x]
  N : a < b
  PA : P a = true
  ============================
  (a :: [seq x <- index_iota a.+1 b | P x]) [|n1|] <
  (a :: [seq x <- index_iota a.+1 b | P x]) [|n2|]

subgoal 2 (ID 333) is:
 [seq x <- index_iota a.+1 b | P x] [|n1|] <
 [seq x <- index_iota a.+1 b | P x] [|n2|]

----------------------------------------------------------------------------- *)


          + destruct n1, n2; try done; simpl.

(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 474)
  
  k : nat
  IHk : forall (a b : nat) (P : nat -> bool),
        b - a <= k -> increasing_sequence [seq x <- index_iota a b | P x]
  a, b : nat
  P : nat -> bool
  BO : b - a <= k.+1
  n2 : nat
  GE : 0 < n2.+1
  LT : n2.+1 < size [seq x <- index_iota a b | P x]
  N : a < b
  PA : P a = true
  ============================
  a < [seq x <- index_iota a.+1 b | P x] [|n2|]

subgoal 2 (ID 477) is:
 [seq x <- index_iota a.+1 b | P x] [|n1|] <
 [seq x <- index_iota a.+1 b | P x] [|n2|]
subgoal 3 (ID 333) is:
 [seq x <- index_iota a.+1 b | P x] [|n1|] <
 [seq x <- index_iota a.+1 b | P x] [|n2|]

----------------------------------------------------------------------------- *)


            × apply iota_filter_gt; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 479)
  
  k : nat
  IHk : forall (a b : nat) (P : nat -> bool),
        b - a <= k -> increasing_sequence [seq x <- index_iota a b | P x]
  a, b : nat
  P : nat -> bool
  BO : b - a <= k.+1
  n2 : nat
  GE : 0 < n2.+1
  LT : n2.+1 < size [seq x <- index_iota a b | P x]
  N : a < b
  PA : P a = true
  ============================
  n2 < size [seq x <- index_iota a.+1 b | P x]

subgoal 2 (ID 477) is:
 [seq x <- index_iota a.+1 b | P x] [|n1|] <
 [seq x <- index_iota a.+1 b | P x] [|n2|]
subgoal 3 (ID 333) is:
 [seq x <- index_iota a.+1 b | P x] [|n1|] <
 [seq x <- index_iota a.+1 b | P x] [|n2|]

----------------------------------------------------------------------------- *)


              rewrite index_iota_lt_step // //= PA //= in LT.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 477)
  
  k : nat
  IHk : forall (a b : nat) (P : nat -> bool),
        b - a <= k -> increasing_sequence [seq x <- index_iota a b | P x]
  a, b : nat
  P : nat -> bool
  BO : b - a <= k.+1
  n1, n2 : nat
  GE : n1.+1 < n2.+1
  LT : n2.+1 < size [seq x <- index_iota a b | P x]
  N : a < b
  PA : P a = true
  ============================
  [seq x <- index_iota a.+1 b | P x] [|n1|] <
  [seq x <- index_iota a.+1 b | P x] [|n2|]

subgoal 2 (ID 333) is:
 [seq x <- index_iota a.+1 b | P x] [|n1|] <
 [seq x <- index_iota a.+1 b | P x] [|n2|]

----------------------------------------------------------------------------- *)


            × apply IHk; try ssrlia.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 547)
  
  k : nat
  IHk : forall (a b : nat) (P : nat -> bool),
        b - a <= k -> increasing_sequence [seq x <- index_iota a b | P x]
  a, b : nat
  P : nat -> bool
  BO : b - a <= k.+1
  n1, n2 : nat
  GE : n1.+1 < n2.+1
  LT : n2.+1 < size [seq x <- index_iota a b | P x]
  N : a < b
  PA : P a = true
  ============================
  n1 < n2 < size [seq x <- index_iota a.+1 b | P x]

subgoal 2 (ID 333) is:
 [seq x <- index_iota a.+1 b | P x] [|n1|] <
 [seq x <- index_iota a.+1 b | P x] [|n2|]

----------------------------------------------------------------------------- *)


              apply/andP; split; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 1182)
  
  k : nat
  IHk : forall (a b : nat) (P : nat -> bool),
        b - a <= k -> increasing_sequence [seq x <- index_iota a b | P x]
  a, b : nat
  P : nat -> bool
  BO : b - a <= k.+1
  n1, n2 : nat
  GE : n1.+1 < n2.+1
  LT : n2.+1 < size [seq x <- index_iota a b | P x]
  N : a < b
  PA : P a = true
  ============================
  n2 < size [seq x <- index_iota a.+1 b | P x]

subgoal 2 (ID 333) is:
 [seq x <- index_iota a.+1 b | P x] [|n1|] <
 [seq x <- index_iota a.+1 b | P x] [|n2|]

----------------------------------------------------------------------------- *)


              rewrite index_iota_lt_step // //= PA //= in LT.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 333)
  
  k : nat
  IHk : forall (a b : nat) (P : nat -> bool),
        b - a <= k -> increasing_sequence [seq x <- index_iota a b | P x]
  a, b : nat
  P : nat -> bool
  BO : b - a <= k.+1
  n1, n2 : nat
  GE : n1 < n2
  LT : n2 < size [seq x <- index_iota a b | P x]
  N : a < b
  PA : P a = false
  ============================
  [seq x <- index_iota a.+1 b | P x] [|n1|] <
  [seq x <- index_iota a.+1 b | P x] [|n2|]

----------------------------------------------------------------------------- *)


          + apply IHk; try ssrlia.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 1250)
  
  k : nat
  IHk : forall (a b : nat) (P : nat -> bool),
        b - a <= k -> increasing_sequence [seq x <- index_iota a b | P x]
  a, b : nat
  P : nat -> bool
  BO : b - a <= k.+1
  n1, n2 : nat
  GE : n1 < n2
  LT : n2 < size [seq x <- index_iota a b | P x]
  N : a < b
  PA : P a = false
  ============================
  n1 < n2 < size [seq x <- index_iota a.+1 b | P x]

----------------------------------------------------------------------------- *)


            apply/andP; split; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 1884)
  
  k : nat
  IHk : forall (a b : nat) (P : nat -> bool),
        b - a <= k -> increasing_sequence [seq x <- index_iota a b | P x]
  a, b : nat
  P : nat -> bool
  BO : b - a <= k.+1
  n1, n2 : nat
  GE : n1 < n2
  LT : n2 < size [seq x <- index_iota a b | P x]
  N : a < b
  PA : P a = false
  ============================
  n2 < size [seq x <- index_iota a.+1 b | P x]

----------------------------------------------------------------------------- *)


            rewrite index_iota_lt_step // //= PA //= in LT.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


      }
(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)



    Qed.

We prove that any increasing sequence is also a non-decreasing sequence.
    Lemma increasing_implies_nondecreasing:
       xs,
        increasing_sequence xs
        nondecreasing_sequence xs.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 26)
  
  ============================
  forall xs : seq nat, increasing_sequence xs -> nondecreasing_sequence xs

----------------------------------------------------------------------------- *)


    Proof.
      intros ? INC.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 28)
  
  xs : seq nat
  INC : increasing_sequence xs
  ============================
  nondecreasing_sequence xs

----------------------------------------------------------------------------- *)


      intros n1 n2.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 31)
  
  xs : seq nat
  INC : increasing_sequence xs
  n1, n2 : nat
  ============================
  n1 <= n2 < size xs -> xs [|n1|] <= xs [|n2|]

----------------------------------------------------------------------------- *)


      move ⇒ /andP; rewrite leq_eqVlt; move ⇒ [/orP [/eqP EQ| LT1] LT2].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 147)
  
  xs : seq nat
  INC : increasing_sequence xs
  n1, n2 : nat
  EQ : n1 = n2
  LT2 : n2 < size xs
  ============================
  xs [|n1|] <= xs [|n2|]

subgoal 2 (ID 148) is:
 xs [|n1|] <= xs [|n2|]

----------------------------------------------------------------------------- *)


      - by subst.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 148)
  
  xs : seq nat
  INC : increasing_sequence xs
  n1, n2 : nat
  LT1 : n1 < n2
  LT2 : n2 < size xs
  ============================
  xs [|n1|] <= xs [|n2|]

----------------------------------------------------------------------------- *)


      - by apply ltnW; apply INC; apply/andP; split.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

  End IncreasingSequence.

Properties of Non-Decreasing Sequence

In this section we prove a few lemmas about non-decreasing sequences.
  Section NonDecreasingSequence.

First we prove that if [0 ∈ xs], then [0] is the first element of [xs].
    Lemma nondec_seq_zero_first:
       xs,
        (0 \in xs)
        nondecreasing_sequence xs
        first0 xs = 0.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 24)
  
  ============================
  forall xs : seq_predType nat_eqType,
  0 \in xs -> nondecreasing_sequence xs -> first0 xs = 0

----------------------------------------------------------------------------- *)


    Proof.
      destruct xs as [ | x xs]; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 32)
  
  x : nat_eqType
  xs : seq nat_eqType
  ============================
  0 \in x :: xs -> nondecreasing_sequence (x :: xs) -> first0 (x :: xs) = 0

----------------------------------------------------------------------------- *)


      destruct x as [ | x]; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 41)
  
  x : nat
  xs : seq nat_eqType
  ============================
  0 \in x.+1 :: xs ->
  nondecreasing_sequence (x.+1 :: xs) -> first0 (x.+1 :: xs) = 0

----------------------------------------------------------------------------- *)


      rewrite in_cons; move ⇒ /orP [/eqP EQ | IN] ND; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 125)
  
  x : nat
  xs : seq nat_eqType
  IN : 0 \in xs
  ND : nondecreasing_sequence (x.+1 :: xs)
  ============================
  first0 (x.+1 :: xs) = 0

----------------------------------------------------------------------------- *)


      exfalso.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 144)
  
  x : nat
  xs : seq nat_eqType
  IN : 0 \in xs
  ND : nondecreasing_sequence (x.+1 :: xs)
  ============================
  False

----------------------------------------------------------------------------- *)


      have NTH := nth_index 0 IN.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 152)
  
  x : nat
  xs : seq nat_eqType
  IN : 0 \in xs
  ND : nondecreasing_sequence (x.+1 :: xs)
  NTH : xs [|index 0 xs|] = 0
  ============================
  False

----------------------------------------------------------------------------- *)


      specialize (ND 0 (index 0 xs).+1).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 155)
  
  x : nat
  xs : seq nat_eqType
  IN : 0 \in xs
  ND : 0 <= (index 0 xs).+1 < size (x.+1 :: xs) ->
       (x.+1 :: xs) [|0|] <= (x.+1 :: xs) [|(index 0 xs).+1|]
  NTH : xs [|index 0 xs|] = 0
  ============================
  False

----------------------------------------------------------------------------- *)


      feed ND.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 156)
  
  x : nat
  xs : seq nat_eqType
  IN : 0 \in xs
  ND : 0 <= (index 0 xs).+1 < size (x.+1 :: xs) ->
       (x.+1 :: xs) [|0|] <= (x.+1 :: xs) [|(index 0 xs).+1|]
  NTH : xs [|index 0 xs|] = 0
  ============================
  0 <= (index 0 xs).+1 < size (x.+1 :: xs)

subgoal 2 (ID 161) is:
 False

----------------------------------------------------------------------------- *)



      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 156)
  
  x : nat
  xs : seq nat_eqType
  IN : 0 \in xs
  ND : 0 <= (index 0 xs).+1 < size (x.+1 :: xs) ->
       (x.+1 :: xs) [|0|] <= (x.+1 :: xs) [|(index 0 xs).+1|]
  NTH : xs [|index 0 xs|] = 0
  ============================
  0 <= (index 0 xs).+1 < size (x.+1 :: xs)

----------------------------------------------------------------------------- *)


apply/andP; split; first by done.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 188)
  
  x : nat
  xs : seq nat_eqType
  IN : 0 \in xs
  ND : 0 <= (index 0 xs).+1 < size (x.+1 :: xs) ->
       (x.+1 :: xs) [|0|] <= (x.+1 :: xs) [|(index 0 xs).+1|]
  NTH : xs [|index 0 xs|] = 0
  ============================
  (index 0 xs).+1 < size (x.+1 :: xs)

----------------------------------------------------------------------------- *)



          by simpl; rewrite ltnS index_mem.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 161) is:
 False

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 161)
  
  x : nat
  xs : seq nat_eqType
  IN : 0 \in xs
  ND : (x.+1 :: xs) [|0|] <= (x.+1 :: xs) [|(index 0 xs).+1|]
  NTH : xs [|index 0 xs|] = 0
  ============================
  False

----------------------------------------------------------------------------- *)


        by simpl in ND; rewrite NTH in ND.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

If [x1::x2::xs] is a non-decreasing sequence, then either [x1 = x2] or [x1 < x2].
    Lemma nondecreasing_sequence_2cons_leVeq:
       x1 x2 xs,
        nondecreasing_sequence (x1 :: x2 :: xs)
        x1 = x2 x1 < x2.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 34)
  
  ============================
  forall (x1 x2 : nat) (xs : seq nat),
  nondecreasing_sequence [:: x1, x2 & xs] -> x1 = x2 \/ x1 < x2

----------------------------------------------------------------------------- *)


    Proof.
      intros ? ? ? ND.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 38)
  
  x1, x2 : nat
  xs : seq nat
  ND : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  x1 = x2 \/ x1 < x2

----------------------------------------------------------------------------- *)


      destruct (ltngtP x1 x2) as [LT | GT | EQ]; auto.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 148)
  
  x1, x2 : nat
  xs : seq nat
  ND : nondecreasing_sequence [:: x1, x2 & xs]
  GT : x2 < x1
  ============================
  x1 = x2 \/ false

----------------------------------------------------------------------------- *)


      move_neq_down GT.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 205)
  
  x1, x2 : nat
  xs : seq nat
  ND : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  x1 <= x2

----------------------------------------------------------------------------- *)


        by specialize (ND 0 1); apply ND.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

We prove that if [x::xs] is a non-decreasing sequence, then [xs] also is a non-decreasing sequence.
    Lemma nondecreasing_sequence_cons:
       x xs,
        nondecreasing_sequence (x :: xs)
        nondecreasing_sequence xs.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 39)
  
  ============================
  forall (x : nat) (xs : seq nat),
  nondecreasing_sequence (x :: xs) -> nondecreasing_sequence xs

----------------------------------------------------------------------------- *)


    Proof.
      intros ? ? ND.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 42)
  
  x : nat
  xs : seq nat
  ND : nondecreasing_sequence (x :: xs)
  ============================
  nondecreasing_sequence xs

----------------------------------------------------------------------------- *)


      moven1 n2 /andP [LT1 LT2].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 84)
  
  x : nat
  xs : seq nat
  ND : nondecreasing_sequence (x :: xs)
  n1, n2 : nat
  LT1 : n1 <= n2
  LT2 : n2 < size xs
  ============================
  xs [|n1|] <= xs [|n2|]

----------------------------------------------------------------------------- *)


      specialize (ND n1.+1 n2.+1).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 86)
  
  x : nat
  xs : seq nat
  n1, n2 : nat
  ND : n1 < n2.+1 < size (x :: xs) ->
       (x :: xs) [|n1.+1|] <= (x :: xs) [|n2.+1|]
  LT1 : n1 <= n2
  LT2 : n2 < size xs
  ============================
  xs [|n1|] <= xs [|n2|]

----------------------------------------------------------------------------- *)


      apply ND.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 87)
  
  x : nat
  xs : seq nat
  n1, n2 : nat
  ND : n1 < n2.+1 < size (x :: xs) ->
       (x :: xs) [|n1.+1|] <= (x :: xs) [|n2.+1|]
  LT1 : n1 <= n2
  LT2 : n2 < size xs
  ============================
  n1 < n2.+1 < size (x :: xs)

----------------------------------------------------------------------------- *)


      apply/andP; split.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 113)
  
  x : nat
  xs : seq nat
  n1, n2 : nat
  ND : n1 < n2.+1 < size (x :: xs) ->
       (x :: xs) [|n1.+1|] <= (x :: xs) [|n2.+1|]
  LT1 : n1 <= n2
  LT2 : n2 < size xs
  ============================
  n1 < n2.+1

subgoal 2 (ID 114) is:
 n2.+1 < size (x :: xs)

----------------------------------------------------------------------------- *)


      - by rewrite ltnS.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 114)
  
  x : nat
  xs : seq nat
  n1, n2 : nat
  ND : n1 < n2.+1 < size (x :: xs) ->
       (x :: xs) [|n1.+1|] <= (x :: xs) [|n2.+1|]
  LT1 : n1 <= n2
  LT2 : n2 < size xs
  ============================
  n2.+1 < size (x :: xs)

----------------------------------------------------------------------------- *)


      - by simpl; rewrite ltnS.
(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

Let [xs] be a non-decreasing sequence, then for [x] s.t. [∀ y ∈ xs, x ≤ y] [x::xs] is a non-decreasing sequence.
    Lemma nondecreasing_sequence_add_min:
       x xs,
        ( y, y \in xs x y)
        nondecreasing_sequence xs
        nondecreasing_sequence (x :: xs).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 53)
  
  ============================
  forall (x : nat) (xs : seq_predType nat_eqType),
  (forall y : nat, y \in xs -> x <= y) ->
  nondecreasing_sequence xs -> nondecreasing_sequence (x :: xs)

----------------------------------------------------------------------------- *)


    Proof.
      intros x xs MIN ND [ |n1] [ | n2]; try done.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 69)
  
  x : nat
  xs : seq_predType nat_eqType
  MIN : forall y : nat, y \in xs -> x <= y
  ND : nondecreasing_sequence xs
  n2 : nat
  ============================
  0 <= n2.+1 < size (x :: xs) -> (x :: xs) [|0|] <= (x :: xs) [|n2.+1|]

subgoal 2 (ID 76) is:
 n1 < n2.+1 < size (x :: xs) -> (x :: xs) [|n1.+1|] <= (x :: xs) [|n2.+1|]

----------------------------------------------------------------------------- *)


      - move ⇒ /andP [_ S]; simpl.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 188)
  
  x : nat
  xs : seq_predType nat_eqType
  MIN : forall y : nat, y \in xs -> x <= y
  ND : nondecreasing_sequence xs
  n2 : nat
  S : n2.+1 < size (x :: xs)
  ============================
  x <= xs [|n2|]

subgoal 2 (ID 76) is:
 n1 < n2.+1 < size (x :: xs) -> (x :: xs) [|n1.+1|] <= (x :: xs) [|n2.+1|]

----------------------------------------------------------------------------- *)


        apply leq_trans with (xs [| 0 |]).

(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 190)
  
  x : nat
  xs : seq_predType nat_eqType
  MIN : forall y : nat, y \in xs -> x <= y
  ND : nondecreasing_sequence xs
  n2 : nat
  S : n2.+1 < size (x :: xs)
  ============================
  x <= xs [|0|]

subgoal 2 (ID 191) is:
 xs [|0|] <= xs [|n2|]
subgoal 3 (ID 76) is:
 n1 < n2.+1 < size (x :: xs) -> (x :: xs) [|n1.+1|] <= (x :: xs) [|n2.+1|]

----------------------------------------------------------------------------- *)


        + apply MIN; apply mem_nth.

(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 193)
  
  x : nat
  xs : seq_predType nat_eqType
  MIN : forall y : nat, y \in xs -> x <= y
  ND : nondecreasing_sequence xs
  n2 : nat
  S : n2.+1 < size (x :: xs)
  ============================
  0 < size xs

subgoal 2 (ID 191) is:
 xs [|0|] <= xs [|n2|]
subgoal 3 (ID 76) is:
 n1 < n2.+1 < size (x :: xs) -> (x :: xs) [|n1.+1|] <= (x :: xs) [|n2.+1|]

----------------------------------------------------------------------------- *)


          simpl in ×.
(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 196)
  
  x : nat
  xs : seq nat
  MIN : forall y : nat, y \in xs -> x <= y
  ND : nondecreasing_sequence xs
  n2 : nat
  S : n2.+1 < (size xs).+1
  ============================
  0 < size xs

subgoal 2 (ID 191) is:
 xs [|0|] <= xs [|n2|]
subgoal 3 (ID 76) is:
 n1 < n2.+1 < size (x :: xs) -> (x :: xs) [|n1.+1|] <= (x :: xs) [|n2.+1|]

----------------------------------------------------------------------------- *)


rewrite ltnS in S.

(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 213)
  
  x : nat
  xs : seq nat
  MIN : forall y : nat, y \in xs -> x <= y
  ND : nondecreasing_sequence xs
  n2 : nat
  S : n2 < size xs
  ============================
  0 < size xs

subgoal 2 (ID 191) is:
 xs [|0|] <= xs [|n2|]
subgoal 3 (ID 76) is:
 n1 < n2.+1 < size (x :: xs) -> (x :: xs) [|n1.+1|] <= (x :: xs) [|n2.+1|]

----------------------------------------------------------------------------- *)


            by apply leq_ltn_trans with n2.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 191)
  
  x : nat
  xs : seq_predType nat_eqType
  MIN : forall y : nat, y \in xs -> x <= y
  ND : nondecreasing_sequence xs
  n2 : nat
  S : n2.+1 < size (x :: xs)
  ============================
  xs [|0|] <= xs [|n2|]

subgoal 2 (ID 76) is:
 n1 < n2.+1 < size (x :: xs) -> (x :: xs) [|n1.+1|] <= (x :: xs) [|n2.+1|]

----------------------------------------------------------------------------- *)


        + apply ND; apply/andP; split; auto.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 76)
  
  x : nat
  xs : seq_predType nat_eqType
  MIN : forall y : nat, y \in xs -> x <= y
  ND : nondecreasing_sequence xs
  n1, n2 : nat
  ============================
  n1 < n2.+1 < size (x :: xs) -> (x :: xs) [|n1.+1|] <= (x :: xs) [|n2.+1|]

----------------------------------------------------------------------------- *)


      - simpl; rewrite !ltnS.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 257)
  
  x : nat
  xs : seq_predType nat_eqType
  MIN : forall y : nat, y \in xs -> x <= y
  ND : nondecreasing_sequence xs
  n1, n2 : nat
  ============================
  n1 <= n2 < size xs -> xs [|n1|] <= xs [|n2|]

----------------------------------------------------------------------------- *)


          by apply ND.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

We prove that if [x::xs] is a non-decreasing sequence, then [x::x::xs] also is a non-decreasing sequence.
    Lemma nondecreasing_sequence_cons_double:
       x xs,
        nondecreasing_sequence (x :: xs)
        nondecreasing_sequence (x :: x :: xs).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 60)
  
  ============================
  forall (x : nat) (xs : seq nat),
  nondecreasing_sequence (x :: xs) -> nondecreasing_sequence [:: x, x & xs]

----------------------------------------------------------------------------- *)


    Proof.
      intros ? ? ND.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 63)
  
  x : nat
  xs : seq nat
  ND : nondecreasing_sequence (x :: xs)
  ============================
  nondecreasing_sequence [:: x, x & xs]

----------------------------------------------------------------------------- *)


      move ⇒ [ | n1] [ | n2] /andP [LT1 LT2]; try done.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 251)
  
  x : nat
  xs : seq nat
  ND : nondecreasing_sequence (x :: xs)
  n2 : nat
  LT1 : 0 <= n2.+1
  LT2 : n2.+1 < size [:: x, x & xs]
  ============================
  [:: x, x & xs] [|0|] <= [:: x, x & xs] [|n2.+1|]

subgoal 2 (ID 253) is:
 [:: x, x & xs] [|n1.+1|] <= [:: x, x & xs] [|n2.+1|]

----------------------------------------------------------------------------- *)


      - specialize (ND 0 n2); simpl in ND.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 323)
  
  x : nat
  xs : seq nat
  n2 : nat
  ND : n2 < (size xs).+1 -> x <= (x :: xs) [|n2|]
  LT1 : 0 <= n2.+1
  LT2 : n2.+1 < size [:: x, x & xs]
  ============================
  [:: x, x & xs] [|0|] <= [:: x, x & xs] [|n2.+1|]

subgoal 2 (ID 253) is:
 [:: x, x & xs] [|n1.+1|] <= [:: x, x & xs] [|n2.+1|]

----------------------------------------------------------------------------- *)


        apply ND.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 324)
  
  x : nat
  xs : seq nat
  n2 : nat
  ND : n2 < (size xs).+1 -> x <= (x :: xs) [|n2|]
  LT1 : 0 <= n2.+1
  LT2 : n2.+1 < size [:: x, x & xs]
  ============================
  n2 < (size xs).+1

subgoal 2 (ID 253) is:
 [:: x, x & xs] [|n1.+1|] <= [:: x, x & xs] [|n2.+1|]

----------------------------------------------------------------------------- *)


          by simpl in LT2; rewrite ltnS in LT2.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 253)
  
  x : nat
  xs : seq nat
  ND : nondecreasing_sequence (x :: xs)
  n1, n2 : nat
  LT1 : n1 < n2.+1
  LT2 : n2.+1 < size [:: x, x & xs]
  ============================
  [:: x, x & xs] [|n1.+1|] <= [:: x, x & xs] [|n2.+1|]

----------------------------------------------------------------------------- *)


      - apply ND.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 345)
  
  x : nat
  xs : seq nat
  ND : nondecreasing_sequence (x :: xs)
  n1, n2 : nat
  LT1 : n1 < n2.+1
  LT2 : n2.+1 < size [:: x, x & xs]
  ============================
  n1 <= n2 < size (x :: xs)

----------------------------------------------------------------------------- *)


        apply/andP; split.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 371)
  
  x : nat
  xs : seq nat
  ND : nondecreasing_sequence (x :: xs)
  n1, n2 : nat
  LT1 : n1 < n2.+1
  LT2 : n2.+1 < size [:: x, x & xs]
  ============================
  n1 <= n2

subgoal 2 (ID 372) is:
 n2 < size (x :: xs)

----------------------------------------------------------------------------- *)


        + by rewrite ltnS in LT1.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 372)
  
  x : nat
  xs : seq nat
  ND : nondecreasing_sequence (x :: xs)
  n1, n2 : nat
  LT1 : n1 < n2.+1
  LT2 : n2.+1 < size [:: x, x & xs]
  ============================
  n2 < size (x :: xs)

----------------------------------------------------------------------------- *)


        + by simpl in LT2; rewrite ltnS in LT2.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

We prove that if [x::xs] is a non-decreasing sequence, then [x] is a minimal element of [xs].
    Lemma nondecreasing_sequence_cons_min:
       x xs,
        nondecreasing_sequence (x :: xs)
        ( y, y \in xs x y).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 71)
  
  ============================
  forall (x : nat) (xs : seq nat),
  nondecreasing_sequence (x :: xs) ->
  forall y : nat_eqType, y \in xs -> x <= y

----------------------------------------------------------------------------- *)


    Proof.
      intros ? ? ND ? IN.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 76)
  
  x : nat
  xs : seq nat
  ND : nondecreasing_sequence (x :: xs)
  y : nat_eqType
  IN : y \in xs
  ============================
  x <= y

----------------------------------------------------------------------------- *)


      have IDX := nth_index 0 IN.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 84)
  
  x : nat
  xs : seq nat
  ND : nondecreasing_sequence (x :: xs)
  y : nat_eqType
  IN : y \in xs
  IDX : xs [|index y xs|] = y
  ============================
  x <= y

----------------------------------------------------------------------------- *)


      specialize (ND 0 (index y xs).+1).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 87)
  
  x : nat
  xs : seq nat
  y : nat_eqType
  ND : 0 <= (index y xs).+1 < size (x :: xs) ->
       (x :: xs) [|0|] <= (x :: xs) [|(index y xs).+1|]
  IN : y \in xs
  IDX : xs [|index y xs|] = y
  ============================
  x <= y

----------------------------------------------------------------------------- *)


      move: (IN) ⇒ IDL; rewrite -index_mem in IDL.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 108)
  
  x : nat
  xs : seq nat
  y : nat_eqType
  ND : 0 <= (index y xs).+1 < size (x :: xs) ->
       (x :: xs) [|0|] <= (x :: xs) [|(index y xs).+1|]
  IN : y \in xs
  IDX : xs [|index y xs|] = y
  IDL : index y xs < size xs
  ============================
  x <= y

----------------------------------------------------------------------------- *)


      feed ND.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 109)
  
  x : nat
  xs : seq nat
  y : nat_eqType
  ND : 0 <= (index y xs).+1 < size (x :: xs) ->
       (x :: xs) [|0|] <= (x :: xs) [|(index y xs).+1|]
  IN : y \in xs
  IDX : xs [|index y xs|] = y
  IDL : index y xs < size xs
  ============================
  0 <= (index y xs).+1 < size (x :: xs)

subgoal 2 (ID 114) is:
 x <= y

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 109)
  
  x : nat
  xs : seq nat
  y : nat_eqType
  ND : 0 <= (index y xs).+1 < size (x :: xs) ->
       (x :: xs) [|0|] <= (x :: xs) [|(index y xs).+1|]
  IN : y \in xs
  IDX : xs [|index y xs|] = y
  IDL : index y xs < size xs
  ============================
  0 <= (index y xs).+1 < size (x :: xs)

----------------------------------------------------------------------------- *)


apply/andP; split; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 141)
  
  x : nat
  xs : seq nat
  y : nat_eqType
  ND : 0 <= (index y xs).+1 < size (x :: xs) ->
       (x :: xs) [|0|] <= (x :: xs) [|(index y xs).+1|]
  IN : y \in xs
  IDX : xs [|index y xs|] = y
  IDL : index y xs < size xs
  ============================
  (index y xs).+1 < size (x :: xs)

----------------------------------------------------------------------------- *)


          by simpl; rewrite ltnS.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 114) is:
 x <= y

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 114)
  
  x : nat
  xs : seq nat
  y : nat_eqType
  ND : (x :: xs) [|0|] <= (x :: xs) [|(index y xs).+1|]
  IN : y \in xs
  IDX : xs [|index y xs|] = y
  IDL : index y xs < size xs
  ============================
  x <= y

----------------------------------------------------------------------------- *)


      eapply leq_trans; first by apply ND.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 150)
  
  x : nat
  xs : seq nat
  y : nat_eqType
  ND : (x :: xs) [|0|] <= (x :: xs) [|(index y xs).+1|]
  IN : y \in xs
  IDX : xs [|index y xs|] = y
  IDL : index y xs < size xs
  ============================
  (x :: xs) [|(index y xs).+1|] <= y

----------------------------------------------------------------------------- *)


        by simpl; rewrite IDX.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

We also prove a similar lemma for strict minimum.
    Corollary nondecreasing_sequence_cons_smin:
       x1 x2 xs,
        x1 < x2
        nondecreasing_sequence (x1 :: x2 :: xs)
        ( y, y \in x2 :: xs x1 < y).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 84)
  
  ============================
  forall (x1 x2 : nat) (xs : seq nat),
  x1 < x2 ->
  nondecreasing_sequence [:: x1, x2 & xs] ->
  forall y : nat_eqType, y \in x2 :: xs -> x1 < y

----------------------------------------------------------------------------- *)


    Proof.
      intros ? ? ? LT ND ? IN.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 91)
  
  x1, x2 : nat
  xs : seq nat
  LT : x1 < x2
  ND : nondecreasing_sequence [:: x1, x2 & xs]
  y : nat_eqType
  IN : y \in x2 :: xs
  ============================
  x1 < y

----------------------------------------------------------------------------- *)


      eapply leq_trans; first by apply LT.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 94)
  
  x1, x2 : nat
  xs : seq nat
  LT : x1 < x2
  ND : nondecreasing_sequence [:: x1, x2 & xs]
  y : nat_eqType
  IN : y \in x2 :: xs
  ============================
  x2 <= y

----------------------------------------------------------------------------- *)


      apply nondecreasing_sequence_cons in ND.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 96)
  
  x1, x2 : nat
  xs : seq nat
  LT : x1 < x2
  ND : nondecreasing_sequence (x2 :: xs)
  y : nat_eqType
  IN : y \in x2 :: xs
  ============================
  x2 <= y

----------------------------------------------------------------------------- *)


      eapply nondecreasing_sequence_cons_min; last by apply IN.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 98)
  
  x1, x2 : nat
  xs : seq nat
  LT : x1 < x2
  ND : nondecreasing_sequence (x2 :: xs)
  y : nat_eqType
  IN : y \in x2 :: xs
  ============================
  nondecreasing_sequence [:: x2, x2 & xs]

----------------------------------------------------------------------------- *)


        by apply nondecreasing_sequence_cons_double.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

Next, we prove that no element can lie strictly between two neighboring elements and still belong to the list.
    Lemma antidensity_of_nondecreasing_seq:
       (xs : seq nat) (x : nat) (n : nat),
        nondecreasing_sequence xs
        xs[|n|] < x < xs[|n.+1|]
        ~~ (x \in xs).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 91)
  
  ============================
  forall (xs : seq nat) (x n : nat),
  nondecreasing_sequence xs -> xs [|n|] < x < xs [|n.+1|] -> x \notin xs

----------------------------------------------------------------------------- *)


    Proof.
      intros ? ? ? STR ?; apply/negP; intros ?.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 118)
  
  xs : seq nat
  x, n : nat
  STR : nondecreasing_sequence xs
  H : xs [|n|] < x < xs [|n.+1|]
  H0 : x \in xs
  ============================
  False

----------------------------------------------------------------------------- *)


      move: H0 ⇒ /nthP.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 155)
  
  xs : seq nat
  x, n : nat
  STR : nondecreasing_sequence xs
  H : xs [|n|] < x < xs [|n.+1|]
  ============================
  (forall s : nat_eqType, exists2 i : nat, i < size xs & nth s xs i = x) ->
  False

----------------------------------------------------------------------------- *)


 intros GG.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 156)
  
  xs : seq nat
  x, n : nat
  STR : nondecreasing_sequence xs
  H : xs [|n|] < x < xs [|n.+1|]
  GG : forall s : nat_eqType, exists2 i : nat, i < size xs & nth s xs i = x
  ============================
  False

----------------------------------------------------------------------------- *)


      specialize (GG 0).
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 158)
  
  xs : seq nat
  x, n : nat
  STR : nondecreasing_sequence xs
  H : xs [|n|] < x < xs [|n.+1|]
  GG : exists2 i : nat, i < size xs & xs [|i|] = x
  ============================
  False

----------------------------------------------------------------------------- *)


      move: GG ⇒ [ind LE HHH].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 173)
  
  xs : seq nat
  x, n : nat
  STR : nondecreasing_sequence xs
  H : xs [|n|] < x < xs [|n.+1|]
  ind : nat
  LE : ind < size xs
  HHH : xs [|ind|] = x
  ============================
  False

----------------------------------------------------------------------------- *)


      subst x; rename ind into x.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 180)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  H : xs [|n|] < xs [|x|] < xs [|n.+1|]
  LE : x < size xs
  ============================
  False

----------------------------------------------------------------------------- *)



      destruct (n.+1 < size xs) eqn:Bt; last first.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 192)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  H : xs [|n|] < xs [|x|] < xs [|n.+1|]
  LE : x < size xs
  Bt : (n.+1 < size xs) = false
  ============================
  False

subgoal 2 (ID 191) is:
 False

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 192)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  H : xs [|n|] < xs [|x|] < xs [|n.+1|]
  LE : x < size xs
  Bt : (n.+1 < size xs) = false
  ============================
  False

----------------------------------------------------------------------------- *)


move: Bt ⇒ /negP /negP; rewrite -leqNgt; moveBt.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 274)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  H : xs [|n|] < xs [|x|] < xs [|n.+1|]
  LE : x < size xs
  Bt : size xs <= n.+1
  ============================
  False

----------------------------------------------------------------------------- *)


        apply nth_default with (x0 := 0) in Bt.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 276)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  H : xs [|n|] < xs [|x|] < xs [|n.+1|]
  LE : x < size xs
  Bt : xs [|n.+1|] = 0
  ============================
  False

----------------------------------------------------------------------------- *)


        rewrite Bt in H; by move: H ⇒ /andP [_ T].
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 191) is:
 False

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 191)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  H : xs [|n|] < xs [|x|] < xs [|n.+1|]
  LE : x < size xs
  Bt : (n.+1 < size xs) = true
  ============================
  False

----------------------------------------------------------------------------- *)


      have B1: n.+1 < size xs; first by done.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 363)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  H : xs [|n|] < xs [|x|] < xs [|n.+1|]
  LE : x < size xs
  Bt : (n.+1 < size xs) = true
  B1 : n.+1 < size xs
  ============================
  False

----------------------------------------------------------------------------- *)


clear Bt.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 364)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  H : xs [|n|] < xs [|x|] < xs [|n.+1|]
  LE : x < size xs
  B1 : n.+1 < size xs
  ============================
  False

----------------------------------------------------------------------------- *)


      have B2: n < size xs; first by apply leq_ltn_trans with n.+1.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 368)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  H : xs [|n|] < xs [|x|] < xs [|n.+1|]
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  ============================
  False

----------------------------------------------------------------------------- *)



      have GT: n < x.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 371)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  H : xs [|n|] < xs [|x|] < xs [|n.+1|]
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  ============================
  n < x

subgoal 2 (ID 373) is:
 False

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 371)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  H : xs [|n|] < xs [|x|] < xs [|n.+1|]
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  ============================
  n < x

----------------------------------------------------------------------------- *)


move: H ⇒ /andP [T _].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 414)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  T : xs [|n|] < xs [|x|]
  ============================
  n < x

----------------------------------------------------------------------------- *)


        rewrite ltnNge; apply/negP; intros CONTR.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 440)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  T : xs [|n|] < xs [|x|]
  CONTR : x <= n
  ============================
  False

----------------------------------------------------------------------------- *)


        specialize (STR x n).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 442)
  
  xs : seq nat
  n, x : nat
  STR : x <= n < size xs -> xs [|x|] <= xs [|n|]
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  T : xs [|n|] < xs [|x|]
  CONTR : x <= n
  ============================
  False

----------------------------------------------------------------------------- *)


        feed STR.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 443)
  
  xs : seq nat
  n, x : nat
  STR : x <= n < size xs -> xs [|x|] <= xs [|n|]
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  T : xs [|n|] < xs [|x|]
  CONTR : x <= n
  ============================
  x <= n < size xs

subgoal 2 (ID 448) is:
 False

----------------------------------------------------------------------------- *)


by apply/andP; split.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 448)
  
  xs : seq nat
  n, x : nat
  STR : xs [|x|] <= xs [|n|]
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  T : xs [|n|] < xs [|x|]
  CONTR : x <= n
  ============================
  False

----------------------------------------------------------------------------- *)


          by move: STR; rewrite leqNgt; move ⇒ /negP STR; apply: STR.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 373) is:
 False

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 373)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  H : xs [|n|] < xs [|x|] < xs [|n.+1|]
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  GT : n < x
  ============================
  False

----------------------------------------------------------------------------- *)


      have LT: x < n.+1.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 513)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  H : xs [|n|] < xs [|x|] < xs [|n.+1|]
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  GT : n < x
  ============================
  x < n.+1

subgoal 2 (ID 515) is:
 False

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 513)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  H : xs [|n|] < xs [|x|] < xs [|n.+1|]
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  GT : n < x
  ============================
  x < n.+1

----------------------------------------------------------------------------- *)


clear GT.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 516)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  H : xs [|n|] < xs [|x|] < xs [|n.+1|]
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  ============================
  x < n.+1

----------------------------------------------------------------------------- *)


        move: H ⇒ /andP [_ T].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 557)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  T : xs [|x|] < xs [|n.+1|]
  ============================
  x < n.+1

----------------------------------------------------------------------------- *)


        rewrite ltnNge; apply/negP; intros CONTR.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 583)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  T : xs [|x|] < xs [|n.+1|]
  CONTR : n < x
  ============================
  False

----------------------------------------------------------------------------- *)


        move: CONTR; rewrite leq_eqVlt; move ⇒ /orP [/eqP EQ | CONTR].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 662)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  T : xs [|x|] < xs [|n.+1|]
  EQ : n.+1 = x
  ============================
  False

subgoal 2 (ID 663) is:
 False

----------------------------------------------------------------------------- *)


        {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 662)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  T : xs [|x|] < xs [|n.+1|]
  EQ : n.+1 = x
  ============================
  False

----------------------------------------------------------------------------- *)


by subst; rewrite ltnn in T.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals

subgoal 1 (ID 663) is:
 False
subgoal 2 (ID 515) is:
 False

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 663)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  T : xs [|x|] < xs [|n.+1|]
  CONTR : n.+1 < x
  ============================
  False

----------------------------------------------------------------------------- *)


        specialize (STR n.+1 x).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 716)
  
  xs : seq nat
  n, x : nat
  STR : n < x < size xs -> xs [|n.+1|] <= xs [|x|]
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  T : xs [|x|] < xs [|n.+1|]
  CONTR : n.+1 < x
  ============================
  False

----------------------------------------------------------------------------- *)


        feed STR.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 717)
  
  xs : seq nat
  n, x : nat
  STR : n < x < size xs -> xs [|n.+1|] <= xs [|x|]
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  T : xs [|x|] < xs [|n.+1|]
  CONTR : n.+1 < x
  ============================
  n < x < size xs

subgoal 2 (ID 722) is:
 False

----------------------------------------------------------------------------- *)


by apply/andP; split; [ apply ltnW | done].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 722)
  
  xs : seq nat
  n, x : nat
  STR : xs [|n.+1|] <= xs [|x|]
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  T : xs [|x|] < xs [|n.+1|]
  CONTR : n.+1 < x
  ============================
  False

----------------------------------------------------------------------------- *)


          by move: STR; rewrite leqNgt; move ⇒ /negP STR; apply: STR.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 515) is:
 False

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 515)
  
  xs : seq nat
  n : nat
  STR : nondecreasing_sequence xs
  x : nat
  H : xs [|n|] < xs [|x|] < xs [|n.+1|]
  LE : x < size xs
  B1 : n.+1 < size xs
  B2 : n < size xs
  GT : n < x
  LT : x < n.+1
  ============================
  False

----------------------------------------------------------------------------- *)


        by move: LT; rewrite ltnNge; move ⇒ /negP LT; apply: LT.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    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]].
    Lemma belonging_to_segment_of_seq_is_total:
       (xs : seq nat) (x : nat),
        2 size xs
        first0 xs x < last0 xs
         n,
          n.+1 < size xs
          xs[|n|] x < xs[|n.+1|].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 98)
  
  ============================
  forall (xs : seq nat) (x : nat),
  1 < size xs ->
  first0 xs <= x < last0 xs ->
  exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]

----------------------------------------------------------------------------- *)


    Proof.
      intros ? ? SIZE LAST.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 102)
  
  xs : seq nat
  x : nat
  SIZE : 1 < size xs
  LAST : first0 xs <= x < last0 xs
  ============================
  exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]

----------------------------------------------------------------------------- *)


      have EX: n, size xs n by (size xs).
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 111)
  
  xs : seq nat
  x : nat
  SIZE : 1 < size xs
  LAST : first0 xs <= x < last0 xs
  EX : exists n : nat, size xs <= n
  ============================
  exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]

----------------------------------------------------------------------------- *)


move: EX ⇒ [n LE].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 124)
  
  xs : seq nat
  x : nat
  SIZE : 1 < size xs
  LAST : first0 xs <= x < last0 xs
  n : nat
  LE : size xs <= n
  ============================
  exists n0 : nat, n0.+1 < size xs /\ xs [|n0|] <= x < xs [|n0.+1|]

----------------------------------------------------------------------------- *)


      destruct n; first by destruct xs.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 135)
  
  xs : seq nat
  x : nat
  SIZE : 1 < size xs
  LAST : first0 xs <= x < last0 xs
  n : nat
  LE : size xs <= n.+1
  ============================
  exists n0 : nat, n0.+1 < size xs /\ xs [|n0|] <= x < xs [|n0.+1|]

----------------------------------------------------------------------------- *)


      destruct n; first by destruct xs; last destruct xs.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 220)
  
  xs : seq nat
  x : nat
  SIZE : 1 < size xs
  LAST : first0 xs <= x < last0 xs
  n : nat
  LE : size xs <= n.+2
  ============================
  exists n0 : nat, n0.+1 < size xs /\ xs [|n0|] <= x < xs [|n0.+1|]

----------------------------------------------------------------------------- *)


      generalize dependent xs.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 344)
  
  x, n : nat
  ============================
  forall xs : seq nat,
  1 < size xs ->
  first0 xs <= x < last0 xs ->
  size xs <= n.+2 ->
  exists n0 : nat, n0.+1 < size xs /\ xs [|n0|] <= x < xs [|n0.+1|]

----------------------------------------------------------------------------- *)


      induction n; intros.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 355)
  
  x : nat
  xs : seq nat
  SIZE : 1 < size xs
  LAST : first0 xs <= x < last0 xs
  LE : size xs <= 2
  ============================
  exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]

subgoal 2 (ID 359) is:
 exists n0 : nat, n0.+1 < size xs /\ xs [|n0|] <= x < xs [|n0.+1|]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 355)
  
  x : nat
  xs : seq nat
  SIZE : 1 < size xs
  LAST : first0 xs <= x < last0 xs
  LE : size xs <= 2
  ============================
  exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]

----------------------------------------------------------------------------- *)


by destruct xs; [ | destruct xs; [ | destruct xs; [ 0 | ] ] ].
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 359) is:
 exists n0 : nat, n0.+1 < size xs /\ xs [|n0|] <= x < xs [|n0.+1|]

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 359)
  
  x, n : nat
  IHn : forall xs : seq nat,
        1 < size xs ->
        first0 xs <= x < last0 xs ->
        size xs <= n.+2 ->
        exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]
  xs : seq nat
  SIZE : 1 < size xs
  LAST : first0 xs <= x < last0 xs
  LE : size xs <= n.+3
  ============================
  exists n0 : nat, n0.+1 < size xs /\ xs [|n0|] <= x < xs [|n0.+1|]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 359)
  
  x, n : nat
  IHn : forall xs : seq nat,
        1 < size xs ->
        first0 xs <= x < last0 xs ->
        size xs <= n.+2 ->
        exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]
  xs : seq nat
  SIZE : 1 < size xs
  LAST : first0 xs <= x < last0 xs
  LE : size xs <= n.+3
  ============================
  exists n0 : nat, n0.+1 < size xs /\ xs [|n0|] <= x < xs [|n0.+1|]

----------------------------------------------------------------------------- *)


destruct xs; [ | destruct xs; [ | ]]; try by done.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 566)
  
  x, n : nat
  IHn : forall xs : seq nat,
        1 < size xs ->
        first0 xs <= x < last0 xs ->
        size xs <= n.+2 ->
        exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]
  n0, n1 : nat
  xs : seq nat
  SIZE : 1 < size [:: n0, n1 & xs]
  LAST : first0 [:: n0, n1 & xs] <= x < last0 [:: n0, n1 & xs]
  LE : size [:: n0, n1 & xs] <= n.+3
  ============================
  exists n2 : nat,
    n2.+1 < size [:: n0, n1 & xs] /\
    [:: n0, n1 & xs] [|n2|] <= x < [:: n0, n1 & xs] [|n2.+1|]

----------------------------------------------------------------------------- *)


        destruct xs.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 659)
  
  x, n : nat
  IHn : forall xs : seq nat,
        1 < size xs ->
        first0 xs <= x < last0 xs ->
        size xs <= n.+2 ->
        exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]
  n0, n1 : nat
  SIZE : 1 < size [:: n0; n1]
  LAST : first0 [:: n0; n1] <= x < last0 [:: n0; n1]
  LE : size [:: n0; n1] <= n.+3
  ============================
  exists n2 : nat,
    n2.+1 < size [:: n0; n1] /\
    [:: n0; n1] [|n2|] <= x < [:: n0; n1] [|n2.+1|]

subgoal 2 (ID 664) is:
 exists n3 : nat,
   n3.+1 < size [:: n0, n1, n2 & xs] /\
   [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)


        {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 659)
  
  x, n : nat
  IHn : forall xs : seq nat,
        1 < size xs ->
        first0 xs <= x < last0 xs ->
        size xs <= n.+2 ->
        exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]
  n0, n1 : nat
  SIZE : 1 < size [:: n0; n1]
  LAST : first0 [:: n0; n1] <= x < last0 [:: n0; n1]
  LE : size [:: n0; n1] <= n.+3
  ============================
  exists n2 : nat,
    n2.+1 < size [:: n0; n1] /\
    [:: n0; n1] [|n2|] <= x < [:: n0; n1] [|n2.+1|]

----------------------------------------------------------------------------- *)


by 0; simpl in ×.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 664) is:
 exists n3 : nat,
   n3.+1 < size [:: n0, n1, n2 & xs] /\
   [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 664)
  
  x, n : nat
  IHn : forall xs : seq nat,
        1 < size xs ->
        first0 xs <= x < last0 xs ->
        size xs <= n.+2 ->
        exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]
  n0, n1, n2 : nat
  xs : seq nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  ============================
  exists n3 : nat,
    n3.+1 < size [:: n0, n1, n2 & xs] /\
    [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)


        destruct (leqP n1 x) as [NEQ|NEQ]; last first.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 770)
  
  x, n : nat
  IHn : forall xs : seq nat,
        1 < size xs ->
        first0 xs <= x < last0 xs ->
        size xs <= n.+2 ->
        exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]
  n0, n1, n2 : nat
  xs : seq nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : x < n1
  ============================
  exists n3 : nat,
    n3.+1 < size [:: n0, n1, n2 & xs] /\
    [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

subgoal 2 (ID 769) is:
 exists n3 : nat,
   n3.+1 < size [:: n0, n1, n2 & xs] /\
   [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)


        {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 770)
  
  x, n : nat
  IHn : forall xs : seq nat,
        1 < size xs ->
        first0 xs <= x < last0 xs ->
        size xs <= n.+2 ->
        exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]
  n0, n1, n2 : nat
  xs : seq nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : x < n1
  ============================
  exists n3 : nat,
    n3.+1 < size [:: n0, n1, n2 & xs] /\
    [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)


0; split; auto.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 775)
  
  x, n : nat
  IHn : forall xs : seq nat,
        1 < size xs ->
        first0 xs <= x < last0 xs ->
        size xs <= n.+2 ->
        exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]
  n0, n1, n2 : nat
  xs : seq nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : x < n1
  ============================
  [:: n0, n1, n2 & xs] [|0|] <= x < [:: n0, n1, n2 & xs] [|1|]

----------------------------------------------------------------------------- *)


move: LAST ⇒ /andP [LAST _].
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 823)
  
  x, n : nat
  IHn : forall xs : seq nat,
        1 < size xs ->
        first0 xs <= x < last0 xs ->
        size xs <= n.+2 ->
        exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]
  n0, n1, n2 : nat
  xs : seq nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : x < n1
  LAST : first0 [:: n0, n1, n2 & xs] <= x
  ============================
  [:: n0, n1, n2 & xs] [|0|] <= x < [:: n0, n1, n2 & xs] [|1|]

----------------------------------------------------------------------------- *)


by apply/andP; split.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 769) is:
 exists n3 : nat,
   n3.+1 < size [:: n0, n1, n2 & xs] /\
   [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 769)
  
  x, n : nat
  IHn : forall xs : seq nat,
        1 < size xs ->
        first0 xs <= x < last0 xs ->
        size xs <= n.+2 ->
        exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]
  n0, n1, n2 : nat
  xs : seq nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : n1 <= x
  ============================
  exists n3 : nat,
    n3.+1 < size [:: n0, n1, n2 & xs] /\
    [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)



        {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 769)
  
  x, n : nat
  IHn : forall xs : seq nat,
        1 < size xs ->
        first0 xs <= x < last0 xs ->
        size xs <= n.+2 ->
        exists n : nat, n.+1 < size xs /\ xs [|n|] <= x < xs [|n.+1|]
  n0, n1, n2 : nat
  xs : seq nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : n1 <= x
  ============================
  exists n3 : nat,
    n3.+1 < size [:: n0, n1, n2 & xs] /\
    [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)


specialize (IHn [:: n1, n2 & xs]).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 854)
  
  x, n, n1, n2 : nat
  xs : seq nat
  IHn : 1 < size [:: n1, n2 & xs] ->
        first0 [:: n1, n2 & xs] <= x < last0 [:: n1, n2 & xs] ->
        size [:: n1, n2 & xs] <= n.+2 ->
        exists n : nat,
          n.+1 < size [:: n1, n2 & xs] /\
          [:: n1, n2 & xs] [|n|] <= x < [:: n1, n2 & xs] [|n.+1|]
  n0 : nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : n1 <= x
  ============================
  exists n3 : nat,
    n3.+1 < size [:: n0, n1, n2 & xs] /\
    [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)


          feed_n 3 IHn.

(* ----------------------------------[ coqtop ]---------------------------------

4 subgoals (ID 855)
  
  x, n, n1, n2 : nat
  xs : seq nat
  IHn : 1 < size [:: n1, n2 & xs] ->
        first0 [:: n1, n2 & xs] <= x < last0 [:: n1, n2 & xs] ->
        size [:: n1, n2 & xs] <= n.+2 ->
        exists n : nat,
          n.+1 < size [:: n1, n2 & xs] /\
          [:: n1, n2 & xs] [|n|] <= x < [:: n1, n2 & xs] [|n.+1|]
  n0 : nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : n1 <= x
  ============================
  1 < size [:: n1, n2 & xs]

subgoal 2 (ID 861) is:
 first0 [:: n1, n2 & xs] <= x < last0 [:: n1, n2 & xs]
subgoal 3 (ID 867) is:
 size [:: n1, n2 & xs] <= n.+2
subgoal 4 (ID 872) is:
 exists n3 : nat,
   n3.+1 < size [:: n0, n1, n2 & xs] /\
   [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)


          {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 855)
  
  x, n, n1, n2 : nat
  xs : seq nat
  IHn : 1 < size [:: n1, n2 & xs] ->
        first0 [:: n1, n2 & xs] <= x < last0 [:: n1, n2 & xs] ->
        size [:: n1, n2 & xs] <= n.+2 ->
        exists n : nat,
          n.+1 < size [:: n1, n2 & xs] /\
          [:: n1, n2 & xs] [|n|] <= x < [:: n1, n2 & xs] [|n.+1|]
  n0 : nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : n1 <= x
  ============================
  1 < size [:: n1, n2 & xs]

----------------------------------------------------------------------------- *)


by done.
(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals

subgoal 1 (ID 861) is:
 first0 [:: n1, n2 & xs] <= x < last0 [:: n1, n2 & xs]
subgoal 2 (ID 867) is:
 size [:: n1, n2 & xs] <= n.+2
subgoal 3 (ID 872) is:
 exists n3 : nat,
   n3.+1 < size [:: n0, n1, n2 & xs] /\
   [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 861)
  
  x, n, n1, n2 : nat
  xs : seq nat
  IHn : first0 [:: n1, n2 & xs] <= x < last0 [:: n1, n2 & xs] ->
        size [:: n1, n2 & xs] <= n.+2 ->
        exists n : nat,
          n.+1 < size [:: n1, n2 & xs] /\
          [:: n1, n2 & xs] [|n|] <= x < [:: n1, n2 & xs] [|n.+1|]
  n0 : nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : n1 <= x
  ============================
  first0 [:: n1, n2 & xs] <= x < last0 [:: n1, n2 & xs]

subgoal 2 (ID 867) is:
 size [:: n1, n2 & xs] <= n.+2
subgoal 3 (ID 872) is:
 exists n3 : nat,
   n3.+1 < size [:: n0, n1, n2 & xs] /\
   [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)



          {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 861)
  
  x, n, n1, n2 : nat
  xs : seq nat
  IHn : first0 [:: n1, n2 & xs] <= x < last0 [:: n1, n2 & xs] ->
        size [:: n1, n2 & xs] <= n.+2 ->
        exists n : nat,
          n.+1 < size [:: n1, n2 & xs] /\
          [:: n1, n2 & xs] [|n|] <= x < [:: n1, n2 & xs] [|n.+1|]
  n0 : nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : n1 <= x
  ============================
  first0 [:: n1, n2 & xs] <= x < last0 [:: n1, n2 & xs]

----------------------------------------------------------------------------- *)


move: LAST ⇒ /andP [LAST1 LAST2].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 913)
  
  x, n, n1, n2 : nat
  xs : seq nat
  IHn : first0 [:: n1, n2 & xs] <= x < last0 [:: n1, n2 & xs] ->
        size [:: n1, n2 & xs] <= n.+2 ->
        exists n : nat,
          n.+1 < size [:: n1, n2 & xs] /\
          [:: n1, n2 & xs] [|n|] <= x < [:: n1, n2 & xs] [|n.+1|]
  n0 : nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : n1 <= x
  LAST1 : first0 [:: n0, n1, n2 & xs] <= x
  LAST2 : x < last0 [:: n0, n1, n2 & xs]
  ============================
  first0 [:: n1, n2 & xs] <= x < last0 [:: n1, n2 & xs]

----------------------------------------------------------------------------- *)


            apply/andP; split; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 940)
  
  x, n, n1, n2 : nat
  xs : seq nat
  IHn : first0 [:: n1, n2 & xs] <= x < last0 [:: n1, n2 & xs] ->
        size [:: n1, n2 & xs] <= n.+2 ->
        exists n : nat,
          n.+1 < size [:: n1, n2 & xs] /\
          [:: n1, n2 & xs] [|n|] <= x < [:: n1, n2 & xs] [|n.+1|]
  n0 : nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : n1 <= x
  LAST1 : first0 [:: n0, n1, n2 & xs] <= x
  LAST2 : x < last0 [:: n0, n1, n2 & xs]
  ============================
  x < last0 [:: n1, n2 & xs]

----------------------------------------------------------------------------- *)


            apply leq_trans with (last0 [:: n0, n1, n2 & xs]); first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 945)
  
  x, n, n1, n2 : nat
  xs : seq nat
  IHn : first0 [:: n1, n2 & xs] <= x < last0 [:: n1, n2 & xs] ->
        size [:: n1, n2 & xs] <= n.+2 ->
        exists n : nat,
          n.+1 < size [:: n1, n2 & xs] /\
          [:: n1, n2 & xs] [|n|] <= x < [:: n1, n2 & xs] [|n.+1|]
  n0 : nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : n1 <= x
  LAST1 : first0 [:: n0, n1, n2 & xs] <= x
  LAST2 : x < last0 [:: n0, n1, n2 & xs]
  ============================
  last0 [:: n0, n1, n2 & xs] <= last0 [:: n1, n2 & xs]

----------------------------------------------------------------------------- *)


              by rewrite /last0 !last_cons.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals

subgoal 1 (ID 867) is:
 size [:: n1, n2 & xs] <= n.+2
subgoal 2 (ID 872) is:
 exists n3 : nat,
   n3.+1 < size [:: n0, n1, n2 & xs] /\
   [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)


          }

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 867)
  
  x, n, n1, n2 : nat
  xs : seq nat
  IHn : size [:: n1, n2 & xs] <= n.+2 ->
        exists n : nat,
          n.+1 < size [:: n1, n2 & xs] /\
          [:: n1, n2 & xs] [|n|] <= x < [:: n1, n2 & xs] [|n.+1|]
  n0 : nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : n1 <= x
  ============================
  size [:: n1, n2 & xs] <= n.+2

subgoal 2 (ID 872) is:
 exists n3 : nat,
   n3.+1 < size [:: n0, n1, n2 & xs] /\
   [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)


          {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 867)
  
  x, n, n1, n2 : nat
  xs : seq nat
  IHn : size [:: n1, n2 & xs] <= n.+2 ->
        exists n : nat,
          n.+1 < size [:: n1, n2 & xs] /\
          [:: n1, n2 & xs] [|n|] <= x < [:: n1, n2 & xs] [|n.+1|]
  n0 : nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : n1 <= x
  ============================
  size [:: n1, n2 & xs] <= n.+2

----------------------------------------------------------------------------- *)


by rewrite -(ltn_add2r 1) !addn1.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 872) is:
 exists n3 : nat,
   n3.+1 < size [:: n0, n1, n2 & xs] /\
   [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 872)
  
  x, n, n1, n2 : nat
  xs : seq nat
  IHn : exists n : nat,
          n.+1 < size [:: n1, n2 & xs] /\
          [:: n1, n2 & xs] [|n|] <= x < [:: n1, n2 & xs] [|n.+1|]
  n0 : nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : n1 <= x
  ============================
  exists n3 : nat,
    n3.+1 < size [:: n0, n1, n2 & xs] /\
    [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)


          move: IHn ⇒ [idx [SI /andP [G L]]].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 1052)
  
  x, n, n1, n2 : nat
  xs : seq nat
  n0 : nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : n1 <= x
  idx : nat
  SI : idx.+1 < size [:: n1, n2 & xs]
  G : [:: n1, n2 & xs] [|idx|] <= x
  L : x < [:: n1, n2 & xs] [|idx.+1|]
  ============================
  exists n3 : nat,
    n3.+1 < size [:: n0, n1, n2 & xs] /\
    [:: n0, n1, n2 & xs] [|n3|] <= x < [:: n0, n1, n2 & xs] [|n3.+1|]

----------------------------------------------------------------------------- *)


           idx.+1; split.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 1056)
  
  x, n, n1, n2 : nat
  xs : seq nat
  n0 : nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : n1 <= x
  idx : nat
  SI : idx.+1 < size [:: n1, n2 & xs]
  G : [:: n1, n2 & xs] [|idx|] <= x
  L : x < [:: n1, n2 & xs] [|idx.+1|]
  ============================
  idx.+2 < size [:: n0, n1, n2 & xs]

subgoal 2 (ID 1057) is:
 [:: n0, n1, n2 & xs] [|idx.+1|] <= x < [:: n0, n1, n2 & xs] [|idx.+2|]

----------------------------------------------------------------------------- *)


          - by simpl in *; rewrite -addn1 -[in X in _ X]addn1 leq_add2r.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 1057)
  
  x, n, n1, n2 : nat
  xs : seq nat
  n0 : nat
  SIZE : 1 < size [:: n0, n1, n2 & xs]
  LAST : first0 [:: n0, n1, n2 & xs] <= x < last0 [:: n0, n1, n2 & xs]
  LE : size [:: n0, n1, n2 & xs] <= n.+3
  NEQ : n1 <= x
  idx : nat
  SI : idx.+1 < size [:: n1, n2 & xs]
  G : [:: n1, n2 & xs] [|idx|] <= x
  L : x < [:: n1, n2 & xs] [|idx.+1|]
  ============================
  [:: n0, n1, n2 & xs] [|idx.+1|] <= x < [:: n0, n1, n2 & xs] [|idx.+2|]

----------------------------------------------------------------------------- *)


          - by apply/andP; split.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


        }

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

Note that the last element of a non-decreasing sequence is the max element.
    Lemma last_is_max_in_nondecreasing_seq:
       (xs : seq nat) (x : nat),
        nondecreasing_sequence xs
        (x \in xs)
        x last0 xs.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 103)
  
  ============================
  forall (xs : seq nat) (x : nat),
  nondecreasing_sequence xs -> x \in xs -> x <= last0 xs

----------------------------------------------------------------------------- *)


    Proof.
      clear; intros ? ? STR IN.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 107)
  
  xs : seq nat
  x : nat
  STR : nondecreasing_sequence xs
  IN : x \in xs
  ============================
  x <= last0 xs

----------------------------------------------------------------------------- *)


      have NEQ: x y, x = y x != y.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 115)
  
  xs : seq nat
  x : nat
  STR : nondecreasing_sequence xs
  IN : x \in xs
  ============================
  forall (t : eqType) (x0 y : t), x0 = y \/ x0 != y

subgoal 2 (ID 117) is:
 x <= last0 xs

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 115)
  
  xs : seq nat
  x : nat
  STR : nondecreasing_sequence xs
  IN : x \in xs
  ============================
  forall (t : eqType) (x0 y : t), x0 = y \/ x0 != y

----------------------------------------------------------------------------- *)


clear.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 118)
  
  ============================
  forall (t : eqType) (x y : t), x = y \/ x != y

----------------------------------------------------------------------------- *)


intros.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 121)
  
  t : eqType
  x, y : t
  ============================
  x = y \/ x != y

----------------------------------------------------------------------------- *)


        destruct (x == y) eqn:EQ.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 134)
  
  t : eqType
  x, y : t
  EQ : (x == y) = true
  ============================
  x = y \/ ~~ true

subgoal 2 (ID 135) is:
 x = y \/ ~~ false

----------------------------------------------------------------------------- *)


        - by left; apply/eqP.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 135)
  
  t : eqType
  x, y : t
  EQ : (x == y) = false
  ============================
  x = y \/ ~~ false

----------------------------------------------------------------------------- *)


        - by right.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 117) is:
 x <= last0 xs

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 117)
  
  xs : seq nat
  x : nat
  STR : nondecreasing_sequence xs
  IN : x \in xs
  NEQ : forall (t : eqType) (x y : t), x = y \/ x != y
  ============================
  x <= last0 xs

----------------------------------------------------------------------------- *)


      move: (NEQ _ x (last0 xs)); clear NEQ; move ⇒ [EQ|NEQ].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 211)
  
  xs : seq nat
  x : nat
  STR : nondecreasing_sequence xs
  IN : x \in xs
  EQ : x = last0 xs
  ============================
  x <= last0 xs

subgoal 2 (ID 212) is:
 x <= last0 xs

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 211)
  
  xs : seq nat
  x : nat
  STR : nondecreasing_sequence xs
  IN : x \in xs
  EQ : x = last0 xs
  ============================
  x <= last0 xs

----------------------------------------------------------------------------- *)


by subst x.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 212) is:
 x <= last0 xs

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 212)
  
  xs : seq nat
  x : nat
  STR : nondecreasing_sequence xs
  IN : x \in xs
  NEQ : x != last0 xs
  ============================
  x <= last0 xs

----------------------------------------------------------------------------- *)


      move: IN ⇒ /nthP EX.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 256)
  
  xs : seq nat
  x : nat
  STR : nondecreasing_sequence xs
  NEQ : x != last0 xs
  EX : forall s : nat_eqType, exists2 i : nat, i < size xs & nth s xs i = x
  ============================
  x <= last0 xs

----------------------------------------------------------------------------- *)


      specialize (EX 0).
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 258)
  
  xs : seq nat
  x : nat
  STR : nondecreasing_sequence xs
  NEQ : x != last0 xs
  EX : exists2 i : nat, i < size xs & xs [|i|] = x
  ============================
  x <= last0 xs

----------------------------------------------------------------------------- *)


      move: EX ⇒ [id SIZE EQ].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 273)
  
  xs : seq nat
  x : nat
  STR : nondecreasing_sequence xs
  NEQ : x != last0 xs
  id : nat
  SIZE : id < size xs
  EQ : xs [|id|] = x
  ============================
  x <= last0 xs

----------------------------------------------------------------------------- *)


      rewrite /last0 -nth_last -EQ; subst x.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 287)
  
  xs : seq nat
  STR : nondecreasing_sequence xs
  id : nat
  NEQ : xs [|id|] != last0 xs
  SIZE : id < size xs
  ============================
  xs [|id|] <= xs [|(size xs).-1|]

----------------------------------------------------------------------------- *)



      rewrite -addn1 in SIZE.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 302)
  
  xs : seq nat
  STR : nondecreasing_sequence xs
  id : nat
  NEQ : xs [|id|] != last0 xs
  SIZE : id + 1 <= size xs
  ============================
  xs [|id|] <= xs [|(size xs).-1|]

----------------------------------------------------------------------------- *)


      apply STR; apply/andP.

(* ----------------------------------[ coqtop ]---------------------------------

1 focused subgoal
(shelved: 1) (ID 327)
  
  xs : seq nat
  STR : nondecreasing_sequence xs
  id : nat
  NEQ : xs [|id|] != last0 xs
  SIZE : id + 1 <= size xs
  ============================
  id <= (size xs).-1 /\ (size xs).-1 < size xs

----------------------------------------------------------------------------- *)


      have POS: 0 < size xs.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 329)
  
  xs : seq nat
  STR : nondecreasing_sequence xs
  id : nat
  NEQ : xs [|id|] != last0 xs
  SIZE : id + 1 <= size xs
  ============================
  0 < size xs

subgoal 2 (ID 331) is:
 id <= (size xs).-1 /\ (size xs).-1 < size xs

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 329)
  
  xs : seq nat
  STR : nondecreasing_sequence xs
  id : nat
  NEQ : xs [|id|] != last0 xs
  SIZE : id + 1 <= size xs
  ============================
  0 < size xs

----------------------------------------------------------------------------- *)


by apply leq_trans with (id + 1); [rewrite addn1| done].
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 331) is:
 id <= (size xs).-1 /\ (size xs).-1 < size xs

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 331)
  
  xs : seq nat
  STR : nondecreasing_sequence xs
  id : nat
  NEQ : xs [|id|] != last0 xs
  SIZE : id + 1 <= size xs
  POS : 0 < size xs
  ============================
  id <= (size xs).-1 /\ (size xs).-1 < size xs

----------------------------------------------------------------------------- *)


      split.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 338)
  
  xs : seq nat
  STR : nondecreasing_sequence xs
  id : nat
  NEQ : xs [|id|] != last0 xs
  SIZE : id + 1 <= size xs
  POS : 0 < size xs
  ============================
  id <= (size xs).-1

subgoal 2 (ID 339) is:
 (size xs).-1 < size xs

----------------------------------------------------------------------------- *)


      - by rewrite -(leq_add2r 1) !addn1 prednK // -addn1.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 339)
  
  xs : seq nat
  STR : nondecreasing_sequence xs
  id : nat
  NEQ : xs [|id|] != last0 xs
  SIZE : id + 1 <= size xs
  POS : 0 < size xs
  ============================
  (size xs).-1 < size xs

----------------------------------------------------------------------------- *)


      - by rewrite prednK.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

  End 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:
       {X : eqType} (x : X) (xs : seq X),
        undup (x::x::xs) = undup (x::xs).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 22)
  
  ============================
  forall (X : eqType) (x : X) (xs : seq X),
  undup [:: x, x & xs] = undup (x :: xs)

----------------------------------------------------------------------------- *)


    Proof.
      intros; rewrite {2 3}[cons] lock //= -lock.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 58)
  
  X : eqType
  x : X
  xs : seq X
  ============================
  (if x \in x :: xs then undup (x :: xs) else x :: undup (x :: xs)) =
  undup (x :: xs)

----------------------------------------------------------------------------- *)


      rewrite in_cons eq_refl; simpl.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 73)
  
  X : eqType
  x : X
  xs : seq X
  ============================
  (if x \in xs then undup xs else x :: undup xs) =
  (if x \in xs then undup xs else x :: undup xs)

----------------------------------------------------------------------------- *)


        by destruct (x \in xs).

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

For non-decreasing sequences we show that the fact that [x1 < x2] implies that [undup x1::x2::xs = x1::undup x2::xs].
    Lemma nodup_sort_2cons_lt:
       x1 x2 xs,
        x1 < x2
        nondecreasing_sequence (x1::x2::xs)
        undup (x1::x2::xs) = x1 :: undup (x2::xs).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 35)
  
  ============================
  forall (x1 x2 : nat) (xs : seq nat),
  x1 < x2 ->
  nondecreasing_sequence [:: x1, x2 & xs] ->
  undup [:: x1, x2 & xs] = x1 :: undup (x2 :: xs)

----------------------------------------------------------------------------- *)


    Proof.
      intros; rewrite {2 3 4}[cons] lock //= -lock.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 73)
  
  x1, x2 : nat
  xs : seq nat
  H : x1 < x2
  H0 : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  (if x1 \in x2 :: xs then undup (x2 :: xs) else x1 :: undup (x2 :: xs)) =
  x1 :: undup (x2 :: xs)

----------------------------------------------------------------------------- *)


      rewrite in_cons.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 79)
  
  x1, x2 : nat
  xs : seq nat
  H : x1 < x2
  H0 : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  (if (x1 == x2) || (x1 \in xs)
   then undup (x2 :: xs)
   else x1 :: undup (x2 :: xs)) = x1 :: undup (x2 :: xs)

----------------------------------------------------------------------------- *)


      have → : (x1 == x2) = false.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 82)
  
  x1, x2 : nat
  xs : seq nat
  H : x1 < x2
  H0 : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  (x1 == x2) = false

subgoal 2 (ID 87) is:
 (if false || (x1 \in xs) then undup (x2 :: xs) else x1 :: undup (x2 :: xs)) =
 x1 :: undup (x2 :: xs)

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 82)
  
  x1, x2 : nat
  xs : seq nat
  H : x1 < x2
  H0 : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  (x1 == x2) = false

----------------------------------------------------------------------------- *)


by apply/eqP/eqP; rewrite neq_ltn; rewrite H.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 87) is:
 (if false || (x1 \in xs) then undup (x2 :: xs) else x1 :: undup (x2 :: xs)) =
 x1 :: undup (x2 :: xs)

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 87)
  
  x1, x2 : nat
  xs : seq nat
  H : x1 < x2
  H0 : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  (if false || (x1 \in xs) then undup (x2 :: xs) else x1 :: undup (x2 :: xs)) =
  x1 :: undup (x2 :: xs)

----------------------------------------------------------------------------- *)


      rewrite [cons]lock //= -lock.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 262)
  
  x1, x2 : nat
  xs : seq nat
  H : x1 < x2
  H0 : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  (if x1 \in xs then undup (x2 :: xs) else x1 :: undup (x2 :: xs)) =
  x1 :: undup (x2 :: xs)

----------------------------------------------------------------------------- *)


      have → : (x1 \in xs) = false; last by done.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 268)
  
  x1, x2 : nat
  xs : seq nat
  H : x1 < x2
  H0 : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  (x1 \in xs) = false

----------------------------------------------------------------------------- *)



      apply/eqP; rewrite eqbF_neg.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 331)
  
  x1, x2 : nat
  xs : seq nat
  H : x1 < x2
  H0 : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  x1 \notin xs

----------------------------------------------------------------------------- *)


      apply nondecreasing_sequence_cons in H0.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 333)
  
  x1, x2 : nat
  xs : seq nat
  H : x1 < x2
  H0 : nondecreasing_sequence (x2 :: xs)
  ============================
  x1 \notin xs

----------------------------------------------------------------------------- *)


      apply/negP; intros ?; eauto 2.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 355)
  
  x1, x2 : nat
  xs : seq nat
  H : x1 < x2
  H0 : nondecreasing_sequence (x2 :: xs)
  H1 : x1 \in xs
  ============================
  False

----------------------------------------------------------------------------- *)


      eapply nondecreasing_sequence_cons_min in H0; eauto 2.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 361)
  
  x1, x2 : nat
  xs : seq nat
  H : x1 < x2
  H1 : x1 \in xs
  H0 : x2 <= x1
  ============================
  False

----------------------------------------------------------------------------- *)


        by move_neq_down H.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

Next we show that function [undup] doesn't change the last element of a sequence.
    Lemma last0_undup:
       xs,
        nondecreasing_sequence xs
        last0 (undup xs) = last0 xs.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 39)
  
  ============================
  forall xs : seq nat,
  nondecreasing_sequence xs -> last0 (undup xs) = last0 xs

----------------------------------------------------------------------------- *)


    Proof.
      induction xs as [ | x1 xs]; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 48)
  
  x1 : nat
  xs : seq nat
  IHxs : nondecreasing_sequence xs -> last0 (undup xs) = last0 xs
  ============================
  nondecreasing_sequence (x1 :: xs) ->
  last0 (undup (x1 :: xs)) = last0 (x1 :: xs)

----------------------------------------------------------------------------- *)


      intros ND; destruct xs as [ |x2 xs]; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 66)
  
  x1, x2 : nat
  xs : seq nat
  IHxs : nondecreasing_sequence (x2 :: xs) ->
         last0 (undup (x2 :: xs)) = last0 (x2 :: xs)
  ND : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  last0 (undup [:: x1, x2 & xs]) = last0 [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)


      destruct (nondecreasing_sequence_2cons_leVeq _ _ _ ND) as [EQ|LT].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 79)
  
  x1, x2 : nat
  xs : seq nat
  IHxs : nondecreasing_sequence (x2 :: xs) ->
         last0 (undup (x2 :: xs)) = last0 (x2 :: xs)
  ND : nondecreasing_sequence [:: x1, x2 & xs]
  EQ : x1 = x2
  ============================
  last0 (undup [:: x1, x2 & xs]) = last0 [:: x1, x2 & xs]

subgoal 2 (ID 80) is:
 last0 (undup [:: x1, x2 & xs]) = last0 [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)


      + subst; rename x2 into x.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 87)
  
  x : nat
  xs : seq nat
  IHxs : nondecreasing_sequence (x :: xs) ->
         last0 (undup (x :: xs)) = last0 (x :: xs)
  ND : nondecreasing_sequence [:: x, x & xs]
  ============================
  last0 (undup [:: x, x & xs]) = last0 [:: x, x & xs]

subgoal 2 (ID 80) is:
 last0 (undup [:: x1, x2 & xs]) = last0 [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)


        rewrite nodup_sort_2cons_eq IHxs.

(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 96)
  
  x : nat
  xs : seq nat
  IHxs : nondecreasing_sequence (x :: xs) ->
         last0 (undup (x :: xs)) = last0 (x :: xs)
  ND : nondecreasing_sequence [:: x, x & xs]
  ============================
  last0 (x :: xs) = last0 [:: x, x & xs]

subgoal 2 (ID 97) is:
 nondecreasing_sequence (x :: xs)
subgoal 3 (ID 80) is:
 last0 (undup [:: x1, x2 & xs]) = last0 [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)


        rewrite [in X in _ = X]last0_cons //.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 97)
  
  x : nat
  xs : seq nat
  IHxs : nondecreasing_sequence (x :: xs) ->
         last0 (undup (x :: xs)) = last0 (x :: xs)
  ND : nondecreasing_sequence [:: x, x & xs]
  ============================
  nondecreasing_sequence (x :: xs)

subgoal 2 (ID 80) is:
 last0 (undup [:: x1, x2 & xs]) = last0 [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)


        eapply nondecreasing_sequence_cons; eauto 2.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 80)
  
  x1, x2 : nat
  xs : seq nat
  IHxs : nondecreasing_sequence (x2 :: xs) ->
         last0 (undup (x2 :: xs)) = last0 (x2 :: xs)
  ND : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  ============================
  last0 (undup [:: x1, x2 & xs]) = last0 [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)


      + rewrite nodup_sort_2cons_lt // last0_cons.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 174)
  
  x1, x2 : nat
  xs : seq nat
  IHxs : nondecreasing_sequence (x2 :: xs) ->
         last0 (undup (x2 :: xs)) = last0 (x2 :: xs)
  ND : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  ============================
  last0 (undup (x2 :: xs)) = last0 [:: x1, x2 & xs]

subgoal 2 (ID 175) is:
 undup (x2 :: xs) <> [::]

----------------------------------------------------------------------------- *)


        rewrite IHxs //; eauto using nondecreasing_sequence_cons.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 175)
  
  x1, x2 : nat
  xs : seq nat
  IHxs : nondecreasing_sequence (x2 :: xs) ->
         last0 (undup (x2 :: xs)) = last0 (x2 :: xs)
  ND : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  ============================
  undup (x2 :: xs) <> [::]

----------------------------------------------------------------------------- *)


          by intros ?; apply undup_nil in H.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

Non-decreasing sequence remains non-decreasing after application of [undup].
    Lemma nondecreasing_sequence_undup:
       xs,
        nondecreasing_sequence xs
        nondecreasing_sequence (undup xs).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 42)
  
  ============================
  forall xs : seq nat,
  nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)

----------------------------------------------------------------------------- *)


    Proof.
      intros ?.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 43)
  
  xs : seq nat
  ============================
  nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)

----------------------------------------------------------------------------- *)


      have EX: len, size xs len.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 47)
  
  xs : seq nat
  ============================
  exists len : nat, size xs <= len

subgoal 2 (ID 49) is:
 nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 47)
  
  xs : seq nat
  ============================
  exists len : nat, size xs <= len

----------------------------------------------------------------------------- *)


(size xs); now simpl.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 49) is:
 nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 49)
  
  xs : seq nat
  EX : exists len : nat, size xs <= len
  ============================
  nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)

----------------------------------------------------------------------------- *)


destruct EX as [n BO].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 58)
  
  xs : seq nat
  n : nat
  BO : size xs <= n
  ============================
  nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)

----------------------------------------------------------------------------- *)


      revert xs BO; induction n.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 64)
  
  ============================
  forall xs : seq nat,
  size xs <= 0 ->
  nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)

subgoal 2 (ID 67) is:
 forall xs : seq nat,
 size xs <= n.+1 ->
 nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)

----------------------------------------------------------------------------- *)



      - by intros xs; rewrite leqn0 size_eq0; move ⇒ /eqP EQ; subst xs.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 67)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)
  ============================
  forall xs : seq nat,
  size xs <= n.+1 ->
  nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)

----------------------------------------------------------------------------- *)


      - intros [ |x1 [ | x2 xs]]; try done.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 124)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)
  x1, x2 : nat
  xs : seq nat
  ============================
  size [:: x1, x2 & xs] <= n.+1 ->
  nondecreasing_sequence [:: x1, x2 & xs] ->
  nondecreasing_sequence (undup [:: x1, x2 & xs])

----------------------------------------------------------------------------- *)


        intros Size NonDec.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 167)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  nondecreasing_sequence (undup [:: x1, x2 & xs])

----------------------------------------------------------------------------- *)



        destruct (nondecreasing_sequence_2cons_leVeq _ _ _ NonDec) as [EQ|LT].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 180)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  EQ : x1 = x2
  ============================
  nondecreasing_sequence (undup [:: x1, x2 & xs])

subgoal 2 (ID 181) is:
 nondecreasing_sequence (undup [:: x1, x2 & xs])

----------------------------------------------------------------------------- *)


        × subst; rename x2 into x.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 190)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)
  x : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x, x & xs]
  Size : size [:: x, x & xs] <= n.+1
  ============================
  nondecreasing_sequence (undup [:: x, x & xs])

subgoal 2 (ID 181) is:
 nondecreasing_sequence (undup [:: x1, x2 & xs])

----------------------------------------------------------------------------- *)


            by rewrite nodup_sort_2cons_eq; apply IHn; eauto using nondecreasing_sequence_cons.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 181)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  ============================
  nondecreasing_sequence (undup [:: x1, x2 & xs])

----------------------------------------------------------------------------- *)


        × rewrite nodup_sort_2cons_lt //.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 211)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  ============================
  nondecreasing_sequence (x1 :: undup (x2 :: xs))

----------------------------------------------------------------------------- *)


          apply nondecreasing_sequence_add_min.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 238)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  ============================
  forall y : nat, y \in undup (x2 :: xs) -> x1 <= y

subgoal 2 (ID 239) is:
 nondecreasing_sequence (undup (x2 :: xs))

----------------------------------------------------------------------------- *)


          intros ? ?.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 241)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  y : nat
  H : y \in undup (x2 :: xs)
  ============================
  x1 <= y

subgoal 2 (ID 239) is:
 nondecreasing_sequence (undup (x2 :: xs))

----------------------------------------------------------------------------- *)


          eapply nondecreasing_sequence_cons_min with (y := y) in NonDec; auto.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 244)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  y : nat
  H : y \in undup (x2 :: xs)
  ============================
  y \in x2 :: xs

subgoal 2 (ID 239) is:
 nondecreasing_sequence (undup (x2 :: xs))

----------------------------------------------------------------------------- *)


          rewrite -mem_undup; eauto using nondecreasing_sequence_cons.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 239)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs -> nondecreasing_sequence (undup xs)
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  ============================
  nondecreasing_sequence (undup (x2 :: xs))

----------------------------------------------------------------------------- *)


            by apply IHn; eauto using nondecreasing_sequence_cons.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

We also show that the penultimate element of a sequence [undup xs] is bounded by the penultimate element of sequence [xs].
    Lemma undup_nth_le:
       xs,
        nondecreasing_sequence xs
        undup xs [| (size (undup xs)).-2 |] xs [| (size xs).-2 |].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 50)
  
  ============================
  forall xs : seq nat,
  nondecreasing_sequence xs ->
  undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]

----------------------------------------------------------------------------- *)


    Proof.
      Opaque undup.
      intros ?.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 51)
  
  xs : seq nat
  ============================
  nondecreasing_sequence xs ->
  undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]

----------------------------------------------------------------------------- *)


      have EX: len, size xs len.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 55)
  
  xs : seq nat
  ============================
  exists len : nat, size xs <= len

subgoal 2 (ID 57) is:
 nondecreasing_sequence xs ->
 undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 55)
  
  xs : seq nat
  ============================
  exists len : nat, size xs <= len

----------------------------------------------------------------------------- *)


(size xs); now simpl.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 57) is:
 nondecreasing_sequence xs ->
 undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 57)
  
  xs : seq nat
  EX : exists len : nat, size xs <= len
  ============================
  nondecreasing_sequence xs ->
  undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]

----------------------------------------------------------------------------- *)


destruct EX as [n BO].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 66)
  
  xs : seq nat
  n : nat
  BO : size xs <= n
  ============================
  nondecreasing_sequence xs ->
  undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]

----------------------------------------------------------------------------- *)


      revert xs BO; induction n.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 72)
  
  ============================
  forall xs : seq nat,
  size xs <= 0 ->
  nondecreasing_sequence xs ->
  undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]

subgoal 2 (ID 75) is:
 forall xs : seq nat,
 size xs <= n.+1 ->
 nondecreasing_sequence xs ->
 undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]

----------------------------------------------------------------------------- *)



      - by intros xs; rewrite leqn0 size_eq0; move ⇒ /eqP EQ; subst xs.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 75)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  ============================
  forall xs : seq nat,
  size xs <= n.+1 ->
  nondecreasing_sequence xs ->
  undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]

----------------------------------------------------------------------------- *)


      - intros [ |x1 [ | x2 xs]]; try done.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 132)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x1, x2 : nat
  xs : seq nat
  ============================
  size [:: x1, x2 & xs] <= n.+1 ->
  nondecreasing_sequence [:: x1, x2 & xs] ->
  undup [:: x1, x2 & xs] [|(size (undup [:: x1, x2 & xs])).-2|] <=
  [:: x1, x2 & xs] [|(size [:: x1, x2 & xs]).-2|]

----------------------------------------------------------------------------- *)


        intros Size NonDec.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 163)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  undup [:: x1, x2 & xs] [|(size (undup [:: x1, x2 & xs])).-2|] <=
  [:: x1, x2 & xs] [|(size [:: x1, x2 & xs]).-2|]

----------------------------------------------------------------------------- *)



        destruct (nondecreasing_sequence_2cons_leVeq _ _ _ NonDec) as [EQ|LT].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 176)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  EQ : x1 = x2
  ============================
  undup [:: x1, x2 & xs] [|(size (undup [:: x1, x2 & xs])).-2|] <=
  [:: x1, x2 & xs] [|(size [:: x1, x2 & xs]).-2|]

subgoal 2 (ID 177) is:
 undup [:: x1, x2 & xs] [|(size (undup [:: x1, x2 & xs])).-2|] <=
 [:: x1, x2 & xs] [|(size [:: x1, x2 & xs]).-2|]

----------------------------------------------------------------------------- *)


        × subst; rename x2 into x.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 186)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x, x & xs]
  Size : size [:: x, x & xs] <= n.+1
  ============================
  undup [:: x, x & xs] [|(size (undup [:: x, x & xs])).-2|] <=
  [:: x, x & xs] [|(size [:: x, x & xs]).-2|]

subgoal 2 (ID 177) is:
 undup [:: x1, x2 & xs] [|(size (undup [:: x1, x2 & xs])).-2|] <=
 [:: x1, x2 & xs] [|(size [:: x1, x2 & xs]).-2|]

----------------------------------------------------------------------------- *)



          rewrite nodup_sort_2cons_eq //.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 192)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x, x & xs]
  Size : size [:: x, x & xs] <= n.+1
  ============================
  undup (x :: xs) [|(size (undup (x :: xs))).-2|] <=
  [:: x, x & xs] [|(size [:: x, x & xs]).-2|]

subgoal 2 (ID 177) is:
 undup [:: x1, x2 & xs] [|(size (undup [:: x1, x2 & xs])).-2|] <=
 [:: x1, x2 & xs] [|(size [:: x1, x2 & xs]).-2|]

----------------------------------------------------------------------------- *)


          eapply leq_trans.
(* ----------------------------------[ coqtop ]---------------------------------

3 focused subgoals
(shelved: 1) (ID 215)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x, x & xs]
  Size : size [:: x, x & xs] <= n.+1
  ============================
  undup (x :: xs) [|(size (undup (x :: xs))).-2|] <= ?n

subgoal 2 (ID 216) is:
 ?n <= [:: x, x & xs] [|(size [:: x, x & xs]).-2|]
subgoal 3 (ID 177) is:
 undup [:: x1, x2 & xs] [|(size (undup [:: x1, x2 & xs])).-2|] <=
 [:: x1, x2 & xs] [|(size [:: x1, x2 & xs]).-2|]

----------------------------------------------------------------------------- *)


apply IHn.
(* ----------------------------------[ coqtop ]---------------------------------

4 subgoals (ID 217)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x, x & xs]
  Size : size [:: x, x & xs] <= n.+1
  ============================
  size (x :: xs) <= n

subgoal 2 (ID 218) is:
 nondecreasing_sequence (x :: xs)
subgoal 3 (ID 216) is:
 (x :: xs) [|(size (x :: xs)).-2|] <=
 [:: x, x & xs] [|(size [:: x, x & xs]).-2|]
subgoal 4 (ID 177) is:
 undup [:: x1, x2 & xs] [|(size (undup [:: x1, x2 & xs])).-2|] <=
 [:: x1, x2 & xs] [|(size [:: x1, x2 & xs]).-2|]

----------------------------------------------------------------------------- *)


by done.
(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 218)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x, x & xs]
  Size : size [:: x, x & xs] <= n.+1
  ============================
  nondecreasing_sequence (x :: xs)

subgoal 2 (ID 216) is:
 (x :: xs) [|(size (x :: xs)).-2|] <=
 [:: x, x & xs] [|(size [:: x, x & xs]).-2|]
subgoal 3 (ID 177) is:
 undup [:: x1, x2 & xs] [|(size (undup [:: x1, x2 & xs])).-2|] <=
 [:: x1, x2 & xs] [|(size [:: x1, x2 & xs]).-2|]

----------------------------------------------------------------------------- *)


eapply nondecreasing_sequence_cons; eauto.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 216)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x, x & xs]
  Size : size [:: x, x & xs] <= n.+1
  ============================
  (x :: xs) [|(size (x :: xs)).-2|] <=
  [:: x, x & xs] [|(size [:: x, x & xs]).-2|]

subgoal 2 (ID 177) is:
 undup [:: x1, x2 & xs] [|(size (undup [:: x1, x2 & xs])).-2|] <=
 [:: x1, x2 & xs] [|(size [:: x1, x2 & xs]).-2|]

----------------------------------------------------------------------------- *)


          destruct xs as [ | x1 xs]; first by done.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 236)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x, x1 : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x, x, x1 & xs]
  Size : size [:: x, x, x1 & xs] <= n.+1
  ============================
  [:: x, x1 & xs] [|(size [:: x, x1 & xs]).-2|] <=
  [:: x, x, x1 & xs] [|(size [:: x, x, x1 & xs]).-2|]

subgoal 2 (ID 177) is:
 undup [:: x1, x2 & xs] [|(size (undup [:: x1, x2 & xs])).-2|] <=
 [:: x1, x2 & xs] [|(size [:: x1, x2 & xs]).-2|]

----------------------------------------------------------------------------- *)


            by rewrite [in X in _ X]nth0_cons //.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 177)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  ============================
  undup [:: x1, x2 & xs] [|(size (undup [:: x1, x2 & xs])).-2|] <=
  [:: x1, x2 & xs] [|(size [:: x1, x2 & xs]).-2|]

----------------------------------------------------------------------------- *)


        × rewrite nodup_sort_2cons_lt //; simpl.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 287)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  ============================
  (x1 :: undup (x2 :: xs)) [|(size (undup (x2 :: xs))).-1|] <=
  [:: x1, x2 & xs] [|size xs|]

----------------------------------------------------------------------------- *)


          case (posnP (size (undup (x2 :: xs))).-1) as [Z|POS].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 313)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  Z : (size (undup (x2 :: xs))).-1 = 0
  ============================
  (x1 :: undup (x2 :: xs)) [|(size (undup (x2 :: xs))).-1|] <=
  [:: x1, x2 & xs] [|size xs|]

subgoal 2 (ID 314) is:
 (x1 :: undup (x2 :: xs)) [|(size (undup (x2 :: xs))).-1|] <=
 [:: x1, x2 & xs] [|size xs|]

----------------------------------------------------------------------------- *)


          -- rewrite Z; simpl.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 318)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  Z : (size (undup (x2 :: xs))).-1 = 0
  ============================
  x1 <= [:: x1, x2 & xs] [|size xs|]

subgoal 2 (ID 314) is:
 (x1 :: undup (x2 :: xs)) [|(size (undup (x2 :: xs))).-1|] <=
 [:: x1, x2 & xs] [|size xs|]

----------------------------------------------------------------------------- *)


             apply leq_trans with ([:: x1, x2 & xs] [|0|]); first by done.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 323)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  Z : (size (undup (x2 :: xs))).-1 = 0
  ============================
  [:: x1, x2 & xs] [|0|] <= [:: x1, x2 & xs] [|size xs|]

subgoal 2 (ID 314) is:
 (x1 :: undup (x2 :: xs)) [|(size (undup (x2 :: xs))).-1|] <=
 [:: x1, x2 & xs] [|size xs|]

----------------------------------------------------------------------------- *)


               by apply NonDec; apply/andP; split; simpl.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 314)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  POS : 0 < (size (undup (x2 :: xs))).-1
  ============================
  (x1 :: undup (x2 :: xs)) [|(size (undup (x2 :: xs))).-1|] <=
  [:: x1, x2 & xs] [|size xs|]

----------------------------------------------------------------------------- *)


          -- rewrite nth0_cons //.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 361)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  POS : 0 < (size (undup (x2 :: xs))).-1
  ============================
  undup (x2 :: xs) [|(size (undup (x2 :: xs))).-2|] <=
  [:: x1, x2 & xs] [|size xs|]

----------------------------------------------------------------------------- *)


             eapply leq_trans; first apply IHn; eauto using nondecreasing_sequence_cons.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 386)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x1, x2 : nat
  xs : seq nat
  Size : size [:: x1, x2 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LT : x1 < x2
  POS : 0 < (size (undup (x2 :: xs))).-1
  ============================
  (x2 :: xs) [|(size (x2 :: xs)).-2|] <= [:: x1, x2 & xs] [|size xs|]

----------------------------------------------------------------------------- *)


             destruct xs.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 2454)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x1, x2 : nat
  Size : size [:: x1; x2] <= n.+1
  NonDec : nondecreasing_sequence [:: x1; x2]
  LT : x1 < x2
  POS : 0 < (size (undup [:: x2])).-1
  ============================
  [:: x2] [|(size [:: x2]).-2|] <= [:: x1; x2] [|size [::]|]

subgoal 2 (ID 2463) is:
 [:: x2, n0 & xs] [|(size [:: x2, n0 & xs]).-2|] <=
 [:: x1, x2, n0 & xs] [|size (n0 :: xs)|]

----------------------------------------------------------------------------- *)


             ++ by exfalso.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 2463)
  
  n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        nondecreasing_sequence xs ->
        undup xs [|(size (undup xs)).-2|] <= xs [|(size xs).-2|]
  x1, x2, n0 : nat
  xs : seq nat
  Size : size [:: x1, x2, n0 & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x1, x2, n0 & xs]
  LT : x1 < x2
  POS : 0 < (size (undup [:: x2, n0 & xs])).-1
  ============================
  [:: x2, n0 & xs] [|(size [:: x2, n0 & xs]).-2|] <=
  [:: x1, x2, n0 & xs] [|size (n0 :: xs)|]

----------------------------------------------------------------------------- *)


             ++ destruct xs; simpl in *; auto.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


                Transparent undup.
    Qed.

  End Undup.

Properties of Distances

In this section we prove a few lemmas about function [distances].
  Section Distances.

We begin with a simple lemma that helps us unfold [distances] of lists with two consecutive cons [x0::x1::xs].
    Lemma distances_unfold_2cons:
       x0 x1 xs,
        distances (x0::x1::xs) = (x1 - x0) :: distances (x1::xs).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 27)
  
  ============================
  forall (x0 x1 : nat) (xs : seq nat),
  distances [:: x0, x1 & xs] = x1 - x0 :: distances (x1 :: xs)

----------------------------------------------------------------------------- *)


    Proof. by intros; unfold distances; simpl; rewrite drop0.
(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


Qed.

Similarly, we prove a lemma stating that two consecutive appends to a sequence in [distances] function ([distances(xs ++ [:: a; b])]) can be rewritten as [distances(xs ++ [:: a]) ++ [:: b - a]].
    Lemma distances_unfold_2app_last:
       (a b : nat) (xs : seq nat),
        distances (xs ++ [:: a; b])
        = distances (xs ++ [:: a]) ++ [:: b - a].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 39)
  
  ============================
  forall (a b : nat) (xs : seq nat),
  distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]

----------------------------------------------------------------------------- *)


    Proof.
      clear; intros.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 42)
  
  a, b : nat
  xs : seq nat
  ============================
  distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]

----------------------------------------------------------------------------- *)


      have EX: n, size xs n.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 46)
  
  a, b : nat
  xs : seq nat
  ============================
  exists n : nat, size xs <= n

subgoal 2 (ID 48) is:
 distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]

----------------------------------------------------------------------------- *)


(size xs); by done.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 48)
  
  a, b : nat
  xs : seq nat
  EX : exists n : nat, size xs <= n
  ============================
  distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]

----------------------------------------------------------------------------- *)


destruct EX as [n LE].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 56)
  
  a, b : nat
  xs : seq nat
  n : nat
  LE : size xs <= n
  ============================
  distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]

----------------------------------------------------------------------------- *)


      revert xs LE; induction n; intros.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 67)
  
  a, b : nat
  xs : seq nat
  LE : size xs <= 0
  ============================
  distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]

subgoal 2 (ID 69) is:
 distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]

----------------------------------------------------------------------------- *)


      - by move: LE; rewrite leqn0 size_eq0; move ⇒ /eqP LE; subst.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 69)
  
  a, b, n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]
  xs : seq nat
  LE : size xs <= n.+1
  ============================
  distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]

----------------------------------------------------------------------------- *)


      - destruct xs as [ | x0]; first by unfold distances.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 125)
  
  a, b, n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]
  x0 : nat
  xs : seq nat
  LE : size (x0 :: xs) <= n.+1
  ============================
  distances ((x0 :: xs) ++ [:: a; b]) =
  distances ((x0 :: xs) ++ [:: a]) ++ [:: b - a]

----------------------------------------------------------------------------- *)


        destruct xs as [ | x1]; first by unfold distances.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 138)
  
  a, b, n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]
  x0, x1 : nat
  xs : seq nat
  LE : size [:: x0, x1 & xs] <= n.+1
  ============================
  distances ([:: x0, x1 & xs] ++ [:: a; b]) =
  distances ([:: x0, x1 & xs] ++ [:: a]) ++ [:: b - a]

----------------------------------------------------------------------------- *)


        have → : distances ([:: x0, x1 & xs] ++ [:: a; b]) = x1 - x0 :: distances ((x1 :: xs) ++ [:: a; b]).

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 153)
  
  a, b, n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]
  x0, x1 : nat
  xs : seq nat
  LE : size [:: x0, x1 & xs] <= n.+1
  ============================
  distances ([:: x0, x1 & xs] ++ [:: a; b]) =
  x1 - x0 :: distances ((x1 :: xs) ++ [:: a; b])

subgoal 2 (ID 158) is:
 x1 - x0 :: distances ((x1 :: xs) ++ [:: a; b]) =
 distances ([:: x0, x1 & xs] ++ [:: a]) ++ [:: b - a]

----------------------------------------------------------------------------- *)


        {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 153)
  
  a, b, n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]
  x0, x1 : nat
  xs : seq nat
  LE : size [:: x0, x1 & xs] <= n.+1
  ============================
  distances ([:: x0, x1 & xs] ++ [:: a; b]) =
  x1 - x0 :: distances ((x1 :: xs) ++ [:: a; b])

----------------------------------------------------------------------------- *)


by simpl; rewrite distances_unfold_2cons.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 158) is:
 x1 - x0 :: distances ((x1 :: xs) ++ [:: a; b]) =
 distances ([:: x0, x1 & xs] ++ [:: a]) ++ [:: b - a]

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 158)
  
  a, b, n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]
  x0, x1 : nat
  xs : seq nat
  LE : size [:: x0, x1 & xs] <= n.+1
  ============================
  x1 - x0 :: distances ((x1 :: xs) ++ [:: a; b]) =
  distances ([:: x0, x1 & xs] ++ [:: a]) ++ [:: b - a]

----------------------------------------------------------------------------- *)


        rewrite IHn; last by simpl in *; rewrite -(leq_add2r 1) !addn1.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 171)
  
  a, b, n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]
  x0, x1 : nat
  xs : seq nat
  LE : size [:: x0, x1 & xs] <= n.+1
  ============================
  x1 - x0 :: distances ((x1 :: xs) ++ [:: a]) ++ [:: b - a] =
  distances ([:: x0, x1 & xs] ++ [:: a]) ++ [:: b - a]

----------------------------------------------------------------------------- *)


        have → : distances ([:: x0, x1 & xs] ++ [:: a]) = x1 - x0 :: distances ((x1 :: xs) ++ [:: a]).

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 200)
  
  a, b, n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]
  x0, x1 : nat
  xs : seq nat
  LE : size [:: x0, x1 & xs] <= n.+1
  ============================
  distances ([:: x0, x1 & xs] ++ [:: a]) =
  x1 - x0 :: distances ((x1 :: xs) ++ [:: a])

subgoal 2 (ID 205) is:
 x1 - x0 :: distances ((x1 :: xs) ++ [:: a]) ++ [:: b - a] =
 (x1 - x0 :: distances ((x1 :: xs) ++ [:: a])) ++ [:: b - a]

----------------------------------------------------------------------------- *)


        {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 200)
  
  a, b, n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]
  x0, x1 : nat
  xs : seq nat
  LE : size [:: x0, x1 & xs] <= n.+1
  ============================
  distances ([:: x0, x1 & xs] ++ [:: a]) =
  x1 - x0 :: distances ((x1 :: xs) ++ [:: a])

----------------------------------------------------------------------------- *)


by simpl; rewrite distances_unfold_2cons.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 205) is:
 x1 - x0 :: distances ((x1 :: xs) ++ [:: a]) ++ [:: b - a] =
 (x1 - x0 :: distances ((x1 :: xs) ++ [:: a])) ++ [:: b - a]

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 205)
  
  a, b, n : nat
  IHn : forall xs : seq nat,
        size xs <= n ->
        distances (xs ++ [:: a; b]) = distances (xs ++ [:: a]) ++ [:: b - a]
  x0, x1 : nat
  xs : seq nat
  LE : size [:: x0, x1 & xs] <= n.+1
  ============================
  x1 - x0 :: distances ((x1 :: xs) ++ [:: a]) ++ [:: b - a] =
  (x1 - x0 :: distances ((x1 :: xs) ++ [:: a])) ++ [:: b - a]

----------------------------------------------------------------------------- *)


          by done.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    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]].
    Lemma distances_unfold_1app_last:
       x xs,
        size xs 1
        distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 54)
  
  ============================
  forall (x : nat) (xs : seq nat),
  0 < size xs -> distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]

----------------------------------------------------------------------------- *)


    Proof.
      clear. intros x xs POS.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 57)
  
  x : nat
  xs : seq nat
  POS : 0 < size xs
  ============================
  distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]

----------------------------------------------------------------------------- *)


      have EX: n, size xs n.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 61)
  
  x : nat
  xs : seq nat
  POS : 0 < size xs
  ============================
  exists n : nat, size xs <= n

subgoal 2 (ID 63) is:
 distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]

----------------------------------------------------------------------------- *)


(size xs); by done.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 63)
  
  x : nat
  xs : seq nat
  POS : 0 < size xs
  EX : exists n : nat, size xs <= n
  ============================
  distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]

----------------------------------------------------------------------------- *)


destruct EX as [n LE].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 71)
  
  x : nat
  xs : seq nat
  POS : 0 < size xs
  n : nat
  LE : size xs <= n
  ============================
  distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]

----------------------------------------------------------------------------- *)


      revert x xs LE POS; induction n; intros.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 84)
  
  x : nat
  xs : seq nat
  LE : size xs <= 0
  POS : 0 < size xs
  ============================
  distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]

subgoal 2 (ID 88) is:
 distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]

----------------------------------------------------------------------------- *)


      - by move: LE; rewrite leqn0 size_eq0; move ⇒ /eqP LE; subst.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 88)
  
  n : nat
  IHn : forall (x : nat) (xs : seq nat),
        size xs <= n ->
        0 < size xs ->
        distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]
  x : nat
  xs : seq nat
  LE : size xs <= n.+1
  POS : 0 < size xs
  ============================
  distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]

----------------------------------------------------------------------------- *)


      - move: LE; rewrite leq_eqVlt; move ⇒ /orP [/eqP LEN' | LE]; last first.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 237)
  
  n : nat
  IHn : forall (x : nat) (xs : seq nat),
        size xs <= n ->
        0 < size xs ->
        distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]
  x : nat
  xs : seq nat
  POS : 0 < size xs
  LE : size xs < n.+1
  ============================
  distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]

subgoal 2 (ID 236) is:
 distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]

----------------------------------------------------------------------------- *)


        + by rewrite ltnS in LE; apply IHn.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 236)
  
  n : nat
  IHn : forall (x : nat) (xs : seq nat),
        size xs <= n ->
        0 < size xs ->
        distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]
  x : nat
  xs : seq nat
  POS : 0 < size xs
  LEN' : size xs = n.+1
  ============================
  distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]

----------------------------------------------------------------------------- *)


        + destruct (seq_elim_last _ _ LEN') as [x__new [xs__l [EQ2 LEN]]].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 275)
  
  n : nat
  IHn : forall (x : nat) (xs : seq nat),
        size xs <= n ->
        0 < size xs ->
        distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]
  x : nat
  xs : seq nat
  POS : 0 < size xs
  LEN' : size xs = n.+1
  x__new : nat
  xs__l : seq nat
  EQ2 : xs = xs__l ++ [:: x__new]
  LEN : size xs__l = n
  ============================
  distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]

----------------------------------------------------------------------------- *)


          subst xs; clear LEN' POS; rename xs__l into xs.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 285)
  
  n : nat
  IHn : forall (x : nat) (xs : seq nat),
        size xs <= n ->
        0 < size xs ->
        distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]
  x, x__new : nat
  xs : seq nat
  LEN : size xs = n
  ============================
  distances ((xs ++ [:: x__new]) ++ [:: x]) =
  distances (xs ++ [:: x__new]) ++ [:: x - last0 (xs ++ [:: x__new])]

----------------------------------------------------------------------------- *)


          rewrite -catA.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 291)
  
  n : nat
  IHn : forall (x : nat) (xs : seq nat),
        size xs <= n ->
        0 < size xs ->
        distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]
  x, x__new : nat
  xs : seq nat
  LEN : size xs = n
  ============================
  distances (xs ++ [:: x__new] ++ [:: x]) =
  distances (xs ++ [:: x__new]) ++ [:: x - last0 (xs ++ [:: x__new])]

----------------------------------------------------------------------------- *)


          rewrite distances_unfold_2app_last.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 296)
  
  n : nat
  IHn : forall (x : nat) (xs : seq nat),
        size xs <= n ->
        0 < size xs ->
        distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]
  x, x__new : nat
  xs : seq nat
  LEN : size xs = n
  ============================
  distances (xs ++ [:: x__new]) ++ [:: x - x__new] =
  distances (xs ++ [:: x__new]) ++ [:: x - last0 (xs ++ [:: x__new])]

----------------------------------------------------------------------------- *)



          destruct xs; first by done.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 308)
  
  n : nat
  IHn : forall (x : nat) (xs : seq nat),
        size xs <= n ->
        0 < size xs ->
        distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]
  x, x__new, n0 : nat
  xs : seq nat
  LEN : size (n0 :: xs) = n
  ============================
  distances ((n0 :: xs) ++ [:: x__new]) ++ [:: x - x__new] =
  distances ((n0 :: xs) ++ [:: x__new]) ++
  [:: x - last0 ((n0 :: xs) ++ [:: x__new])]

----------------------------------------------------------------------------- *)


          rewrite IHn.

(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 314)
  
  n : nat
  IHn : forall (x : nat) (xs : seq nat),
        size xs <= n ->
        0 < size xs ->
        distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]
  x, x__new, n0 : nat
  xs : seq nat
  LEN : size (n0 :: xs) = n
  ============================
  (distances (n0 :: xs) ++ [:: x__new - last0 (n0 :: xs)]) ++ [:: x - x__new] =
  (distances (n0 :: xs) ++ [:: x__new - last0 (n0 :: xs)]) ++
  [:: x - last0 ((n0 :: xs) ++ [:: x__new])]

subgoal 2 (ID 315) is:
 size (n0 :: xs) <= n
subgoal 3 (ID 316) is:
 0 < size (n0 :: xs)

----------------------------------------------------------------------------- *)


          × by rewrite /last0 last_cat.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 315)
  
  n : nat
  IHn : forall (x : nat) (xs : seq nat),
        size xs <= n ->
        0 < size xs ->
        distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]
  x, x__new, n0 : nat
  xs : seq nat
  LEN : size (n0 :: xs) = n
  ============================
  size (n0 :: xs) <= n

subgoal 2 (ID 316) is:
 0 < size (n0 :: xs)

----------------------------------------------------------------------------- *)


          × by rewrite LEN.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 316)
  
  n : nat
  IHn : forall (x : nat) (xs : seq nat),
        size xs <= n ->
        0 < size xs ->
        distances (xs ++ [:: x]) = distances xs ++ [:: x - last0 xs]
  x, x__new, n0 : nat
  xs : seq nat
  LEN : size (n0 :: xs) = n
  ============================
  0 < size (n0 :: xs)

----------------------------------------------------------------------------- *)


          × by done.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

We prove that the difference between any two neighboring elements is bounded by the max element of the distances-sequence.
    Lemma distance_between_neighboring_elements_le_max_distance_in_seq:
       (xs : seq nat) (n : nat),
        xs[|n.+1|] - xs[|n|] max0 (distances xs).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 57)
  
  ============================
  forall (xs : seq nat) (n : nat),
  xs [|n.+1|] - xs [|n|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


    Proof.
      clear; intros xs id.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 59)
  
  xs : seq nat
  id : nat
  ============================
  xs [|id.+1|] - xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


      apply leq_trans with (distances xs [| id |]).

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 61)
  
  xs : seq nat
  id : nat
  ============================
  xs [|id.+1|] - xs [|id|] <= distances xs [|id|]

subgoal 2 (ID 62) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


      rewrite leq_eqVlt; apply/orP; left; apply/eqP.

(* ----------------------------------[ coqtop ]---------------------------------

2 focused subgoals
(shelved: 1) (ID 120)
  
  xs : seq nat
  id : nat
  ============================
  xs [|id.+1|] - xs [|id|] = distances xs [|id|]

subgoal 2 (ID 62) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


      have EX: n, size xs n.
(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 124)
  
  xs : seq nat
  id : nat
  ============================
  exists n : nat, size xs <= n

subgoal 2 (ID 126) is:
 xs [|id.+1|] - xs [|id|] = distances xs [|id|]
subgoal 3 (ID 62) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


{
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 124)
  
  xs : seq nat
  id : nat
  ============================
  exists n : nat, size xs <= n

----------------------------------------------------------------------------- *)


by (size xs).
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals

subgoal 1 (ID 126) is:
 xs [|id.+1|] - xs [|id|] = distances xs [|id|]
subgoal 2 (ID 62) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 126)
  
  xs : seq nat
  id : nat
  EX : exists n : nat, size xs <= n
  ============================
  xs [|id.+1|] - xs [|id|] = distances xs [|id|]

subgoal 2 (ID 62) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


move: EX ⇒ [n LE].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 142)
  
  xs : seq nat
  id, n : nat
  LE : size xs <= n
  ============================
  xs [|id.+1|] - xs [|id|] = distances xs [|id|]

subgoal 2 (ID 62) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


      generalize dependent xs; generalize dependent id.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 146)
  
  n : nat
  ============================
  forall (id : nat) (xs : seq nat),
  size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]

subgoal 2 (ID 62) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


      induction n.
(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 150)
  
  ============================
  forall (id : nat) (xs : seq nat),
  size xs <= 0 -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]

subgoal 2 (ID 153) is:
 forall (id : nat) (xs : seq nat),
 size xs <= n.+1 -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
subgoal 3 (ID 62) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 150)
  
  ============================
  forall (id : nat) (xs : seq nat),
  size xs <= 0 -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]

----------------------------------------------------------------------------- *)


intros.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 156)
  
  id : nat
  xs : seq nat
  LE : size xs <= 0
  ============================
  xs [|id.+1|] - xs [|id|] = distances xs [|id|]

----------------------------------------------------------------------------- *)


        move: LE; rewrite leqn0 size_eq0; move ⇒ /eqP EQ; subst.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 200)
  
  id : nat
  ============================
  [::] [|id.+1|] - [::] [|id|] = distances [::] [|id|]

----------------------------------------------------------------------------- *)


          by rewrite !nth_default.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals

subgoal 1 (ID 153) is:
 forall (id : nat) (xs : seq nat),
 size xs <= n.+1 -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
subgoal 2 (ID 62) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 153)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  ============================
  forall (id : nat) (xs : seq nat),
  size xs <= n.+1 -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]

subgoal 2 (ID 62) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 153)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  ============================
  forall (id : nat) (xs : seq nat),
  size xs <= n.+1 -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]

----------------------------------------------------------------------------- *)


intros.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 234)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  id : nat
  xs : seq nat
  LE : size xs <= n.+1
  ============================
  xs [|id.+1|] - xs [|id|] = distances xs [|id|]

----------------------------------------------------------------------------- *)


        move: LE; rewrite leq_eqVlt; move ⇒ /orP [/eqP EQ|LT]; last first.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 314)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  id : nat
  xs : seq nat
  LT : size xs < n.+1
  ============================
  xs [|id.+1|] - xs [|id|] = distances xs [|id|]

subgoal 2 (ID 313) is:
 xs [|id.+1|] - xs [|id|] = distances xs [|id|]

----------------------------------------------------------------------------- *)


        {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 314)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  id : nat
  xs : seq nat
  LT : size xs < n.+1
  ============================
  xs [|id.+1|] - xs [|id|] = distances xs [|id|]

----------------------------------------------------------------------------- *)


by apply IHn; rewrite ltnS in LT.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals

subgoal 1 (ID 313) is:
 xs [|id.+1|] - xs [|id|] = distances xs [|id|]
subgoal 2 (ID 62) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 313)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  id : nat
  xs : seq nat
  EQ : size xs = n.+1
  ============================
  xs [|id.+1|] - xs [|id|] = distances xs [|id|]

----------------------------------------------------------------------------- *)


        destruct xs; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 343)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  id, n0 : nat
  xs : seq nat
  EQ : size (n0 :: xs) = n.+1
  ============================
  (n0 :: xs) [|id.+1|] - (n0 :: xs) [|id|] = distances (n0 :: xs) [|id|]

----------------------------------------------------------------------------- *)


        destruct xs; first by destruct id; [simpl |rewrite !nth_default].
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 376)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  id, n0, n1 : nat
  xs : seq nat
  EQ : size [:: n0, n1 & xs] = n.+1
  ============================
  [:: n0, n1 & xs] [|id.+1|] - [:: n0, n1 & xs] [|id|] =
  distances [:: n0, n1 & xs] [|id|]

----------------------------------------------------------------------------- *)


        have Fact: distances [:: n0, n1 & xs] = (n1 - n0) :: distances [:: n1 & xs].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 442)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  id, n0, n1 : nat
  xs : seq nat
  EQ : size [:: n0, n1 & xs] = n.+1
  ============================
  distances [:: n0, n1 & xs] = n1 - n0 :: distances (n1 :: xs)

subgoal 2 (ID 444) is:
 [:: n0, n1 & xs] [|id.+1|] - [:: n0, n1 & xs] [|id|] =
 distances [:: n0, n1 & xs] [|id|]

----------------------------------------------------------------------------- *)


        {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 442)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  id, n0, n1 : nat
  xs : seq nat
  EQ : size [:: n0, n1 & xs] = n.+1
  ============================
  distances [:: n0, n1 & xs] = n1 - n0 :: distances (n1 :: xs)

----------------------------------------------------------------------------- *)


by rewrite /distances; simpl; rewrite drop0.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals

subgoal 1 (ID 444) is:
 [:: n0, n1 & xs] [|id.+1|] - [:: n0, n1 & xs] [|id|] =
 distances [:: n0, n1 & xs] [|id|]
subgoal 2 (ID 62) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 444)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  id, n0, n1 : nat
  xs : seq nat
  EQ : size [:: n0, n1 & xs] = n.+1
  Fact : distances [:: n0, n1 & xs] = n1 - n0 :: distances (n1 :: xs)
  ============================
  [:: n0, n1 & xs] [|id.+1|] - [:: n0, n1 & xs] [|id|] =
  distances [:: n0, n1 & xs] [|id|]

----------------------------------------------------------------------------- *)



        rewrite Fact; clear Fact.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 461)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  id, n0, n1 : nat
  xs : seq nat
  EQ : size [:: n0, n1 & xs] = n.+1
  ============================
  [:: n0, n1 & xs] [|id.+1|] - [:: n0, n1 & xs] [|id|] =
  (n1 - n0 :: distances (n1 :: xs)) [|id|]

----------------------------------------------------------------------------- *)


        destruct id; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 468)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  id, n0, n1 : nat
  xs : seq nat
  EQ : size [:: n0, n1 & xs] = n.+1
  ============================
  [:: n0, n1 & xs] [|id.+2|] - [:: n0, n1 & xs] [|id.+1|] =
  (n1 - n0 :: distances (n1 :: xs)) [|id.+1|]

----------------------------------------------------------------------------- *)


        simpl.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 473)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  id, n0, n1 : nat
  xs : seq nat
  EQ : size [:: n0, n1 & xs] = n.+1
  ============================
  xs [|id|] - (n1 :: xs) [|id|] = distances (n1 :: xs) [|id|]

----------------------------------------------------------------------------- *)


        rewrite -IHn.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 478)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  id, n0, n1 : nat
  xs : seq nat
  EQ : size [:: n0, n1 & xs] = n.+1
  ============================
  xs [|id|] - (n1 :: xs) [|id|] = (n1 :: xs) [|id.+1|] - (n1 :: xs) [|id|]

subgoal 2 (ID 479) is:
 size (n1 :: xs) <= n

----------------------------------------------------------------------------- *)


simpl.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 481)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  id, n0, n1 : nat
  xs : seq nat
  EQ : size [:: n0, n1 & xs] = n.+1
  ============================
  xs [|id|] - (n1 :: xs) [|id|] = xs [|id|] - (n1 :: xs) [|id|]

subgoal 2 (ID 479) is:
 size (n1 :: xs) <= n

----------------------------------------------------------------------------- *)


by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 479)
  
  n : nat
  IHn : forall (id : nat) (xs : seq nat),
        size xs <= n -> xs [|id.+1|] - xs [|id|] = distances xs [|id|]
  id, n0, n1 : nat
  xs : seq nat
  EQ : size [:: n0, n1 & xs] = n.+1
  ============================
  size (n1 :: xs) <= n

----------------------------------------------------------------------------- *)


          by move: EQ ⇒ /eqP; simpl; rewrite eqSS; move ⇒ /eqP EQ; rewrite -EQ.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 62) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 62)
  
  xs : seq nat
  id : nat
  ============================
  distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 62)
  
  xs : seq nat
  id : nat
  ============================
  distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


have Lem: x xs, x \in xs x max0 xs.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 593)
  
  xs : seq nat
  id : nat
  ============================
  forall (x : nat) (xs0 : seq_predType nat_eqType),
  x \in xs0 -> x <= max0 xs0

subgoal 2 (ID 595) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


        {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 593)
  
  xs : seq nat
  id : nat
  ============================
  forall (x : nat) (xs0 : seq_predType nat_eqType),
  x \in xs0 -> x <= max0 xs0

----------------------------------------------------------------------------- *)


clear; intros.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 599)
  
  x : nat
  xs : seq_predType nat_eqType
  H : x \in xs
  ============================
  x <= max0 xs

----------------------------------------------------------------------------- *)


          generalize dependent x.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 601)
  
  xs : seq_predType nat_eqType
  ============================
  forall x : nat, x \in xs -> x <= max0 xs

----------------------------------------------------------------------------- *)


          induction xs; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 609)
  
  a : nat_eqType
  xs : seq nat_eqType
  IHxs : forall x : nat, x \in xs -> x <= max0 xs
  ============================
  forall x : nat, x \in a :: xs -> x <= max0 (a :: xs)

----------------------------------------------------------------------------- *)


          intros ? IN; rewrite max0_cons leq_max; apply/orP.

(* ----------------------------------[ coqtop ]---------------------------------

1 focused subgoal
(shelved: 1) (ID 669)
  
  a : nat_eqType
  xs : seq nat_eqType
  IHxs : forall x : nat, x \in xs -> x <= max0 xs
  x : nat
  IN : x \in a :: xs
  ============================
  x <= a \/ x <= max0 xs

----------------------------------------------------------------------------- *)


          move: IN; rewrite in_cons; move ⇒ /orP [/eqP EQ| IN].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 750)
  
  a : nat_eqType
  xs : seq nat_eqType
  IHxs : forall x : nat, x \in xs -> x <= max0 xs
  x : nat
  EQ : x = a
  ============================
  x <= a \/ x <= max0 xs

subgoal 2 (ID 751) is:
 x <= a \/ x <= max0 xs

----------------------------------------------------------------------------- *)


          - by left; subst.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 751)
  
  a : nat_eqType
  xs : seq nat_eqType
  IHxs : forall x : nat, x \in xs -> x <= max0 xs
  x : nat
  IN : x \in xs
  ============================
  x <= a \/ x <= max0 xs

----------------------------------------------------------------------------- *)


          - by right; apply IHxs.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 595) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


        }

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 595)
  
  xs : seq nat
  id : nat
  Lem : forall (x : nat) (xs : seq_predType nat_eqType),
        x \in xs -> x <= max0 xs
  ============================
  distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


        destruct (size (distances xs) id) eqn:SIZE.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 769)
  
  xs : seq nat
  id : nat
  Lem : forall (x : nat) (xs : seq_predType nat_eqType),
        x \in xs -> x <= max0 xs
  SIZE : (size (distances xs) <= id) = true
  ============================
  distances xs [|id|] <= max0 (distances xs)

subgoal 2 (ID 770) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


        {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 769)
  
  xs : seq nat
  id : nat
  Lem : forall (x : nat) (xs : seq_predType nat_eqType),
        x \in xs -> x <= max0 xs
  SIZE : (size (distances xs) <= id) = true
  ============================
  distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


by rewrite nth_default.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 770) is:
 distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 770)
  
  xs : seq nat
  id : nat
  Lem : forall (x : nat) (xs : seq_predType nat_eqType),
        x \in xs -> x <= max0 xs
  SIZE : (size (distances xs) <= id) = false
  ============================
  distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


        {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 770)
  
  xs : seq nat
  id : nat
  Lem : forall (x : nat) (xs : seq_predType nat_eqType),
        x \in xs -> x <= max0 xs
  SIZE : (size (distances xs) <= id) = false
  ============================
  distances xs [|id|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


apply Lem; rewrite mem_nth //.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 787)
  
  xs : seq nat
  id : nat
  Lem : forall (x : nat) (xs : seq_predType nat_eqType),
        x \in xs -> x <= max0 xs
  SIZE : (size (distances xs) <= id) = false
  ============================
  id < size (distances xs)

----------------------------------------------------------------------------- *)


          move: SIZE ⇒ /negP /negP.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 885)
  
  xs : seq nat
  id : nat
  Lem : forall (x : nat) (xs : seq_predType nat_eqType),
        x \in xs -> x <= max0 xs
  ============================
  ~~ (size (distances xs) <= id) -> id < size (distances xs)

----------------------------------------------------------------------------- *)


            by rewrite ltnNge.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


        }
(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)



      }
(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


             
    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].
    Lemma function_of_distances_is_correct:
       (xs : seq nat) (n : nat),
        (distances xs)[|n|] = xs[|n.+1|] - xs[|n|].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 62)
  
  ============================
  forall (xs : seq nat) (n : nat),
  distances xs [|n|] = xs [|n.+1|] - xs [|n|]

----------------------------------------------------------------------------- *)


    Proof.
      intros xs.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 63)
  
  xs : seq nat
  ============================
  forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]

----------------------------------------------------------------------------- *)


      have EX: len, size xs len.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 67)
  
  xs : seq nat
  ============================
  exists len : nat, size xs <= len

subgoal 2 (ID 69) is:
 forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 67)
  
  xs : seq nat
  ============================
  exists len : nat, size xs <= len

----------------------------------------------------------------------------- *)


by (size xs).
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 69) is:
 forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 69)
  
  xs : seq nat
  EX : exists len : nat, size xs <= len
  ============================
  forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]

----------------------------------------------------------------------------- *)


move: EX ⇒ [len LE].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 85)
  
  xs : seq nat
  len : nat
  LE : size xs <= len
  ============================
  forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]

----------------------------------------------------------------------------- *)


      generalize dependent xs.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 87)
  
  len : nat
  ============================
  forall xs : seq nat,
  size xs <= len ->
  forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]

----------------------------------------------------------------------------- *)


      induction len; intros.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 97)
  
  xs : seq nat
  LE : size xs <= 0
  n : nat
  ============================
  distances xs [|n|] = xs [|n.+1|] - xs [|n|]

subgoal 2 (ID 100) is:
 distances xs [|n|] = xs [|n.+1|] - xs [|n|]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 97)
  
  xs : seq nat
  LE : size xs <= 0
  n : nat
  ============================
  distances xs [|n|] = xs [|n.+1|] - xs [|n|]

----------------------------------------------------------------------------- *)


move: LE; rewrite leqn0 size_eq0; move ⇒ /eqP EQ; subst.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 144)
  
  n : nat
  ============================
  distances [::] [|n|] = [::] [|n.+1|] - [::] [|n|]

----------------------------------------------------------------------------- *)


        unfold distances.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 145)
  
  n : nat
  ============================
  [seq (let '(x1, x2) := pat in x2 - x1) | pat <- zip [::] (drop 1 [::])]
  [|n|] = [::] [|n.+1|] - [::] [|n|]

----------------------------------------------------------------------------- *)


simpl.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 150)
  
  n : nat
  ============================
  [::] [|n|] = 0 - [::] [|n|]

----------------------------------------------------------------------------- *)


          by destruct n; simpl.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 100) is:
 distances xs [|n|] = xs [|n.+1|] - xs [|n|]

----------------------------------------------------------------------------- *)


      }
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 100)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  xs : seq nat
  LE : size xs <= len.+1
  n : nat
  ============================
  distances xs [|n|] = xs [|n.+1|] - xs [|n|]

----------------------------------------------------------------------------- *)



      move: LE; rewrite leq_eqVlt; move ⇒ /orP [/eqP EQ| LE]; last by apply IHlen.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 241)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  xs : seq nat
  n : nat
  EQ : size xs = len.+1
  ============================
  distances xs [|n|] = xs [|n.+1|] - xs [|n|]

----------------------------------------------------------------------------- *)


      destruct xs as [ | x1 xs]; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 257)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  x1 : nat
  xs : seq nat
  n : nat
  EQ : size (x1 :: xs) = len.+1
  ============================
  distances (x1 :: xs) [|n|] = (x1 :: xs) [|n.+1|] - (x1 :: xs) [|n|]

----------------------------------------------------------------------------- *)


      destruct xs as [ | x2 xs].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 287)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  x1, n : nat
  EQ : size [:: x1] = len.+1
  ============================
  distances [:: x1] [|n|] = [:: x1] [|n.+1|] - [:: x1] [|n|]

subgoal 2 (ID 292) is:
 distances [:: x1, x2 & xs] [|n|] =
 [:: x1, x2 & xs] [|n.+1|] - [:: x1, x2 & xs] [|n|]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 287)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  x1, n : nat
  EQ : size [:: x1] = len.+1
  ============================
  distances [:: x1] [|n|] = [:: x1] [|n.+1|] - [:: x1] [|n|]

----------------------------------------------------------------------------- *)


by destruct n as [ | [ | ]].
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 292) is:
 distances [:: x1, x2 & xs] [|n|] =
 [:: x1, x2 & xs] [|n.+1|] - [:: x1, x2 & xs] [|n|]

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 292)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  x1, x2 : nat
  xs : seq nat
  n : nat
  EQ : size [:: x1, x2 & xs] = len.+1
  ============================
  distances [:: x1, x2 & xs] [|n|] =
  [:: x1, x2 & xs] [|n.+1|] - [:: x1, x2 & xs] [|n|]

----------------------------------------------------------------------------- *)


      destruct n; first by done.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 312)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  x1, x2 : nat
  xs : seq nat
  n : nat
  EQ : size [:: x1, x2 & xs] = len.+1
  ============================
  distances [:: x1, x2 & xs] [|n.+1|] =
  [:: x1, x2 & xs] [|n.+2|] - [:: x1, x2 & xs] [|n.+1|]

----------------------------------------------------------------------------- *)


      have F: distances [:: x1, x2 & xs] [|n.+1|] = distances [::x2 & xs] [| n |].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 319)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  x1, x2 : nat
  xs : seq nat
  n : nat
  EQ : size [:: x1, x2 & xs] = len.+1
  ============================
  distances [:: x1, x2 & xs] [|n.+1|] = distances (x2 :: xs) [|n|]

subgoal 2 (ID 321) is:
 distances [:: x1, x2 & xs] [|n.+1|] =
 [:: x1, x2 & xs] [|n.+2|] - [:: x1, x2 & xs] [|n.+1|]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 319)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  x1, x2 : nat
  xs : seq nat
  n : nat
  EQ : size [:: x1, x2 & xs] = len.+1
  ============================
  distances [:: x1, x2 & xs] [|n.+1|] = distances (x2 :: xs) [|n|]

----------------------------------------------------------------------------- *)


have EQ': distances [:: x1, x2 & xs] = (x2 - x1) :: distances [::x2 & xs].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 327)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  x1, x2 : nat
  xs : seq nat
  n : nat
  EQ : size [:: x1, x2 & xs] = len.+1
  ============================
  distances [:: x1, x2 & xs] = x2 - x1 :: distances (x2 :: xs)

subgoal 2 (ID 329) is:
 distances [:: x1, x2 & xs] [|n.+1|] = distances (x2 :: xs) [|n|]

----------------------------------------------------------------------------- *)


        {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 327)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  x1, x2 : nat
  xs : seq nat
  n : nat
  EQ : size [:: x1, x2 & xs] = len.+1
  ============================
  distances [:: x1, x2 & xs] = x2 - x1 :: distances (x2 :: xs)

----------------------------------------------------------------------------- *)


by unfold distances; simpl; rewrite drop0.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals

subgoal 1 (ID 329) is:
 distances [:: x1, x2 & xs] [|n.+1|] = distances (x2 :: xs) [|n|]
subgoal 2 (ID 321) is:
 distances [:: x1, x2 & xs] [|n.+1|] =
 [:: x1, x2 & xs] [|n.+2|] - [:: x1, x2 & xs] [|n.+1|]

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 329)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  x1, x2 : nat
  xs : seq nat
  n : nat
  EQ : size [:: x1, x2 & xs] = len.+1
  EQ' : distances [:: x1, x2 & xs] = x2 - x1 :: distances (x2 :: xs)
  ============================
  distances [:: x1, x2 & xs] [|n.+1|] = distances (x2 :: xs) [|n|]

----------------------------------------------------------------------------- *)



          by rewrite EQ'.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 321) is:
 distances [:: x1, x2 & xs] [|n.+1|] =
 [:: x1, x2 & xs] [|n.+2|] - [:: x1, x2 & xs] [|n.+1|]

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 321)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  x1, x2 : nat
  xs : seq nat
  n : nat
  EQ : size [:: x1, x2 & xs] = len.+1
  F : distances [:: x1, x2 & xs] [|n.+1|] = distances (x2 :: xs) [|n|]
  ============================
  distances [:: x1, x2 & xs] [|n.+1|] =
  [:: x1, x2 & xs] [|n.+2|] - [:: x1, x2 & xs] [|n.+1|]

----------------------------------------------------------------------------- *)


      have F2: [:: x1, x2 & xs] [|n.+2|] - [:: x1, x2 & xs] [|n.+1|] = [:: x2 & xs] [|n.+1|] - [:: x2 & xs] [|n|]; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 359)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  x1, x2 : nat
  xs : seq nat
  n : nat
  EQ : size [:: x1, x2 & xs] = len.+1
  F : distances [:: x1, x2 & xs] [|n.+1|] = distances (x2 :: xs) [|n|]
  F2 : [:: x1, x2 & xs] [|n.+2|] - [:: x1, x2 & xs] [|n.+1|] =
       (x2 :: xs) [|n.+1|] - (x2 :: xs) [|n|]
  ============================
  distances [:: x1, x2 & xs] [|n.+1|] =
  [:: x1, x2 & xs] [|n.+2|] - [:: x1, x2 & xs] [|n.+1|]

----------------------------------------------------------------------------- *)


      rewrite F F2.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 363)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  x1, x2 : nat
  xs : seq nat
  n : nat
  EQ : size [:: x1, x2 & xs] = len.+1
  F : distances [:: x1, x2 & xs] [|n.+1|] = distances (x2 :: xs) [|n|]
  F2 : [:: x1, x2 & xs] [|n.+2|] - [:: x1, x2 & xs] [|n.+1|] =
       (x2 :: xs) [|n.+1|] - (x2 :: xs) [|n|]
  ============================
  distances (x2 :: xs) [|n|] = (x2 :: xs) [|n.+1|] - (x2 :: xs) [|n|]

----------------------------------------------------------------------------- *)


      apply IHlen.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 364)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  x1, x2 : nat
  xs : seq nat
  n : nat
  EQ : size [:: x1, x2 & xs] = len.+1
  F : distances [:: x1, x2 & xs] [|n.+1|] = distances (x2 :: xs) [|n|]
  F2 : [:: x1, x2 & xs] [|n.+2|] - [:: x1, x2 & xs] [|n.+1|] =
       (x2 :: xs) [|n.+1|] - (x2 :: xs) [|n|]
  ============================
  size (x2 :: xs) <= len

----------------------------------------------------------------------------- *)


      move: EQ ⇒ /eqP; simpl; rewrite eqSS; move ⇒ /eqP EQ.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 464)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len ->
          forall n : nat, distances xs [|n|] = xs [|n.+1|] - xs [|n|]
  x1, x2 : nat
  xs : seq nat
  n : nat
  F : distances [:: x1, x2 & xs] [|n.+1|] = distances (x2 :: xs) [|n|]
  F2 : [:: x1, x2 & xs] [|n.+2|] - [:: x1, x2 & xs] [|n.+1|] =
       (x2 :: xs) [|n.+1|] - (x2 :: xs) [|n|]
  EQ : (size xs).+1 = len
  ============================
  size xs < len

----------------------------------------------------------------------------- *)


        by rewrite -EQ.
(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

We show that the size of a distances-sequence is one less than the size of the original sequence.
    Lemma size_of_seq_of_distances:
       (xs : seq nat),
        2 size xs
        size xs = size (distances xs) + 1.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 67)
  
  ============================
  forall xs : seq nat, 1 < size xs -> size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)


    Proof.
      clear.
      intros xs.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 68)
  
  xs : seq nat
  ============================
  1 < size xs -> size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)


      have EX: len, size xs len.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 72)
  
  xs : seq nat
  ============================
  exists len : nat, size xs <= len

subgoal 2 (ID 74) is:
 1 < size xs -> size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 72)
  
  xs : seq nat
  ============================
  exists len : nat, size xs <= len

----------------------------------------------------------------------------- *)


(size xs).
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 77)
  
  xs : seq nat
  ============================
  size xs <= size xs

----------------------------------------------------------------------------- *)


by done.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 74) is:
 1 < size xs -> size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 74)
  
  xs : seq nat
  EX : exists len : nat, size xs <= len
  ============================
  1 < size xs -> size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)



      move: EX ⇒ [len LE].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 90)
  
  xs : seq nat
  len : nat
  LE : size xs <= len
  ============================
  1 < size xs -> size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)


      generalize dependent xs.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 92)
  
  len : nat
  ============================
  forall xs : seq nat,
  size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)


      induction len.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 96)
  
  ============================
  forall xs : seq nat,
  size xs <= 0 -> 1 < size xs -> size xs = size (distances xs) + 1

subgoal 2 (ID 99) is:
 forall xs : seq nat,
 size xs <= len.+1 -> 1 < size xs -> size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 96)
  
  ============================
  forall xs : seq nat,
  size xs <= 0 -> 1 < size xs -> size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)


intros.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 102)
  
  xs : seq nat
  LE : size xs <= 0
  H : 1 < size xs
  ============================
  size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)


        move: LE; rewrite leqn0 size_eq0; move ⇒ /eqP EQ; subst.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 150)
  
  H : 1 < size [::]
  ============================
  size [::] = size (distances [::]) + 1

----------------------------------------------------------------------------- *)


          by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 99) is:
 forall xs : seq nat,
 size xs <= len.+1 -> 1 < size xs -> size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 99)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  ============================
  forall xs : seq nat,
  size xs <= len.+1 -> 1 < size xs -> size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)


      intros ? ? SIZE.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 174)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  xs : seq nat
  LE : size xs <= len.+1
  SIZE : 1 < size xs
  ============================
  size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)


      move: LE; rewrite leq_eqVlt; move ⇒ /orP [/eqP EQ| LE]; last first.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 254)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  xs : seq nat
  SIZE : 1 < size xs
  LE : size xs < len.+1
  ============================
  size xs = size (distances xs) + 1

subgoal 2 (ID 253) is:
 size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 254)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  xs : seq nat
  SIZE : 1 < size xs
  LE : size xs < len.+1
  ============================
  size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)


by apply IHlen.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 253) is:
 size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 253)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  xs : seq nat
  SIZE : 1 < size xs
  EQ : size xs = len.+1
  ============================
  size xs = size (distances xs) + 1

----------------------------------------------------------------------------- *)


      destruct xs as [ | x1 xs]; first by inversion EQ.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 272)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  x1 : nat
  xs : seq nat
  SIZE : 1 < size (x1 :: xs)
  EQ : size (x1 :: xs) = len.+1
  ============================
  size (x1 :: xs) = size (distances (x1 :: xs)) + 1

----------------------------------------------------------------------------- *)


      destruct xs as [ | x2 xs]; first by inversion SIZE.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 297)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  x1, x2 : nat
  xs : seq nat
  SIZE : 1 < size [:: x1, x2 & xs]
  EQ : size [:: x1, x2 & xs] = len.+1
  ============================
  size [:: x1, x2 & xs] = size (distances [:: x1, x2 & xs]) + 1

----------------------------------------------------------------------------- *)


      destruct xs as [ | x3 xs]; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 322)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  x1, x2, x3 : nat
  xs : seq nat
  SIZE : 1 < size [:: x1, x2, x3 & xs]
  EQ : size [:: x1, x2, x3 & xs] = len.+1
  ============================
  size [:: x1, x2, x3 & xs] = size (distances [:: x1, x2, x3 & xs]) + 1

----------------------------------------------------------------------------- *)


      clear SIZE.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 323)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  x1, x2, x3 : nat
  xs : seq nat
  EQ : size [:: x1, x2, x3 & xs] = len.+1
  ============================
  size [:: x1, x2, x3 & xs] = size (distances [:: x1, x2, x3 & xs]) + 1

----------------------------------------------------------------------------- *)


      have F1: size [:: x1, x2, x3 & xs] = size [:: x2, x3 & xs] + 1.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 332)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  x1, x2, x3 : nat
  xs : seq nat
  EQ : size [:: x1, x2, x3 & xs] = len.+1
  ============================
  size [:: x1, x2, x3 & xs] = size [:: x2, x3 & xs] + 1

subgoal 2 (ID 334) is:
 size [:: x1, x2, x3 & xs] = size (distances [:: x1, x2, x3 & xs]) + 1

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 332)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  x1, x2, x3 : nat
  xs : seq nat
  EQ : size [:: x1, x2, x3 & xs] = len.+1
  ============================
  size [:: x1, x2, x3 & xs] = size [:: x2, x3 & xs] + 1

----------------------------------------------------------------------------- *)


by rewrite addn1.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 334) is:
 size [:: x1, x2, x3 & xs] = size (distances [:: x1, x2, x3 & xs]) + 1

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 334)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  x1, x2, x3 : nat
  xs : seq nat
  EQ : size [:: x1, x2, x3 & xs] = len.+1
  F1 : size [:: x1, x2, x3 & xs] = size [:: x2, x3 & xs] + 1
  ============================
  size [:: x1, x2, x3 & xs] = size (distances [:: x1, x2, x3 & xs]) + 1

----------------------------------------------------------------------------- *)



      have F2: size (distances [:: x1, x2, x3 & xs]) = size (distances [:: x2, x3 & xs]) + 1.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 346)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  x1, x2, x3 : nat
  xs : seq nat
  EQ : size [:: x1, x2, x3 & xs] = len.+1
  F1 : size [:: x1, x2, x3 & xs] = size [:: x2, x3 & xs] + 1
  ============================
  size (distances [:: x1, x2, x3 & xs]) =
  size (distances [:: x2, x3 & xs]) + 1

subgoal 2 (ID 348) is:
 size [:: x1, x2, x3 & xs] = size (distances [:: x1, x2, x3 & xs]) + 1

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 346)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  x1, x2, x3 : nat
  xs : seq nat
  EQ : size [:: x1, x2, x3 & xs] = len.+1
  F1 : size [:: x1, x2, x3 & xs] = size [:: x2, x3 & xs] + 1
  ============================
  size (distances [:: x1, x2, x3 & xs]) =
  size (distances [:: x2, x3 & xs]) + 1

----------------------------------------------------------------------------- *)


by rewrite addn1.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 348) is:
 size [:: x1, x2, x3 & xs] = size (distances [:: x1, x2, x3 & xs]) + 1

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 348)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  x1, x2, x3 : nat
  xs : seq nat
  EQ : size [:: x1, x2, x3 & xs] = len.+1
  F1 : size [:: x1, x2, x3 & xs] = size [:: x2, x3 & xs] + 1
  F2 : size (distances [:: x1, x2, x3 & xs]) =
       size (distances [:: x2, x3 & xs]) + 1
  ============================
  size [:: x1, x2, x3 & xs] = size (distances [:: x1, x2, x3 & xs]) + 1

----------------------------------------------------------------------------- *)


      rewrite F1 F2; clear F1 F2.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 356)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  x1, x2, x3 : nat
  xs : seq nat
  EQ : size [:: x1, x2, x3 & xs] = len.+1
  ============================
  size [:: x2, x3 & xs] + 1 = size (distances [:: x2, x3 & xs]) + 1 + 1

----------------------------------------------------------------------------- *)


      apply/eqP; rewrite eqn_add2r; apply/eqP.

(* ----------------------------------[ coqtop ]---------------------------------

1 focused subgoal
(shelved: 1) (ID 444)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  x1, x2, x3 : nat
  xs : seq nat
  EQ : size [:: x1, x2, x3 & xs] = len.+1
  ============================
  size [:: x2, x3 & xs] = size (distances [:: x2, x3 & xs]) + 1

----------------------------------------------------------------------------- *)


      apply IHlen; last by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 445)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  x1, x2, x3 : nat
  xs : seq nat
  EQ : size [:: x1, x2, x3 & xs] = len.+1
  ============================
  size [:: x2, x3 & xs] <= len

----------------------------------------------------------------------------- *)


      move: EQ ⇒ /eqP.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 505)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  x1, x2, x3 : nat
  xs : seq nat
  ============================
  size [:: x1, x2, x3 & xs] == len.+1 -> size [:: x2, x3 & xs] <= len

----------------------------------------------------------------------------- *)


simpl.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 511)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  x1, x2, x3 : nat
  xs : seq nat
  ============================
  (size xs).+3 == len.+1 -> (size xs).+1 < len

----------------------------------------------------------------------------- *)


rewrite eqSS; move ⇒ /eqP EQ.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 548)
  
  len : nat
  IHlen : forall xs : seq nat,
          size xs <= len -> 1 < size xs -> size xs = size (distances xs) + 1
  x1, x2, x3 : nat
  xs : seq nat
  EQ : (size xs).+2 = len
  ============================
  (size xs).+1 < len

----------------------------------------------------------------------------- *)


        by rewrite -EQ.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

We prove that [index_iota 0 n] produces a sequence of numbers with which are always one unit apart each other.
    Lemma distances_of_iota_ε:
       n x, x \in distances (index_iota 0 n) x = ε.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 76)
  
  ============================
  forall (n : nat) (x : nat_eqType),
  x \in distances (index_iota 0 n) -> x = ε

----------------------------------------------------------------------------- *)


    Proof.
      clear; intros n x IN.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 79)
  
  n : nat
  x : nat_eqType
  IN : x \in distances (index_iota 0 n)
  ============================
  x = ε

----------------------------------------------------------------------------- *)


      induction n.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 88)
  
  x : nat_eqType
  IN : x \in distances (index_iota 0 0)
  ============================
  x = ε

subgoal 2 (ID 93) is:
 x = ε

----------------------------------------------------------------------------- *)


      - by unfold index_iota, distances in IN.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 93)
  
  n : nat
  x : nat_eqType
  IN : x \in distances (index_iota 0 n.+1)
  IHn : x \in distances (index_iota 0 n) -> x = ε
  ============================
  x = ε

----------------------------------------------------------------------------- *)


      - destruct n; first by unfold distances, index_iota in IN.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 131)
  
  n : nat
  x : nat_eqType
  IN : x \in distances (index_iota 0 n.+2)
  IHn : x \in distances (index_iota 0 n.+1) -> x = ε
  ============================
  x = ε

----------------------------------------------------------------------------- *)


        rewrite -addn1 /index_iota subn0 iota_add in IN .

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 178)
  
  n : nat
  x : nat_eqType
  IHn : x \in distances (index_iota 0 n.+1) -> x = ε
  IN : x \in distances (iota 0 n.+1 ++ iota (0 + n.+1) 1)
  ============================
  x = ε

----------------------------------------------------------------------------- *)


        rewrite add0n in IN.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 194)
  
  n : nat
  x : nat_eqType
  IHn : x \in distances (index_iota 0 n.+1) -> x = ε
  IN : x \in distances (iota 0 n.+1 ++ iota n.+1 1)
  ============================
  x = ε

----------------------------------------------------------------------------- *)


        rewrite distances_unfold_1app_last in IN; last by rewrite size_iota.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 211)
  
  n : nat
  x : nat_eqType
  IHn : x \in distances (index_iota 0 n.+1) -> x = ε
  IN : x \in distances (iota 0 n.+1) ++ [:: n.+1 - last0 (iota 0 n.+1)]
  ============================
  x = ε

----------------------------------------------------------------------------- *)


        move: IN; rewrite mem_cat; move ⇒ /orP [IN|IN].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 271)
  
  n : nat
  x : nat_eqType
  IHn : x \in distances (index_iota 0 n.+1) -> x = ε
  IN : x \in distances (iota 0 n.+1)
  ============================
  x = ε

subgoal 2 (ID 272) is:
 x = ε

----------------------------------------------------------------------------- *)


        + by apply IHn; rewrite /index_iota subn0; simpl.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 272)
  
  n : nat
  x : nat_eqType
  IHn : x \in distances (index_iota 0 n.+1) -> x = ε
  IN : x \in [:: n.+1 - last0 (iota 0 n.+1)]
  ============================
  x = ε

----------------------------------------------------------------------------- *)


        + by move: IN;
            rewrite -addn1 iota_add /last0 last_cat add0n addn1 // subSnn in_cons;
            move ⇒ /orP [/eqP EQ|F]; subst.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

  End Distances.

Properties of Distances of Non-Decreasing Sequence

In this section, we prove a few basic lemmas about distances of non-decreasing sequences.
First we show that the max distance between elements of any nontrivial sequence (i.e. a sequence that contains at leas two distinct elements) is positive.
    Lemma max_distance_in_nontrivial_seq_is_positive:
       (xs : seq nat),
        nondecreasing_sequence xs
        ( x y, x \in xs y \in xs x y)
        0 < max0 (distances xs).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 31)
  
  ============================
  forall xs : seq nat,
  nondecreasing_sequence xs ->
  (exists x y : nat_eqType, x \in xs /\ y \in xs /\ x <> y) ->
  0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


    Proof.
      movexs SIZE SMI.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 34)
  
  xs : seq nat
  SIZE : nondecreasing_sequence xs
  SMI : exists x y : nat_eqType, x \in xs /\ y \in xs /\ x <> y
  ============================
  0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


move: SMI ⇒ [x [y [INx [INy NEQ]]]].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 77)
  
  xs : seq nat
  SIZE : nondecreasing_sequence xs
  x, y : nat_eqType
  INx : x \in xs
  INy : y \in xs
  NEQ : x <> y
  ============================
  0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


      move: INx INy ⇒ /nthP INx /nthP INy.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 152)
  
  xs : seq nat
  SIZE : nondecreasing_sequence xs
  x, y : nat_eqType
  NEQ : x <> y
  INx : forall s : nat_eqType, exists2 i : nat, i < size xs & nth s xs i = x
  INy : forall s : nat_eqType, exists2 i : nat, i < size xs & nth s xs i = y
  ============================
  0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


specialize (INx 0); specialize (INy 0).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 156)
  
  xs : seq nat
  SIZE : nondecreasing_sequence xs
  x, y : nat_eqType
  NEQ : x <> y
  INx : exists2 i : nat, i < size xs & xs [|i|] = x
  INy : exists2 i : nat, i < size xs & xs [|i|] = y
  ============================
  0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


      move: INx INy ⇒ [indx SIZEx EQx] [indy SIZEy EQy].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 186)
  
  xs : seq nat
  SIZE : nondecreasing_sequence xs
  x, y : nat_eqType
  NEQ : x <> y
  indx : nat
  SIZEx : indx < size xs
  EQx : xs [|indx|] = x
  indy : nat
  SIZEy : indy < size xs
  EQy : xs [|indy|] = y
  ============================
  0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


      have L: (x y indx indy : nat),
          indx < size xs indy < size xs
          nondecreasing_sequence xs
          x < y xs [|indx|] = x xs [|indy|] = y
          0 < max0 (distances xs).

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 193)
  
  xs : seq nat
  SIZE : nondecreasing_sequence xs
  x, y : nat_eqType
  NEQ : x <> y
  indx : nat
  SIZEx : indx < size xs
  EQx : xs [|indx|] = x
  indy : nat
  SIZEy : indy < size xs
  EQy : xs [|indy|] = y
  ============================
  forall x0 y0 indx0 indy0 : nat,
  indx0 < size xs ->
  indy0 < size xs ->
  nondecreasing_sequence xs ->
  x0 < y0 ->
  xs [|indx0|] = x0 -> xs [|indy0|] = y0 -> 0 < max0 (distances xs)

subgoal 2 (ID 195) is:
 0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 193)
  
  xs : seq nat
  SIZE : nondecreasing_sequence xs
  x, y : nat_eqType
  NEQ : x <> y
  indx : nat
  SIZEx : indx < size xs
  EQx : xs [|indx|] = x
  indy : nat
  SIZEy : indy < size xs
  EQy : xs [|indy|] = y
  ============================
  forall x0 y0 indx0 indy0 : nat,
  indx0 < size xs ->
  indy0 < size xs ->
  nondecreasing_sequence xs ->
  x0 < y0 ->
  xs [|indx0|] = x0 -> xs [|indy0|] = y0 -> 0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


clear; intros x y indx indy SIZEx SIZEy SIZE LT EQx EQy.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 206)
  
  xs : seq nat
  x, y, indx, indy : nat
  SIZEx : indx < size xs
  SIZEy : indy < size xs
  SIZE : nondecreasing_sequence xs
  LT : x < y
  EQx : xs [|indx|] = x
  EQy : xs [|indy|] = y
  ============================
  0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


        have LTind: indx < indy.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 207)
  
  xs : seq nat
  x, y, indx, indy : nat
  SIZEx : indx < size xs
  SIZEy : indy < size xs
  SIZE : nondecreasing_sequence xs
  LT : x < y
  EQx : xs [|indx|] = x
  EQy : xs [|indy|] = y
  ============================
  indx < indy

subgoal 2 (ID 209) is:
 0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


        {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 207)
  
  xs : seq nat
  x, y, indx, indy : nat
  SIZEx : indx < size xs
  SIZEy : indy < size xs
  SIZE : nondecreasing_sequence xs
  LT : x < y
  EQx : xs [|indx|] = x
  EQy : xs [|indy|] = y
  ============================
  indx < indy

----------------------------------------------------------------------------- *)


rewrite ltnNge; apply/negP; intros CONTR.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 235)
  
  xs : seq nat
  x, y, indx, indy : nat
  SIZEx : indx < size xs
  SIZEy : indy < size xs
  SIZE : nondecreasing_sequence xs
  LT : x < y
  EQx : xs [|indx|] = x
  EQy : xs [|indy|] = y
  CONTR : indy <= indx
  ============================
  False

----------------------------------------------------------------------------- *)


          subst x y; move: LT; rewrite ltnNge; move ⇒ /negP T; apply: T.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 284)
  
  xs : seq nat
  indx, indy : nat
  SIZEx : indx < size xs
  SIZEy : indy < size xs
  SIZE : nondecreasing_sequence xs
  CONTR : indy <= indx
  ============================
  xs [|indy|] <= xs [|indx|]

----------------------------------------------------------------------------- *)


            by apply SIZE; apply/andP.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals

subgoal 1 (ID 209) is:
 0 < max0 (distances xs)
subgoal 2 (ID 195) is:
 0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 209)
  
  xs : seq nat
  x, y, indx, indy : nat
  SIZEx : indx < size xs
  SIZEy : indy < size xs
  SIZE : nondecreasing_sequence xs
  LT : x < y
  EQx : xs [|indx|] = x
  EQy : xs [|indy|] = y
  LTind : indx < indy
  ============================
  0 < max0 (distances xs)

----------------------------------------------------------------------------- *)



        have EQ: Δ, indy = indx + Δ.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 340)
  
  xs : seq nat
  x, y, indx, indy : nat
  SIZEx : indx < size xs
  SIZEy : indy < size xs
  SIZE : nondecreasing_sequence xs
  LT : x < y
  EQx : xs [|indx|] = x
  EQy : xs [|indy|] = y
  LTind : indx < indy
  ============================
  exists Δ : nat, indy = indx + Δ

subgoal 2 (ID 342) is:
 0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


(indy - indx); ssrlia.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 342)
  
  xs : seq nat
  x, y, indx, indy : nat
  SIZEx : indx < size xs
  SIZEy : indy < size xs
  SIZE : nondecreasing_sequence xs
  LT : x < y
  EQx : xs [|indx|] = x
  EQy : xs [|indy|] = y
  LTind : indx < indy
  EQ : exists Δ : nat, indy = indx + Δ
  ============================
  0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


move: EQ ⇒ [Δ EQ]; subst indy.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 584)
  
  xs : seq nat
  x, y, indx : nat
  SIZEx : indx < size xs
  Δ : nat
  SIZEy : indx + Δ < size xs
  SIZE : nondecreasing_sequence xs
  LT : x < y
  EQx : xs [|indx|] = x
  LTind : indx < indx + Δ
  EQy : xs [|indx + Δ|] = y
  ============================
  0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


        have F: ind, indx ind < indx + Δ xs[|ind|] < xs[|ind.+1|].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 589)
  
  xs : seq nat
  x, y, indx : nat
  SIZEx : indx < size xs
  Δ : nat
  SIZEy : indx + Δ < size xs
  SIZE : nondecreasing_sequence xs
  LT : x < y
  EQx : xs [|indx|] = x
  LTind : indx < indx + Δ
  EQy : xs [|indx + Δ|] = y
  ============================
  exists ind : nat, indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]

subgoal 2 (ID 591) is:
 0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


        {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 589)
  
  xs : seq nat
  x, y, indx : nat
  SIZEx : indx < size xs
  Δ : nat
  SIZEy : indx + Δ < size xs
  SIZE : nondecreasing_sequence xs
  LT : x < y
  EQx : xs [|indx|] = x
  LTind : indx < indx + Δ
  EQy : xs [|indx + Δ|] = y
  ============================
  exists ind : nat, indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]

----------------------------------------------------------------------------- *)


subst x y; clear SIZEx SIZEy; revert xs indx LTind SIZE LT.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 606)
  
  Δ : nat
  ============================
  forall (xs : seq nat) (indx : nat),
  indx < indx + Δ ->
  nondecreasing_sequence xs ->
  xs [|indx|] < xs [|indx + Δ|] ->
  exists ind : nat, indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]

----------------------------------------------------------------------------- *)


          induction Δ; intros; first by ssrlia.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 623)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  LT : xs [|indx|] < xs [|indx + Δ.+1|]
  ============================
  exists ind : nat, indx <= ind < indx + Δ.+1 /\ xs [|ind|] < xs [|ind.+1|]

----------------------------------------------------------------------------- *)


          destruct (posnP Δ) as [ZERO|POS].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 792)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  LT : xs [|indx|] < xs [|indx + Δ.+1|]
  ZERO : Δ = 0
  ============================
  exists ind : nat, indx <= ind < indx + Δ.+1 /\ xs [|ind|] < xs [|ind.+1|]

subgoal 2 (ID 793) is:
 exists ind : nat, indx <= ind < indx + Δ.+1 /\ xs [|ind|] < xs [|ind.+1|]

----------------------------------------------------------------------------- *)


          {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 792)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  LT : xs [|indx|] < xs [|indx + Δ.+1|]
  ZERO : Δ = 0
  ============================
  exists ind : nat, indx <= ind < indx + Δ.+1 /\ xs [|ind|] < xs [|ind.+1|]

----------------------------------------------------------------------------- *)


by subst Δ; indx; split; [rewrite addn1; apply/andP | rewrite addn1 in LT]; auto.
(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals

subgoal 1 (ID 793) is:
 exists ind : nat, indx <= ind < indx + Δ.+1 /\ xs [|ind|] < xs [|ind.+1|]
subgoal 2 (ID 591) is:
 0 < max0 (distances xs)
subgoal 3 (ID 195) is:
 0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 793)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  LT : xs [|indx|] < xs [|indx + Δ.+1|]
  POS : 0 < Δ
  ============================
  exists ind : nat, indx <= ind < indx + Δ.+1 /\ xs [|ind|] < xs [|ind.+1|]

----------------------------------------------------------------------------- *)


          have ALT: xs[|indx + Δ|] == xs[|indx + Δ.+1|] xs[|indx + Δ|] < xs[|indx + Δ.+1|].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 859)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  LT : xs [|indx|] < xs [|indx + Δ.+1|]
  POS : 0 < Δ
  ============================
  xs [|indx + Δ|] == xs [|indx + Δ.+1|] \/
  xs [|indx + Δ|] < xs [|indx + Δ.+1|]

subgoal 2 (ID 861) is:
 exists ind : nat, indx <= ind < indx + Δ.+1 /\ xs [|ind|] < xs [|ind.+1|]

----------------------------------------------------------------------------- *)


          {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 859)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  LT : xs [|indx|] < xs [|indx + Δ.+1|]
  POS : 0 < Δ
  ============================
  xs [|indx + Δ|] == xs [|indx + Δ.+1|] \/
  xs [|indx + Δ|] < xs [|indx + Δ.+1|]

----------------------------------------------------------------------------- *)


apply/orP; rewrite -leq_eqVlt addnS.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 917)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  LT : xs [|indx|] < xs [|indx + Δ.+1|]
  POS : 0 < Δ
  ============================
  xs [|indx + Δ|] <= xs [|(indx + Δ).+1|]

----------------------------------------------------------------------------- *)


            apply SIZE; apply/andP; split; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 945)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  LT : xs [|indx|] < xs [|indx + Δ.+1|]
  POS : 0 < Δ
  ============================
  (indx + Δ).+1 < size xs

----------------------------------------------------------------------------- *)


            rewrite ltnNge; apply/negP; intros CONTR.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 971)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  LT : xs [|indx|] < xs [|indx + Δ.+1|]
  POS : 0 < Δ
  CONTR : size xs <= (indx + Δ).+1
  ============================
  False

----------------------------------------------------------------------------- *)


            move: LT; rewrite ltnNge; move ⇒ /negP LT; apply: LT.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 1008)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  POS : 0 < Δ
  CONTR : size xs <= (indx + Δ).+1
  ============================
  xs [|indx + Δ.+1|] <= xs [|indx|]

----------------------------------------------------------------------------- *)


              by rewrite nth_default ?addnS.
(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals

subgoal 1 (ID 861) is:
 exists ind : nat, indx <= ind < indx + Δ.+1 /\ xs [|ind|] < xs [|ind.+1|]
subgoal 2 (ID 591) is:
 0 < max0 (distances xs)
subgoal 3 (ID 195) is:
 0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 861)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  LT : xs [|indx|] < xs [|indx + Δ.+1|]
  POS : 0 < Δ
  ALT : xs [|indx + Δ|] == xs [|indx + Δ.+1|] \/
        xs [|indx + Δ|] < xs [|indx + Δ.+1|]
  ============================
  exists ind : nat, indx <= ind < indx + Δ.+1 /\ xs [|ind|] < xs [|ind.+1|]

----------------------------------------------------------------------------- *)


                   
          move: ALT ⇒ [/eqP EQ|LT'].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 1072)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  LT : xs [|indx|] < xs [|indx + Δ.+1|]
  POS : 0 < Δ
  EQ : xs [|indx + Δ|] = xs [|indx + Δ.+1|]
  ============================
  exists ind : nat, indx <= ind < indx + Δ.+1 /\ xs [|ind|] < xs [|ind.+1|]

subgoal 2 (ID 1071) is:
 exists ind : nat, indx <= ind < indx + Δ.+1 /\ xs [|ind|] < xs [|ind.+1|]

----------------------------------------------------------------------------- *)


          - edestruct (IHΔ) as [ind [B UP]]; eauto 5 using addn1, leq_add2l.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 1092)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  LT : xs [|indx|] < xs [|indx + Δ.+1|]
  POS : 0 < Δ
  EQ : xs [|indx + Δ|] = xs [|indx + Δ.+1|]
  ind : nat
  B : indx <= ind < indx + Δ
  UP : xs [|ind|] < xs [|ind.+1|]
  ============================
  exists ind0 : nat,
    indx <= ind0 < indx + Δ.+1 /\ xs [|ind0|] < xs [|ind0.+1|]

subgoal 2 (ID 1071) is:
 exists ind : nat, indx <= ind < indx + Δ.+1 /\ xs [|ind|] < xs [|ind.+1|]

----------------------------------------------------------------------------- *)


             ind; split; last by done.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 5687)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  LT : xs [|indx|] < xs [|indx + Δ.+1|]
  POS : 0 < Δ
  EQ : xs [|indx + Δ|] = xs [|indx + Δ.+1|]
  ind : nat
  B : indx <= ind < indx + Δ
  UP : xs [|ind|] < xs [|ind.+1|]
  ============================
  indx <= ind < indx + Δ.+1

subgoal 2 (ID 1071) is:
 exists ind : nat, indx <= ind < indx + Δ.+1 /\ xs [|ind|] < xs [|ind.+1|]

----------------------------------------------------------------------------- *)


            move: B ⇒ /andP [B1 B2]; apply/andP; split; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 5756)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  LT : xs [|indx|] < xs [|indx + Δ.+1|]
  POS : 0 < Δ
  EQ : xs [|indx + Δ|] = xs [|indx + Δ.+1|]
  ind : nat
  UP : xs [|ind|] < xs [|ind.+1|]
  B1 : indx <= ind
  B2 : ind < indx + Δ
  ============================
  ind < indx + Δ.+1

subgoal 2 (ID 1071) is:
 exists ind : nat, indx <= ind < indx + Δ.+1 /\ xs [|ind|] < xs [|ind.+1|]

----------------------------------------------------------------------------- *)


              by rewrite addnS ltnS ltnW.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 1071)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  LT : xs [|indx|] < xs [|indx + Δ.+1|]
  POS : 0 < Δ
  LT' : xs [|indx + Δ|] < xs [|indx + Δ.+1|]
  ============================
  exists ind : nat, indx <= ind < indx + Δ.+1 /\ xs [|ind|] < xs [|ind.+1|]

----------------------------------------------------------------------------- *)


          - (indx + Δ); split; last by rewrite -addnS.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 5774)
  
  Δ : nat
  IHΔ : forall (xs : seq nat) (indx : nat),
        indx < indx + Δ ->
        nondecreasing_sequence xs ->
        xs [|indx|] < xs [|indx + Δ|] ->
        exists ind : nat,
          indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  xs : seq nat
  indx : nat
  LTind : indx < indx + Δ.+1
  SIZE : nondecreasing_sequence xs
  LT : xs [|indx|] < xs [|indx + Δ.+1|]
  POS : 0 < Δ
  LT' : xs [|indx + Δ|] < xs [|indx + Δ.+1|]
  ============================
  indx <= indx + Δ < indx + Δ.+1

----------------------------------------------------------------------------- *)


              by apply/andP; split; [rewrite leq_addr | rewrite addnS].
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals

subgoal 1 (ID 591) is:
 0 < max0 (distances xs)
subgoal 2 (ID 195) is:
 0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


 }

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 591)
  
  xs : seq nat
  x, y, indx : nat
  SIZEx : indx < size xs
  Δ : nat
  SIZEy : indx + Δ < size xs
  SIZE : nondecreasing_sequence xs
  LT : x < y
  EQx : xs [|indx|] = x
  LTind : indx < indx + Δ
  EQy : xs [|indx + Δ|] = y
  F : exists ind : nat, indx <= ind < indx + Δ /\ xs [|ind|] < xs [|ind.+1|]
  ============================
  0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


        move: F ⇒ [ind [/andP [B1 B2] UP]].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 5875)
  
  xs : seq nat
  x, y, indx : nat
  SIZEx : indx < size xs
  Δ : nat
  SIZEy : indx + Δ < size xs
  SIZE : nondecreasing_sequence xs
  LT : x < y
  EQx : xs [|indx|] = x
  LTind : indx < indx + Δ
  EQy : xs [|indx + Δ|] = y
  ind : nat
  B1 : indx <= ind
  B2 : ind < indx + Δ
  UP : xs [|ind|] < xs [|ind.+1|]
  ============================
  0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


        apply leq_trans with (xs [|ind.+1|] - xs [|ind|]).

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 5878)
  
  xs : seq nat
  x, y, indx : nat
  SIZEx : indx < size xs
  Δ : nat
  SIZEy : indx + Δ < size xs
  SIZE : nondecreasing_sequence xs
  LT : x < y
  EQx : xs [|indx|] = x
  LTind : indx < indx + Δ
  EQy : xs [|indx + Δ|] = y
  ind : nat
  B1 : indx <= ind
  B2 : ind < indx + Δ
  UP : xs [|ind|] < xs [|ind.+1|]
  ============================
  0 < xs [|ind.+1|] - xs [|ind|]

subgoal 2 (ID 5879) is:
 xs [|ind.+1|] - xs [|ind|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


        - by rewrite subn_gt0.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 5879)
  
  xs : seq nat
  x, y, indx : nat
  SIZEx : indx < size xs
  Δ : nat
  SIZEy : indx + Δ < size xs
  SIZE : nondecreasing_sequence xs
  LT : x < y
  EQx : xs [|indx|] = x
  LTind : indx < indx + Δ
  EQy : xs [|indx + Δ|] = y
  ind : nat
  B1 : indx <= ind
  B2 : ind < indx + Δ
  UP : xs [|ind|] < xs [|ind.+1|]
  ============================
  xs [|ind.+1|] - xs [|ind|] <= max0 (distances xs)

----------------------------------------------------------------------------- *)


        - by apply distance_between_neighboring_elements_le_max_distance_in_seq.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 195) is:
 0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 195)
  
  xs : seq nat
  SIZE : nondecreasing_sequence xs
  x, y : nat_eqType
  NEQ : x <> y
  indx : nat
  SIZEx : indx < size xs
  EQx : xs [|indx|] = x
  indy : nat
  SIZEy : indy < size xs
  EQy : xs [|indy|] = y
  L : forall x y indx indy : nat,
      indx < size xs ->
      indy < size xs ->
      nondecreasing_sequence xs ->
      x < y -> xs [|indx|] = x -> xs [|indy|] = y -> 0 < max0 (distances xs)
  ============================
  0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


      move: NEQ ⇒ /eqP; rewrite neq_ltn; move ⇒ /orP [LT|LT].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 6002)
  
  xs : seq nat
  SIZE : nondecreasing_sequence xs
  x, y : nat_eqType
  indx : nat
  SIZEx : indx < size xs
  EQx : xs [|indx|] = x
  indy : nat
  SIZEy : indy < size xs
  EQy : xs [|indy|] = y
  L : forall x y indx indy : nat,
      indx < size xs ->
      indy < size xs ->
      nondecreasing_sequence xs ->
      x < y -> xs [|indx|] = x -> xs [|indy|] = y -> 0 < max0 (distances xs)
  LT : x < y
  ============================
  0 < max0 (distances xs)

subgoal 2 (ID 6003) is:
 0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


      - eapply L with (indx := indx) (x := x) (y := y); eauto.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 6003)
  
  xs : seq nat
  SIZE : nondecreasing_sequence xs
  x, y : nat_eqType
  indx : nat
  SIZEx : indx < size xs
  EQx : xs [|indx|] = x
  indy : nat
  SIZEy : indy < size xs
  EQy : xs [|indy|] = y
  L : forall x y indx indy : nat,
      indx < size xs ->
      indy < size xs ->
      nondecreasing_sequence xs ->
      x < y -> xs [|indx|] = x -> xs [|indy|] = y -> 0 < max0 (distances xs)
  LT : y < x
  ============================
  0 < max0 (distances xs)

----------------------------------------------------------------------------- *)


      - eapply L with (indx := indy) (indy := indx) (x := y) (y := x); eauto.
(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    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]].
    Lemma last_seq_minus_last_distance_seq:
       (xs : seq nat),
        nondecreasing_sequence xs
        last0 xs - last0 (distances xs) = xs [| (size xs).-2 |].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 35)
  
  ============================
  forall xs : seq nat,
  nondecreasing_sequence xs ->
  last0 xs - last0 (distances xs) = xs [|(size xs).-2|]

----------------------------------------------------------------------------- *)


    Proof.
      clear.
      intros xs SIS.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 37)
  
  xs : seq nat
  SIS : nondecreasing_sequence xs
  ============================
  last0 xs - last0 (distances xs) = xs [|(size xs).-2|]

----------------------------------------------------------------------------- *)


      destruct xs as [ | x1 xs].
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 46)
  
  SIS : nondecreasing_sequence [::]
  ============================
  last0 [::] - last0 (distances [::]) = [::] [|(size [::]).-2|]

subgoal 2 (ID 49) is:
 last0 (x1 :: xs) - last0 (distances (x1 :: xs)) =
 (x1 :: xs) [|(size (x1 :: xs)).-2|]

----------------------------------------------------------------------------- *)


by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 49)
  
  x1 : nat
  xs : seq nat
  SIS : nondecreasing_sequence (x1 :: xs)
  ============================
  last0 (x1 :: xs) - last0 (distances (x1 :: xs)) =
  (x1 :: xs) [|(size (x1 :: xs)).-2|]

----------------------------------------------------------------------------- *)


      destruct xs as [ | x2 xs].
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 58)
  
  x1 : nat
  SIS : nondecreasing_sequence [:: x1]
  ============================
  last0 [:: x1] - last0 (distances [:: x1]) = [:: x1] [|(size [:: x1]).-2|]

subgoal 2 (ID 61) is:
 last0 [:: x1, x2 & xs] - last0 (distances [:: x1, x2 & xs]) =
 [:: x1, x2 & xs] [|(size [:: x1, x2 & xs]).-2|]

----------------------------------------------------------------------------- *)


by rewrite subn0.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 61)
  
  x1, x2 : nat
  xs : seq nat
  SIS : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  last0 [:: x1, x2 & xs] - last0 (distances [:: x1, x2 & xs]) =
  [:: x1, x2 & xs] [|(size [:: x1, x2 & xs]).-2|]

----------------------------------------------------------------------------- *)


      rewrite {2}/last0 -[in X in _ - X]nth_last function_of_distances_is_correct prednK;
        last by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 85)
  
  x1, x2 : nat
  xs : seq nat
  SIS : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  last0 [:: x1, x2 & xs] -
  ([:: x1, x2 & xs] [|size (distances [:: x1, x2 & xs])|] -
   [:: x1, x2 & xs] [|(size (distances [:: x1, x2 & xs])).-1|]) =
  [:: x1, x2 & xs] [|(size [:: x1, x2 & xs]).-2|]

----------------------------------------------------------------------------- *)


      set [:: x1, x2 & xs] as X.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 90)
  
  x1, x2 : nat
  xs : seq nat
  SIS : nondecreasing_sequence [:: x1, x2 & xs]
  X := [:: x1, x2 & xs] : seq nat
  ============================
  last0 X - (X [|size (distances X)|] - X [|(size (distances X)).-1|]) =
  X [|(size X).-2|]

----------------------------------------------------------------------------- *)


      rewrite /last0 -nth_last.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 96)
  
  x1, x2 : nat
  xs : seq nat
  SIS : nondecreasing_sequence [:: x1, x2 & xs]
  X := [:: x1, x2 & xs] : seq nat
  ============================
  X [|(size X).-1|] -
  (X [|size (distances X)|] - X [|(size (distances X)).-1|]) =
  X [|(size X).-2|]

----------------------------------------------------------------------------- *)


      rewrite size_of_seq_of_distances; last by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 100)
  
  x1, x2 : nat
  xs : seq nat
  SIS : nondecreasing_sequence [:: x1, x2 & xs]
  X := [:: x1, x2 & xs] : seq nat
  ============================
  X [|(size (distances X) + 1).-1|] -
  (X [|size (distances X)|] - X [|(size (distances X)).-1|]) =
  X [|(size (distances X) + 1).-2|]

----------------------------------------------------------------------------- *)


      rewrite !addn1.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 104)
  
  x1, x2 : nat
  xs : seq nat
  SIS : nondecreasing_sequence [:: x1, x2 & xs]
  X := [:: x1, x2 & xs] : seq nat
  ============================
  X [|(size (distances X)).+1.-1|] -
  (X [|size (distances X)|] - X [|(size (distances X)).-1|]) =
  X [|(size (distances X)).+1.-2|]

----------------------------------------------------------------------------- *)


      rewrite -pred_Sn.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 108)
  
  x1, x2 : nat
  xs : seq nat
  SIS : nondecreasing_sequence [:: x1, x2 & xs]
  X := [:: x1, x2 & xs] : seq nat
  ============================
  X [|size (distances X)|] -
  (X [|size (distances X)|] - X [|(size (distances X)).-1|]) =
  X [|(size (distances X)).-1|]

----------------------------------------------------------------------------- *)


      rewrite subKn; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 114)
  
  x1, x2 : nat
  xs : seq nat
  SIS : nondecreasing_sequence [:: x1, x2 & xs]
  X := [:: x1, x2 & xs] : seq nat
  ============================
  X [|(size (distances X)).-1|] <= X [|size (distances X)|]

----------------------------------------------------------------------------- *)


      unfold X.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 115)
  
  x1, x2 : nat
  xs : seq nat
  SIS : nondecreasing_sequence [:: x1, x2 & xs]
  X := [:: x1, x2 & xs] : seq nat
  ============================
  [:: x1, x2 & xs] [|(size (distances [:: x1, x2 & xs])).-1|] <=
  [:: x1, x2 & xs] [|size (distances [:: x1, x2 & xs])|]

----------------------------------------------------------------------------- *)


      unfold nondecreasing_sequence in ×.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 117)
  
  x1, x2 : nat
  xs : seq nat
  SIS : forall n1 n2 : nat,
        n1 <= n2 < size [:: x1, x2 & xs] ->
        [:: x1, x2 & xs] [|n1|] <= [:: x1, x2 & xs] [|n2|]
  X := [:: x1, x2 & xs] : seq nat
  ============================
  [:: x1, x2 & xs] [|(size (distances [:: x1, x2 & xs])).-1|] <=
  [:: x1, x2 & xs] [|size (distances [:: x1, x2 & xs])|]

----------------------------------------------------------------------------- *)


      apply SIS.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 118)
  
  x1, x2 : nat
  xs : seq nat
  SIS : forall n1 n2 : nat,
        n1 <= n2 < size [:: x1, x2 & xs] ->
        [:: x1, x2 & xs] [|n1|] <= [:: x1, x2 & xs] [|n2|]
  X := [:: x1, x2 & xs] : seq nat
  ============================
  (size (distances [:: x1, x2 & xs])).-1 <=
  size (distances [:: x1, x2 & xs]) < size [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)


      apply/andP; split.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 144)
  
  x1, x2 : nat
  xs : seq nat
  SIS : forall n1 n2 : nat,
        n1 <= n2 < size [:: x1, x2 & xs] ->
        [:: x1, x2 & xs] [|n1|] <= [:: x1, x2 & xs] [|n2|]
  X := [:: x1, x2 & xs] : seq nat
  ============================
  (size (distances [:: x1, x2 & xs])).-1 <= size (distances [:: x1, x2 & xs])

subgoal 2 (ID 145) is:
 size (distances [:: x1, x2 & xs]) < size [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)


      simpl; by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 145)
  
  x1, x2 : nat
  xs : seq nat
  SIS : forall n1 n2 : nat,
        n1 <= n2 < size [:: x1, x2 & xs] ->
        [:: x1, x2 & xs] [|n1|] <= [:: x1, x2 & xs] [|n2|]
  X := [:: x1, x2 & xs] : seq nat
  ============================
  size (distances [:: x1, x2 & xs]) < size [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)


      rewrite [in X in _ < X]size_of_seq_of_distances; last by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 164)
  
  x1, x2 : nat
  xs : seq nat
  SIS : forall n1 n2 : nat,
        n1 <= n2 < size [:: x1, x2 & xs] ->
        [:: x1, x2 & xs] [|n1|] <= [:: x1, x2 & xs] [|n2|]
  X := [:: x1, x2 & xs] : seq nat
  ============================
  size (distances [:: x1, x2 & xs]) < size (distances [:: x1, x2 & xs]) + 1

----------------------------------------------------------------------------- *)


        by rewrite addn1.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    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].
    Lemma max_distance_in_seq_le_last_element_of_seq:
       (xs : seq nat),
        nondecreasing_sequence xs
        max0 (distances xs) last0 xs.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 36)
  
  ============================
  forall xs : seq nat,
  nondecreasing_sequence xs -> max0 (distances xs) <= last0 xs

----------------------------------------------------------------------------- *)


    Proof.
      intros.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 38)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  ============================
  max0 (distances xs) <= last0 xs

----------------------------------------------------------------------------- *)


      have SIZE: size xs < 2 2 size xs.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 41)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  ============================
  size xs < 2 \/ 1 < size xs

subgoal 2 (ID 43) is:
 max0 (distances xs) <= last0 xs

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 41)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  ============================
  size xs < 2 \/ 1 < size xs

----------------------------------------------------------------------------- *)


by destruct (size xs) as [ | n]; last destruct n; auto.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 43) is:
 max0 (distances xs) <= last0 xs

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 43)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE : size xs < 2 \/ 1 < size xs
  ============================
  max0 (distances xs) <= last0 xs

----------------------------------------------------------------------------- *)



      move: SIZE ⇒ [LT | SIZE2].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 113)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  LT : size xs < 2
  ============================
  max0 (distances xs) <= last0 xs

subgoal 2 (ID 114) is:
 max0 (distances xs) <= last0 xs

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 113)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  LT : size xs < 2
  ============================
  max0 (distances xs) <= last0 xs

----------------------------------------------------------------------------- *)


by destruct xs; last destruct xs.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 114) is:
 max0 (distances xs) <= last0 xs

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 114)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  ============================
  max0 (distances xs) <= last0 xs

----------------------------------------------------------------------------- *)



      apply leq_trans with (last0 xs - first0 xs); last by apply leq_subr.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 168)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  ============================
  max0 (distances xs) <= last0 xs - first0 xs

----------------------------------------------------------------------------- *)


      have F: xs c, ( x, x \in xs x c) max0 xs c.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 182)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  ============================
  forall (xs0 : seq_predType nat_eqType) (c : nat),
  (forall x : nat, x \in xs0 -> x <= c) -> max0 xs0 <= c

subgoal 2 (ID 184) is:
 max0 (distances xs) <= last0 xs - first0 xs

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 182)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  ============================
  forall (xs0 : seq_predType nat_eqType) (c : nat),
  (forall x : nat, x \in xs0 -> x <= c) -> max0 xs0 <= c

----------------------------------------------------------------------------- *)


clear; intros.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 188)
  
  xs : seq_predType nat_eqType
  c : nat
  H : forall x : nat, x \in xs -> x <= c
  ============================
  max0 xs <= c

----------------------------------------------------------------------------- *)


        induction xs; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 204)
  
  a : nat_eqType
  xs : seq nat_eqType
  c : nat
  H : forall x : nat, x \in a :: xs -> x <= c
  IHxs : (forall x : nat, x \in xs -> x <= c) -> max0 xs <= c
  ============================
  max0 (a :: xs) <= c

----------------------------------------------------------------------------- *)


        rewrite max0_cons geq_max; apply/andP; split.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 239)
  
  a : nat_eqType
  xs : seq nat_eqType
  c : nat
  H : forall x : nat, x \in a :: xs -> x <= c
  IHxs : (forall x : nat, x \in xs -> x <= c) -> max0 xs <= c
  ============================
  a <= c

subgoal 2 (ID 240) is:
 max0 xs <= c

----------------------------------------------------------------------------- *)


        + by apply H; rewrite in_cons; apply/orP; left.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 240)
  
  a : nat_eqType
  xs : seq nat_eqType
  c : nat
  H : forall x : nat, x \in a :: xs -> x <= c
  IHxs : (forall x : nat, x \in xs -> x <= c) -> max0 xs <= c
  ============================
  max0 xs <= c

----------------------------------------------------------------------------- *)


        + by apply IHxs; intros; apply H; rewrite in_cons; apply/orP; right.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 184) is:
 max0 (distances xs) <= last0 xs - first0 xs

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 184)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  F : forall (xs : seq_predType nat_eqType) (c : nat),
      (forall x : nat, x \in xs -> x <= c) -> max0 xs <= c
  ============================
  max0 (distances xs) <= last0 xs - first0 xs

----------------------------------------------------------------------------- *)


      apply F; clear F; intros d IN.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 313)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d : nat
  IN : d \in distances xs
  ============================
  d <= last0 xs - first0 xs

----------------------------------------------------------------------------- *)


      move: IN ⇒ /nthP T; specialize (T 0); move: T ⇒ [idx IN DIST].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 368)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  IN : idx < size (distances xs)
  DIST : distances xs [|idx|] = d
  ============================
  d <= last0 xs - first0 xs

----------------------------------------------------------------------------- *)


      rewrite function_of_distances_is_correct in DIST.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 386)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  IN : idx < size (distances xs)
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  ============================
  d <= last0 xs - first0 xs

----------------------------------------------------------------------------- *)


      rewrite -DIST.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 388)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  IN : idx < size (distances xs)
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  ============================
  xs [|idx.+1|] - xs [|idx|] <= last0 xs - first0 xs

----------------------------------------------------------------------------- *)


      rewrite leq_sub //.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 397)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  IN : idx < size (distances xs)
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  ============================
  xs [|idx.+1|] <= last0 xs

subgoal 2 (ID 398) is:
 first0 xs <= xs [|idx|]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 397)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  IN : idx < size (distances xs)
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  ============================
  xs [|idx.+1|] <= last0 xs

----------------------------------------------------------------------------- *)


destruct (xs [|idx.+1|] == last0 xs) eqn:EQ.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 452)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  IN : idx < size (distances xs)
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  EQ : (xs [|idx.+1|] == last0 xs) = true
  ============================
  xs [|idx.+1|] <= last0 xs

subgoal 2 (ID 453) is:
 xs [|idx.+1|] <= last0 xs

----------------------------------------------------------------------------- *)


        - by rewrite leq_eqVlt; apply/orP; left.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 453)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  IN : idx < size (distances xs)
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  EQ : (xs [|idx.+1|] == last0 xs) = false
  ============================
  xs [|idx.+1|] <= last0 xs

----------------------------------------------------------------------------- *)


        - rewrite /last0 -nth_last.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 489)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  IN : idx < size (distances xs)
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  EQ : (xs [|idx.+1|] == last0 xs) = false
  ============================
  xs [|idx.+1|] <= xs [|(size xs).-1|]

----------------------------------------------------------------------------- *)


apply H.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 490)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  IN : idx < size (distances xs)
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  EQ : (xs [|idx.+1|] == last0 xs) = false
  ============================
  idx < (size xs).-1 < size xs

----------------------------------------------------------------------------- *)


          rewrite -(ltn_add2r 1) addn1 -size_of_seq_of_distances in IN; last by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 517)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  EQ : (xs [|idx.+1|] == last0 xs) = false
  IN : idx.+1 < size xs
  ============================
  idx < (size xs).-1 < size xs

----------------------------------------------------------------------------- *)


          move: IN; rewrite leq_eqVlt; move ⇒ /orP [/eqP KK|KK].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 606)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  EQ : (xs [|idx.+1|] == last0 xs) = false
  KK : idx.+2 = size xs
  ============================
  idx < (size xs).-1 < size xs

subgoal 2 (ID 607) is:
 idx < (size xs).-1 < size xs

----------------------------------------------------------------------------- *)


          move: EQ; rewrite /last0 -nth_last -{1}KK -[_.+2.-1]pred_Sn; move ⇒ /eqP; by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 607)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  EQ : (xs [|idx.+1|] == last0 xs) = false
  KK : idx.+2 < size xs
  ============================
  idx < (size xs).-1 < size xs

----------------------------------------------------------------------------- *)


          apply/andP; split; first rewrite -(ltn_add2r 1) !addn1 prednK //.

(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 716)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  EQ : (xs [|idx.+1|] == last0 xs) = false
  KK : idx.+2 < size xs
  ============================
  idx.+1 < size xs

subgoal 2 (ID 717) is:
 0 < size xs
subgoal 3 (ID 701) is:
 (size xs).-1 < size xs

----------------------------------------------------------------------------- *)


          + by apply ltn_trans with idx.+2.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 717)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  EQ : (xs [|idx.+1|] == last0 xs) = false
  KK : idx.+2 < size xs
  ============================
  0 < size xs

subgoal 2 (ID 701) is:
 (size xs).-1 < size xs

----------------------------------------------------------------------------- *)


          + by apply ltnW.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 701)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  EQ : (xs [|idx.+1|] == last0 xs) = false
  KK : idx.+2 < size xs
  ============================
  (size xs).-1 < size xs

----------------------------------------------------------------------------- *)


          + by rewrite prednK //; apply ltn_trans with idx.+2.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 398) is:
 first0 xs <= xs [|idx|]

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 398)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  IN : idx < size (distances xs)
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  ============================
  first0 xs <= xs [|idx|]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 398)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  IN : idx < size (distances xs)
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  ============================
  first0 xs <= xs [|idx|]

----------------------------------------------------------------------------- *)


destruct (first0 xs == xs [|idx|]) eqn:EQ.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 802)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  IN : idx < size (distances xs)
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  EQ : (first0 xs == xs [|idx|]) = true
  ============================
  first0 xs <= xs [|idx|]

subgoal 2 (ID 803) is:
 first0 xs <= xs [|idx|]

----------------------------------------------------------------------------- *)


        - by rewrite leq_eqVlt; apply/orP; left.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 803)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  IN : idx < size (distances xs)
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  EQ : (first0 xs == xs [|idx|]) = false
  ============================
  first0 xs <= xs [|idx|]

----------------------------------------------------------------------------- *)


        - rewrite /first0 -nth0.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 839)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  IN : idx < size (distances xs)
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  EQ : (first0 xs == xs [|idx|]) = false
  ============================
  xs [|0|] <= xs [|idx|]

----------------------------------------------------------------------------- *)


apply H.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 840)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  IN : idx < size (distances xs)
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  EQ : (first0 xs == xs [|idx|]) = false
  ============================
  0 <= idx < size xs

----------------------------------------------------------------------------- *)


          rewrite -(ltn_add2r 1) addn1 -size_of_seq_of_distances in IN; last by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 867)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  DIST : xs [|idx.+1|] - xs [|idx|] = d
  EQ : (first0 xs == xs [|idx|]) = false
  IN : idx.+1 < size xs
  ============================
  0 <= idx < size xs

----------------------------------------------------------------------------- *)


          destruct idx; first by move: EQ; rewrite /first0 -nth0; move ⇒ /eqP.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 896)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  DIST : xs [|idx.+2|] - xs [|idx.+1|] = d
  EQ : (first0 xs == xs [|idx.+1|]) = false
  IN : idx.+2 < size xs
  ============================
  0 <= idx.+1 < size xs

----------------------------------------------------------------------------- *)


          apply/andP; split; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 984)
  
  xs : seq nat
  H : nondecreasing_sequence xs
  SIZE2 : 1 < size xs
  d, idx : nat
  DIST : xs [|idx.+2|] - xs [|idx.+1|] = d
  EQ : (first0 xs == xs [|idx.+1|]) = false
  IN : idx.+2 < size xs
  ============================
  idx.+1 < size xs

----------------------------------------------------------------------------- *)


            by apply ltn_trans with idx.+2.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

Let [xs] be a non-decreasing sequence. We prove that distances of sequence [[seq ρ <- index_iota 0 k.+1 | ρ \in xs]] coincide with sequence [[seq x <- distances xs | 0 < x]]].
    Lemma distances_iota_filtered:
       xs k,
        ( x, x \in xs x k)
        nondecreasing_sequence xs
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] = [seq x <- distances xs | 0 < x].
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 58)
  
  ============================
  forall (xs : seq_predType nat_eqType) (k : nat),
  (forall x : nat, x \in xs -> x <= k) ->
  nondecreasing_sequence xs ->
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
  [seq x <- distances xs | 0 < x]

----------------------------------------------------------------------------- *)


    Proof.
      intros xs.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 59)
  
  xs : seq_predType nat_eqType
  ============================
  forall k : nat,
  (forall x : nat, x \in xs -> x <= k) ->
  nondecreasing_sequence xs ->
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
  [seq x <- distances xs | 0 < x]

----------------------------------------------------------------------------- *)


      have EX: len, size xs len.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 64)
  
  xs : seq_predType nat_eqType
  ============================
  exists len : nat, size xs <= len

subgoal 2 (ID 66) is:
 forall k : nat,
 (forall x : nat, x \in xs -> x <= k) ->
 nondecreasing_sequence xs ->
 distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
 [seq x <- distances xs | 0 < x]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 64)
  
  xs : seq_predType nat_eqType
  ============================
  exists len : nat, size xs <= len

----------------------------------------------------------------------------- *)


(size xs); now simpl.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 66) is:
 forall k : nat,
 (forall x : nat, x \in xs -> x <= k) ->
 nondecreasing_sequence xs ->
 distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
 [seq x <- distances xs | 0 < x]

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 66)
  
  xs : seq_predType nat_eqType
  EX : exists len : nat, size xs <= len
  ============================
  forall k : nat,
  (forall x : nat, x \in xs -> x <= k) ->
  nondecreasing_sequence xs ->
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
  [seq x <- distances xs | 0 < x]

----------------------------------------------------------------------------- *)


destruct EX as [n BO].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 76)
  
  xs : seq_predType nat_eqType
  n : nat
  BO : size xs <= n
  ============================
  forall k : nat,
  (forall x : nat, x \in xs -> x <= k) ->
  nondecreasing_sequence xs ->
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
  [seq x <- distances xs | 0 < x]

----------------------------------------------------------------------------- *)


      revert xs BO; induction n.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 82)
  
  ============================
  forall xs : seq_predType nat_eqType,
  size xs <= 0 ->
  forall k : nat,
  (forall x : nat, x \in xs -> x <= k) ->
  nondecreasing_sequence xs ->
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
  [seq x <- distances xs | 0 < x]

subgoal 2 (ID 85) is:
 forall xs : seq_predType nat_eqType,
 size xs <= n.+1 ->
 forall k : nat,
 (forall x : nat, x \in xs -> x <= k) ->
 nondecreasing_sequence xs ->
 distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
 [seq x <- distances xs | 0 < x]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 82)
  
  ============================
  forall xs : seq_predType nat_eqType,
  size xs <= 0 ->
  forall k : nat,
  (forall x : nat, x \in xs -> x <= k) ->
  nondecreasing_sequence xs ->
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
  [seq x <- distances xs | 0 < x]

----------------------------------------------------------------------------- *)


intros ? Len k Bound NonDec.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 90)
  
  xs : seq_predType nat_eqType
  Len : size xs <= 0
  k : nat
  Bound : forall x : nat, x \in xs -> x <= k
  NonDec : nondecreasing_sequence xs
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
  [seq x <- distances xs | 0 < x]

----------------------------------------------------------------------------- *)


        move: Len; rewrite leqn0 size_eq0; move ⇒ /eqP T; subst.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 140)
  
  k : nat
  NonDec : nondecreasing_sequence [::]
  Bound : forall x : nat, x \in [::] -> x <= k
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in [::]] =
  [seq x <- distances [::] | 0 < x]

----------------------------------------------------------------------------- *)


          by rewrite filter_pred0.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 85) is:
 forall xs : seq_predType nat_eqType,
 size xs <= n.+1 ->
 forall k : nat,
 (forall x : nat, x \in xs -> x <= k) ->
 nondecreasing_sequence xs ->
 distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
 [seq x <- distances xs | 0 < x]

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 85)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  ============================
  forall xs : seq_predType nat_eqType,
  size xs <= n.+1 ->
  forall k : nat,
  (forall x : nat, x \in xs -> x <= k) ->
  nondecreasing_sequence xs ->
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
  [seq x <- distances xs | 0 < x]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 85)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  ============================
  forall xs : seq_predType nat_eqType,
  size xs <= n.+1 ->
  forall k : nat,
  (forall x : nat, x \in xs -> x <= k) ->
  nondecreasing_sequence xs ->
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
  [seq x <- distances xs | 0 < x]

----------------------------------------------------------------------------- *)


intros ? Len k Bound NonDec.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 149)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  xs : seq_predType nat_eqType
  Len : size xs <= n.+1
  k : nat
  Bound : forall x : nat, x \in xs -> x <= k
  NonDec : nondecreasing_sequence xs
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
  [seq x <- distances xs | 0 < x]

----------------------------------------------------------------------------- *)


        destruct xs as [ |x1 [ |x2 xs]].

(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 165)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  Len : size [::] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [::] -> x <= k
  NonDec : nondecreasing_sequence [::]
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in [::]] =
  [seq x <- distances [::] | 0 < x]

subgoal 2 (ID 177) is:
 distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1]] =
 [seq x <- distances [:: x1] | 0 < x]
subgoal 3 (ID 185) is:
 distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
 [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


        - by rewrite filter_pred0.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 177)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1 : nat_eqType
  Len : size [:: x1] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1] -> x <= k
  NonDec : nondecreasing_sequence [:: x1]
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1]] =
  [seq x <- distances [:: x1] | 0 < x]

subgoal 2 (ID 185) is:
 distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
 [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


        - by rewrite index_iota_filter_singl; last (rewrite ltnS; apply Bound; rewrite in_cons; apply/orP; left).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 185)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
  [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


        - have LEx1: x1 k.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 234)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  ============================
  x1 <= k

subgoal 2 (ID 236) is:
 distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
 [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


by apply Bound; rewrite in_cons eq_refl.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 236)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
  [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


          have LEx2: x2 k.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 248)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  ============================
  x2 <= k

subgoal 2 (ID 250) is:
 distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
 [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


by apply Bound; rewrite !in_cons eq_refl orbT.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 250)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
  [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


          have M1: y : nat, y \in x2 :: xs x1 y.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 280)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  ============================
  forall y : nat, y \in x2 :: xs -> x1 <= y

subgoal 2 (ID 282) is:
 distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
 [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


by apply nondecreasing_sequence_cons_min.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 282)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
  [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


          have M2: x : nat, x \in x2 :: xs x k.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 289)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  ============================
  forall x : nat, x \in x2 :: xs -> x <= k

subgoal 2 (ID 291) is:
 distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
 [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


by intros; apply Bound; rewrite in_cons; apply/orP; right.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 291)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
  [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


          have M3: y : nat, y \in xs x2 y
              by apply nondecreasing_sequence_cons in NonDec; apply nondecreasing_sequence_cons_min.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 336)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
  [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


          destruct (nondecreasing_sequence_2cons_leVeq _ _ _ NonDec).

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 349)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  H : x1 = x2
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
  [seq x <- distances [:: x1, x2 & xs] | 0 < x]

subgoal 2 (ID 350) is:
 distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
 [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


          + subst; rewrite distances_unfold_2cons.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 369)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x2, x2 & xs] <= n.+1
  k : nat
  LEx1 : x2 <= k
  NonDec : nondecreasing_sequence [:: x2, x2 & xs]
  Bound : forall x : nat, x \in [:: x2, x2 & xs] -> x <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x2 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x2, x2 & xs]] =
  [seq x <- x2 - x2 :: distances (x2 :: xs) | 0 < x]

subgoal 2 (ID 350) is:
 distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
 [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


            replace ((@filter nat (fun x : natleq (S O) x) (@cons nat (subn x2 x2) (distances (@cons nat x2 xs)))))
              with ([seq x <- distances (x2 :: xs) | 0 < x]); last by rewrite subnn.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 376)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x2, x2 & xs] <= n.+1
  k : nat
  LEx1 : x2 <= k
  NonDec : nondecreasing_sequence [:: x2, x2 & xs]
  Bound : forall x : nat, x \in [:: x2, x2 & xs] -> x <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x2 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x2, x2 & xs]] =
  [seq x <- distances (x2 :: xs) | 0 < x]

subgoal 2 (ID 350) is:
 distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
 [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


            rewrite range_filter_2cons.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 387)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x2, x2 & xs] <= n.+1
  k : nat
  LEx1 : x2 <= k
  NonDec : nondecreasing_sequence [:: x2, x2 & xs]
  Bound : forall x : nat, x \in [:: x2, x2 & xs] -> x <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x2 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  ============================
  distances [seq ρ <- range 0 k | ρ \in x2 :: xs] =
  [seq x <- distances (x2 :: xs) | 0 < x]

subgoal 2 (ID 350) is:
 distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
 [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


              by apply IHn; eauto 2 using nondecreasing_sequence_cons.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 350)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  H : x1 < x2
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
  [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


          + have M4: y : nat, y \in x2 :: xs x1 < y.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 404)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  H : x1 < x2
  ============================
  forall y : nat, y \in x2 :: xs -> x1 < y

subgoal 2 (ID 406) is:
 distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
 [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


by apply nondecreasing_sequence_cons_smin.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 406)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  H : x1 < x2
  M4 : forall y : nat, y \in x2 :: xs -> x1 < y
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
  [seq x <- distances [:: x1, x2 & xs] | 0 < x]

----------------------------------------------------------------------------- *)


            rewrite distances_unfold_2cons.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 413)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  H : x1 < x2
  M4 : forall y : nat, y \in x2 :: xs -> x1 < y
  ============================
  distances [seq ρ <- index_iota 0 k.+1 | ρ \in [:: x1, x2 & xs]] =
  [seq x <- x2 - x1 :: distances (x2 :: xs) | 0 < x]

----------------------------------------------------------------------------- *)


            rewrite range_iota_filter_step // rem_lt_id //.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 448)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  H : x1 < x2
  M4 : forall y : nat, y \in x2 :: xs -> x1 < y
  ============================
  distances (x1 :: [seq ρ <- range 0 k | ρ \in x2 :: xs]) =
  [seq x <- x2 - x1 :: distances (x2 :: xs) | 0 < x]

----------------------------------------------------------------------------- *)


            replace ((@filter nat (fun x : natleq (S O) x) (@cons nat (subn x2 x1) (distances (@cons nat x2 xs)))))
              with (x2 - x1 :: [seq x <- distances (x2 :: xs) | 0 < x]); last first.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 475)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  H : x1 < x2
  M4 : forall y : nat, y \in x2 :: xs -> x1 < y
  ============================
  x2 - x1 :: [seq x <- distances (x2 :: xs) | 0 < x] =
  [seq x <- x2 - x1 :: distances (x2 :: xs) | 0 < x]

subgoal 2 (ID 478) is:
 distances (x1 :: [seq ρ <- range 0 k | ρ \in x2 :: xs]) =
 x2 - x1 :: [seq x <- distances (x2 :: xs) | 0 < x]

----------------------------------------------------------------------------- *)


            {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 475)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  H : x1 < x2
  M4 : forall y : nat, y \in x2 :: xs -> x1 < y
  ============================
  x2 - x1 :: [seq x <- distances (x2 :: xs) | 0 < x] =
  [seq x <- x2 - x1 :: distances (x2 :: xs) | 0 < x]

----------------------------------------------------------------------------- *)


simpl; replace (0 < x2 - x1) with true; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 499)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  H : x1 < x2
  M4 : forall y : nat, y \in x2 :: xs -> x1 < y
  ============================
  true = (0 < x2 - x1)

----------------------------------------------------------------------------- *)


                by apply/eqP; rewrite eq_sym; rewrite eqb_id subn_gt0.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 478) is:
 distances (x1 :: [seq ρ <- range 0 k | ρ \in x2 :: xs]) =
 x2 - x1 :: [seq x <- distances (x2 :: xs) | 0 < x]

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 478)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  H : x1 < x2
  M4 : forall y : nat, y \in x2 :: xs -> x1 < y
  ============================
  distances (x1 :: [seq ρ <- range 0 k | ρ \in x2 :: xs]) =
  x2 - x1 :: [seq x <- distances (x2 :: xs) | 0 < x]

----------------------------------------------------------------------------- *)


            rewrite -(IHn _ _ k) //; last eapply nondecreasing_sequence_cons; eauto 2.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 582)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  H : x1 < x2
  M4 : forall y : nat, y \in x2 :: xs -> x1 < y
  ============================
  distances (x1 :: [seq ρ <- range 0 k | ρ \in x2 :: xs]) =
  x2 - x1 :: distances [seq ρ <- index_iota 0 k.+1 | ρ \in x2 :: xs]

----------------------------------------------------------------------------- *)


            rewrite {1}range_iota_filter_step //.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 640)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  H : x1 < x2
  M4 : forall y : nat, y \in x2 :: xs -> x1 < y
  ============================
  distances [:: x1, x2 & [seq ρ <- range 0 k | ρ \in rem_all x2 xs]] =
  x2 - x1 :: distances [seq ρ <- index_iota 0 k.+1 | ρ \in x2 :: xs]

----------------------------------------------------------------------------- *)


rewrite distances_unfold_2cons.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 668)
  
  n : nat
  IHn : forall xs : seq_predType nat_eqType,
        size xs <= n ->
        forall k : nat,
        (forall x : nat, x \in xs -> x <= k) ->
        nondecreasing_sequence xs ->
        distances [seq ρ <- index_iota 0 k.+1 | ρ \in xs] =
        [seq x <- distances xs | 0 < x]
  x1, x2 : nat_eqType
  xs : seq nat_eqType
  Len : size [:: x1, x2 & xs] <= n.+1
  k : nat
  Bound : forall x : nat, x \in [:: x1, x2 & xs] -> x <= k
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  LEx1 : x1 <= k
  LEx2 : x2 <= k
  M1 : forall y : nat, y \in x2 :: xs -> x1 <= y
  M2 : forall x : nat, x \in x2 :: xs -> x <= k
  M3 : forall y : nat, y \in xs -> x2 <= y
  H : x1 < x2
  M4 : forall y : nat, y \in x2 :: xs -> x1 < y
  ============================
  x2 - x1 :: distances (x2 :: [seq ρ <- range 0 k | ρ \in rem_all x2 xs]) =
  x2 - x1 :: distances [seq ρ <- index_iota 0 k.+1 | ρ \in x2 :: xs]

----------------------------------------------------------------------------- *)


rewrite {1}range_iota_filter_step //.
(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

Let [xs] again be a non-decreasing sequence. We prove that distances of sequence [undup xs] coincide with sequence of positive distances of [xs].
    Lemma distances_positive_undup:
       xs,
        nondecreasing_sequence xs
        [seq d <- distances xs | 0 < d] = distances (undup xs).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 64)
  
  ============================
  forall xs : seq nat,
  nondecreasing_sequence xs ->
  [seq d <- distances xs | 0 < d] = distances (undup xs)

----------------------------------------------------------------------------- *)


    Proof.
      intros ? NonDec.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 66)
  
  xs : seq nat
  NonDec : nondecreasing_sequence xs
  ============================
  [seq d <- distances xs | 0 < d] = distances (undup xs)

----------------------------------------------------------------------------- *)


      rewrite -(distances_iota_filtered _ (max0 xs)); [ | by apply in_max0_le | by done].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 74)
  
  xs : seq nat
  NonDec : nondecreasing_sequence xs
  ============================
  distances [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] =
  distances (undup xs)

----------------------------------------------------------------------------- *)


      enough ([seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = (undup xs)) as IN; first by rewrite IN.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 86)
  
  xs : seq nat
  NonDec : nondecreasing_sequence xs
  ============================
  [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs

----------------------------------------------------------------------------- *)


      have EX: len, size xs len.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 94)
  
  xs : seq nat
  NonDec : nondecreasing_sequence xs
  ============================
  exists len : nat, size xs <= len

subgoal 2 (ID 96) is:
 [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 94)
  
  xs : seq nat
  NonDec : nondecreasing_sequence xs
  ============================
  exists len : nat, size xs <= len

----------------------------------------------------------------------------- *)


(size xs); now simpl.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 96) is:
 [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs

----------------------------------------------------------------------------- *)


}
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 96)
  
  xs : seq nat
  NonDec : nondecreasing_sequence xs
  EX : exists len : nat, size xs <= len
  ============================
  [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs

----------------------------------------------------------------------------- *)


destruct EX as [n BO].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 105)
  
  xs : seq nat
  NonDec : nondecreasing_sequence xs
  n : nat
  BO : size xs <= n
  ============================
  [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs

----------------------------------------------------------------------------- *)


      revert xs NonDec BO; induction n.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 111)
  
  ============================
  forall xs : seq nat,
  nondecreasing_sequence xs ->
  size xs <= 0 -> [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs

subgoal 2 (ID 114) is:
 forall xs : seq nat,
 nondecreasing_sequence xs ->
 size xs <= n.+1 ->
 [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs

----------------------------------------------------------------------------- *)


      - intros xs _; rewrite leqn0 size_eq0; move ⇒ /eqP EQ; subst xs.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 159)
  
  ============================
  [seq ρ <- index_iota 0 (max0 [::]).+1 | ρ \in [::]] = undup [::]

subgoal 2 (ID 114) is:
 forall xs : seq nat,
 nondecreasing_sequence xs ->
 size xs <= n.+1 ->
 [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs

----------------------------------------------------------------------------- *)


          by rewrite filter_pred0.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 114)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  ============================
  forall xs : seq nat,
  nondecreasing_sequence xs ->
  size xs <= n.+1 ->
  [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs

----------------------------------------------------------------------------- *)


      - intros [ |x1 [ | x2 xs]].

(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 167)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  ============================
  nondecreasing_sequence [::] ->
  size [::] <= n.+1 ->
  [seq ρ <- index_iota 0 (max0 [::]).+1 | ρ \in [::]] = undup [::]

subgoal 2 (ID 173) is:
 nondecreasing_sequence [:: x1] ->
 size [:: x1] <= n.+1 ->
 [seq ρ <- index_iota 0 (max0 [:: x1]).+1 | ρ \in [:: x1]] = undup [:: x1]
subgoal 3 (ID 176) is:
 nondecreasing_sequence [:: x1, x2 & xs] ->
 size [:: x1, x2 & xs] <= n.+1 ->
 [seq ρ <- index_iota 0 (max0 [:: x1, x2 & xs]).+1 | ρ \in [:: x1, x2 & xs]] =
 undup [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)


        + by rewrite filter_pred0.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 173)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  x1 : nat
  ============================
  nondecreasing_sequence [:: x1] ->
  size [:: x1] <= n.+1 ->
  [seq ρ <- index_iota 0 (max0 [:: x1]).+1 | ρ \in [:: x1]] = undup [:: x1]

subgoal 2 (ID 176) is:
 nondecreasing_sequence [:: x1, x2 & xs] ->
 size [:: x1, x2 & xs] <= n.+1 ->
 [seq ρ <- index_iota 0 (max0 [:: x1, x2 & xs]).+1 | ρ \in [:: x1, x2 & xs]] =
 undup [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)


        + by rewrite index_iota_filter_singl ?L02 //; apply/andP; split; [ done | destruct x1].
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 176)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  x1, x2 : nat
  xs : seq nat
  ============================
  nondecreasing_sequence [:: x1, x2 & xs] ->
  size [:: x1, x2 & xs] <= n.+1 ->
  [seq ρ <- index_iota 0 (max0 [:: x1, x2 & xs]).+1 | ρ \in [:: x1, x2 & xs]] =
  undup [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)



        + intros NonDec Size.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 247)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  x1, x2 : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  Size : size [:: x1, x2 & xs] <= n.+1
  ============================
  [seq ρ <- index_iota 0 (max0 [:: x1, x2 & xs]).+1 | ρ \in [:: x1, x2 & xs]] =
  undup [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)



          destruct (nondecreasing_sequence_2cons_leVeq _ _ _ NonDec) as [EQ|LT].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 260)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  x1, x2 : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  Size : size [:: x1, x2 & xs] <= n.+1
  EQ : x1 = x2
  ============================
  [seq ρ <- index_iota 0 (max0 [:: x1, x2 & xs]).+1 | ρ \in [:: x1, x2 & xs]] =
  undup [:: x1, x2 & xs]

subgoal 2 (ID 261) is:
 [seq ρ <- index_iota 0 (max0 [:: x1, x2 & xs]).+1 | ρ \in [:: x1, x2 & xs]] =
 undup [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)


          × subst; rename x2 into x.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 270)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  x : nat
  xs : seq nat
  Size : size [:: x, x & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x, x & xs]
  ============================
  [seq ρ <- index_iota 0 (max0 [:: x, x & xs]).+1 | ρ \in [:: x, x & xs]] =
  undup [:: x, x & xs]

subgoal 2 (ID 261) is:
 [seq ρ <- index_iota 0 (max0 [:: x1, x2 & xs]).+1 | ρ \in [:: x1, x2 & xs]] =
 undup [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)


            rewrite nodup_sort_2cons_eq range_filter_2cons max0_2cons_eq.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 285)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  x : nat
  xs : seq nat
  Size : size [:: x, x & xs] <= n.+1
  NonDec : nondecreasing_sequence [:: x, x & xs]
  ============================
  [seq ρ <- range 0 (max0 (x :: xs)) | ρ \in x :: xs] = undup (x :: xs)

subgoal 2 (ID 261) is:
 [seq ρ <- index_iota 0 (max0 [:: x1, x2 & xs]).+1 | ρ \in [:: x1, x2 & xs]] =
 undup [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)


              by apply IHn; [ eapply nondecreasing_sequence_cons; eauto | by done].
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 261)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  x1, x2 : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  Size : size [:: x1, x2 & xs] <= n.+1
  LT : x1 < x2
  ============================
  [seq ρ <- index_iota 0 (max0 [:: x1, x2 & xs]).+1 | ρ \in [:: x1, x2 & xs]] =
  undup [:: x1, x2 & xs]

----------------------------------------------------------------------------- *)


          × rewrite nodup_sort_2cons_lt // max0_2cons_le; last by rewrite ltnW.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 325)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  x1, x2 : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  Size : size [:: x1, x2 & xs] <= n.+1
  LT : x1 < x2
  ============================
  [seq ρ <- index_iota 0 (max0 (x2 :: xs)).+1 | ρ \in [:: x1, x2 & xs]] =
  x1 :: undup (x2 :: xs)

----------------------------------------------------------------------------- *)


            rewrite index_iota_filter_step; [ | | by apply nondecreasing_sequence_cons_min]; last first.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 341)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  x1, x2 : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  Size : size [:: x1, x2 & xs] <= n.+1
  LT : x1 < x2
  ============================
  0 <= x1 < (max0 (x2 :: xs)).+1

subgoal 2 (ID 340) is:
 x1
 :: [seq ρ <- index_iota 0 (max0 (x2 :: xs)).+1
       | ρ \in rem_all x1 (x2 :: xs)] = x1 :: undup (x2 :: xs)

----------------------------------------------------------------------------- *)


            {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 341)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  x1, x2 : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  Size : size [:: x1, x2 & xs] <= n.+1
  LT : x1 < x2
  ============================
  0 <= x1 < (max0 (x2 :: xs)).+1

----------------------------------------------------------------------------- *)


apply/andP; split; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 370)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  x1, x2 : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  Size : size [:: x1, x2 & xs] <= n.+1
  LT : x1 < x2
  ============================
  x1 < (max0 (x2 :: xs)).+1

----------------------------------------------------------------------------- *)


              eapply leq_trans; first by eassumption.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 373)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  x1, x2 : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  Size : size [:: x1, x2 & xs] <= n.+1
  LT : x1 < x2
  ============================
  x2 <= (max0 (x2 :: xs)).+1

----------------------------------------------------------------------------- *)


              rewrite ltnW // ltnS; apply in_max0_le.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 405)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  x1, x2 : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  Size : size [:: x1, x2 & xs] <= n.+1
  LT : x1 < x2
  ============================
  x2 \in x2 :: xs

----------------------------------------------------------------------------- *)


                by rewrite in_cons eq_refl.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 340) is:
 x1
 :: [seq ρ <- index_iota 0 (max0 (x2 :: xs)).+1
       | ρ \in rem_all x1 (x2 :: xs)] = x1 :: undup (x2 :: xs)

----------------------------------------------------------------------------- *)


            }

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 340)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  x1, x2 : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  Size : size [:: x1, x2 & xs] <= n.+1
  LT : x1 < x2
  ============================
  x1
  :: [seq ρ <- index_iota 0 (max0 (x2 :: xs)).+1
        | ρ \in rem_all x1 (x2 :: xs)] = x1 :: undup (x2 :: xs)

----------------------------------------------------------------------------- *)


            rewrite rem_lt_id //; last by apply nondecreasing_sequence_cons_smin.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 420)
  
  n : nat
  IHn : forall xs : seq nat,
        nondecreasing_sequence xs ->
        size xs <= n ->
        [seq ρ <- index_iota 0 (max0 xs).+1 | ρ \in xs] = undup xs
  x1, x2 : nat
  xs : seq nat
  NonDec : nondecreasing_sequence [:: x1, x2 & xs]
  Size : size [:: x1, x2 & xs] <= n.+1
  LT : x1 < x2
  ============================
  x1 :: [seq ρ <- index_iota 0 (max0 (x2 :: xs)).+1 | ρ \in x2 :: xs] =
  x1 :: undup (x2 :: xs)

----------------------------------------------------------------------------- *)


            rewrite IHn //; eauto using nondecreasing_sequence_cons.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    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].
    Lemma domination_of_distances_implies_domination_of_seq:
       (xs ys : seq nat),
        first0 xs first0 ys
        2 size xs
        2 size ys
        size xs = size ys
        nondecreasing_sequence xs
        nondecreasing_sequence ys
        ( n, (distances xs)[|n|] (distances ys)[|n|])
        ( n, xs[|n|] ys[|n|]).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 76)
  
  ============================
  forall xs ys : seq nat,
  first0 xs <= first0 ys ->
  1 < size xs ->
  1 < size ys ->
  size xs = size ys ->
  nondecreasing_sequence xs ->
  nondecreasing_sequence ys ->
  (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
  forall n : nat, xs [|n|] <= ys [|n|]

----------------------------------------------------------------------------- *)


    Proof.
      intros xs ys.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 78)
  
  xs, ys : seq nat
  ============================
  first0 xs <= first0 ys ->
  1 < size xs ->
  1 < size ys ->
  size xs = size ys ->
  nondecreasing_sequence xs ->
  nondecreasing_sequence ys ->
  (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
  forall n : nat, xs [|n|] <= ys [|n|]

----------------------------------------------------------------------------- *)


      have EX: len, size xs len size ys len.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 83)
  
  xs, ys : seq nat
  ============================
  exists len : nat, size xs <= len /\ size ys <= len

subgoal 2 (ID 85) is:
 first0 xs <= first0 ys ->
 1 < size xs ->
 1 < size ys ->
 size xs = size ys ->
 nondecreasing_sequence xs ->
 nondecreasing_sequence ys ->
 (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
 forall n : nat, xs [|n|] <= ys [|n|]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 83)
  
  xs, ys : seq nat
  ============================
  exists len : nat, size xs <= len /\ size ys <= len

----------------------------------------------------------------------------- *)


(maxn (size xs) (size ys)).

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 89)
  
  xs, ys : seq nat
  ============================
  size xs <= maxn (size xs) (size ys) /\ size ys <= maxn (size xs) (size ys)

----------------------------------------------------------------------------- *)


          by split; rewrite leq_max; apply/orP; [left | right].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 85) is:
 first0 xs <= first0 ys ->
 1 < size xs ->
 1 < size ys ->
 size xs = size ys ->
 nondecreasing_sequence xs ->
 nondecreasing_sequence ys ->
 (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
 forall n : nat, xs [|n|] <= ys [|n|]

----------------------------------------------------------------------------- *)


      }
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 85)
  
  xs, ys : seq nat
  EX : exists len : nat, size xs <= len /\ size ys <= len
  ============================
  first0 xs <= first0 ys ->
  1 < size xs ->
  1 < size ys ->
  size xs = size ys ->
  nondecreasing_sequence xs ->
  nondecreasing_sequence ys ->
  (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
  forall n : nat, xs [|n|] <= ys [|n|]

----------------------------------------------------------------------------- *)


move: EX ⇒ [len [LE1 LE2]].
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 177)
  
  xs, ys : seq nat
  len : nat
  LE1 : size xs <= len
  LE2 : size ys <= len
  ============================
  first0 xs <= first0 ys ->
  1 < size xs ->
  1 < size ys ->
  size xs = size ys ->
  nondecreasing_sequence xs ->
  nondecreasing_sequence ys ->
  (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
  forall n : nat, xs [|n|] <= ys [|n|]

----------------------------------------------------------------------------- *)


      generalize dependent xs; generalize dependent ys.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 181)
  
  len : nat
  ============================
  forall ys : seq nat,
  size ys <= len ->
  forall xs : seq nat,
  size xs <= len ->
  first0 xs <= first0 ys ->
  1 < size xs ->
  1 < size ys ->
  size xs = size ys ->
  nondecreasing_sequence xs ->
  nondecreasing_sequence ys ->
  (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
  forall n : nat, xs [|n|] <= ys [|n|]

----------------------------------------------------------------------------- *)


      induction len.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 185)
  
  ============================
  forall ys : seq nat,
  size ys <= 0 ->
  forall xs : seq nat,
  size xs <= 0 ->
  first0 xs <= first0 ys ->
  1 < size xs ->
  1 < size ys ->
  size xs = size ys ->
  nondecreasing_sequence xs ->
  nondecreasing_sequence ys ->
  (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
  forall n : nat, xs [|n|] <= ys [|n|]

subgoal 2 (ID 188) is:
 forall ys : seq nat,
 size ys <= len.+1 ->
 forall xs : seq nat,
 size xs <= len.+1 ->
 first0 xs <= first0 ys ->
 1 < size xs ->
 1 < size ys ->
 size xs = size ys ->
 nondecreasing_sequence xs ->
 nondecreasing_sequence ys ->
 (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
 forall n : nat, xs [|n|] <= ys [|n|]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 185)
  
  ============================
  forall ys : seq nat,
  size ys <= 0 ->
  forall xs : seq nat,
  size xs <= 0 ->
  first0 xs <= first0 ys ->
  1 < size xs ->
  1 < size ys ->
  size xs = size ys ->
  nondecreasing_sequence xs ->
  nondecreasing_sequence ys ->
  (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
  forall n : nat, xs [|n|] <= ys [|n|]

----------------------------------------------------------------------------- *)


intros; move: LE1 LE2; rewrite !leqn0 !size_eq0; move ⇒ /eqP E1 /eqP E2.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 286)
  
  ys, xs : seq nat
  H : first0 xs <= first0 ys
  H0 : 1 < size xs
  H1 : 1 < size ys
  H2 : size xs = size ys
  H3 : nondecreasing_sequence xs
  H4 : nondecreasing_sequence ys
  H5 : forall n : nat, distances xs [|n|] <= distances ys [|n|]
  n : nat
  E1 : xs = [::]
  E2 : ys = [::]
  ============================
  xs [|n|] <= ys [|n|]

----------------------------------------------------------------------------- *)


          by subst.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 188) is:
 forall ys : seq nat,
 size ys <= len.+1 ->
 forall xs : seq nat,
 size xs <= len.+1 ->
 first0 xs <= first0 ys ->
 1 < size xs ->
 1 < size ys ->
 size xs = size ys ->
 nondecreasing_sequence xs ->
 nondecreasing_sequence ys ->
 (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
 forall n : nat, xs [|n|] <= ys [|n|]

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 188)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  ============================
  forall ys : seq nat,
  size ys <= len.+1 ->
  forall xs : seq nat,
  size xs <= len.+1 ->
  first0 xs <= first0 ys ->
  1 < size xs ->
  1 < size ys ->
  size xs = size ys ->
  nondecreasing_sequence xs ->
  nondecreasing_sequence ys ->
  (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
  forall n : nat, xs [|n|] <= ys [|n|]

----------------------------------------------------------------------------- *)


      {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 188)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  ============================
  forall ys : seq nat,
  size ys <= len.+1 ->
  forall xs : seq nat,
  size xs <= len.+1 ->
  first0 xs <= first0 ys ->
  1 < size xs ->
  1 < size ys ->
  size xs = size ys ->
  nondecreasing_sequence xs ->
  nondecreasing_sequence ys ->
  (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
  forall n : nat, xs [|n|] <= ys [|n|]

----------------------------------------------------------------------------- *)


intros ? LycSIZE ? LxSIZE FLE Sxs Sys SIZEEQ STRxs STRys LE n.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 326)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  ys : seq nat
  LycSIZE : size ys <= len.+1
  xs : seq nat
  LxSIZE : size xs <= len.+1
  FLE : first0 xs <= first0 ys
  Sxs : 1 < size xs
  Sys : 1 < size ys
  SIZEEQ : size xs = size ys
  STRxs : nondecreasing_sequence xs
  STRys : nondecreasing_sequence ys
  LE : forall n : nat, distances xs [|n|] <= distances ys [|n|]
  n : nat
  ============================
  xs [|n|] <= ys [|n|]

----------------------------------------------------------------------------- *)


        destruct xs as [ | x1 xs], ys as [ | y1 ys]; try by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 464)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1 : nat
  ys : seq nat
  LycSIZE : size (y1 :: ys) <= len.+1
  x1 : nat
  xs : seq nat
  LxSIZE : size (x1 :: xs) <= len.+1
  FLE : first0 (x1 :: xs) <= first0 (y1 :: ys)
  Sxs : 1 < size (x1 :: xs)
  Sys : 1 < size (y1 :: ys)
  SIZEEQ : size (x1 :: xs) = size (y1 :: ys)
  STRxs : nondecreasing_sequence (x1 :: xs)
  STRys : nondecreasing_sequence (y1 :: ys)
  LE : forall n : nat,
       distances (x1 :: xs) [|n|] <= distances (y1 :: ys) [|n|]
  n : nat
  ============================
  (x1 :: xs) [|n|] <= (y1 :: ys) [|n|]

----------------------------------------------------------------------------- *)


        destruct xs as [ | x2 xs], ys as [ | y2 ys]; try by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 665)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2 & ys] <= len.+1
  x1, x2 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2 & xs] <= len.+1
  FLE : first0 [:: x1, x2 & xs] <= first0 [:: y1, y2 & ys]
  Sxs : 1 < size [:: x1, x2 & xs]
  Sys : 1 < size [:: y1, y2 & ys]
  SIZEEQ : size [:: x1, x2 & xs] = size [:: y1, y2 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2 & xs]
  STRys : nondecreasing_sequence [:: y1, y2 & ys]
  LE : forall n : nat,
       distances [:: x1, x2 & xs] [|n|] <= distances [:: y1, y2 & ys] [|n|]
  n : nat
  ============================
  [:: x1, x2 & xs] [|n|] <= [:: y1, y2 & ys] [|n|]

----------------------------------------------------------------------------- *)


        have F: x2 y2.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 750)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2 & ys] <= len.+1
  x1, x2 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2 & xs] <= len.+1
  FLE : first0 [:: x1, x2 & xs] <= first0 [:: y1, y2 & ys]
  Sxs : 1 < size [:: x1, x2 & xs]
  Sys : 1 < size [:: y1, y2 & ys]
  SIZEEQ : size [:: x1, x2 & xs] = size [:: y1, y2 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2 & xs]
  STRys : nondecreasing_sequence [:: y1, y2 & ys]
  LE : forall n : nat,
       distances [:: x1, x2 & xs] [|n|] <= distances [:: y1, y2 & ys] [|n|]
  n : nat
  ============================
  x2 <= y2

subgoal 2 (ID 752) is:
 [:: x1, x2 & xs] [|n|] <= [:: y1, y2 & ys] [|n|]

----------------------------------------------------------------------------- *)


        {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 750)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2 & ys] <= len.+1
  x1, x2 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2 & xs] <= len.+1
  FLE : first0 [:: x1, x2 & xs] <= first0 [:: y1, y2 & ys]
  Sxs : 1 < size [:: x1, x2 & xs]
  Sys : 1 < size [:: y1, y2 & ys]
  SIZEEQ : size [:: x1, x2 & xs] = size [:: y1, y2 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2 & xs]
  STRys : nondecreasing_sequence [:: y1, y2 & ys]
  LE : forall n : nat,
       distances [:: x1, x2 & xs] [|n|] <= distances [:: y1, y2 & ys] [|n|]
  n : nat
  ============================
  x2 <= y2

----------------------------------------------------------------------------- *)


specialize (STRxs 0 1); feed STRxs; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 760)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2 & ys] <= len.+1
  x1, x2 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2 & xs] <= len.+1
  FLE : first0 [:: x1, x2 & xs] <= first0 [:: y1, y2 & ys]
  Sxs : 1 < size [:: x1, x2 & xs]
  Sys : 1 < size [:: y1, y2 & ys]
  SIZEEQ : size [:: x1, x2 & xs] = size [:: y1, y2 & ys]
  STRxs : [:: x1, x2 & xs] [|0|] <= [:: x1, x2 & xs] [|1|]
  STRys : nondecreasing_sequence [:: y1, y2 & ys]
  LE : forall n : nat,
       distances [:: x1, x2 & xs] [|n|] <= distances [:: y1, y2 & ys] [|n|]
  n : nat
  ============================
  x2 <= y2

----------------------------------------------------------------------------- *)


          specialize (STRys 0 1); feed STRys; first by done.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 768)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2 & ys] <= len.+1
  x1, x2 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2 & xs] <= len.+1
  FLE : first0 [:: x1, x2 & xs] <= first0 [:: y1, y2 & ys]
  Sxs : 1 < size [:: x1, x2 & xs]
  Sys : 1 < size [:: y1, y2 & ys]
  SIZEEQ : size [:: x1, x2 & xs] = size [:: y1, y2 & ys]
  STRxs : [:: x1, x2 & xs] [|0|] <= [:: x1, x2 & xs] [|1|]
  STRys : [:: y1, y2 & ys] [|0|] <= [:: y1, y2 & ys] [|1|]
  LE : forall n : nat,
       distances [:: x1, x2 & xs] [|n|] <= distances [:: y1, y2 & ys] [|n|]
  n : nat
  ============================
  x2 <= y2

----------------------------------------------------------------------------- *)


          specialize (LE 0); simpl in LE, FLE.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 781)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2 & ys] <= len.+1
  x1, x2 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2 & xs] <= len.+1
  FLE : x1 <= y1
  Sxs : 1 < size [:: x1, x2 & xs]
  Sys : 1 < size [:: y1, y2 & ys]
  SIZEEQ : size [:: x1, x2 & xs] = size [:: y1, y2 & ys]
  STRxs : [:: x1, x2 & xs] [|0|] <= [:: x1, x2 & xs] [|1|]
  STRys : [:: y1, y2 & ys] [|0|] <= [:: y1, y2 & ys] [|1|]
  LE : x2 - x1 <= y2 - y1
  n : nat
  ============================
  x2 <= y2

----------------------------------------------------------------------------- *)


          rewrite leqNgt; apply/negP; intros NEQ.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 807)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2 & ys] <= len.+1
  x1, x2 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2 & xs] <= len.+1
  FLE : x1 <= y1
  Sxs : 1 < size [:: x1, x2 & xs]
  Sys : 1 < size [:: y1, y2 & ys]
  SIZEEQ : size [:: x1, x2 & xs] = size [:: y1, y2 & ys]
  STRxs : [:: x1, x2 & xs] [|0|] <= [:: x1, x2 & xs] [|1|]
  STRys : [:: y1, y2 & ys] [|0|] <= [:: y1, y2 & ys] [|1|]
  LE : x2 - x1 <= y2 - y1
  n : nat
  NEQ : y2 < x2
  ============================
  False

----------------------------------------------------------------------------- *)


          move: LE; rewrite leqNgt; move ⇒ /negP LE; apply: LE.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 844)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2 & ys] <= len.+1
  x1, x2 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2 & xs] <= len.+1
  FLE : x1 <= y1
  Sxs : 1 < size [:: x1, x2 & xs]
  Sys : 1 < size [:: y1, y2 & ys]
  SIZEEQ : size [:: x1, x2 & xs] = size [:: y1, y2 & ys]
  STRxs : [:: x1, x2 & xs] [|0|] <= [:: x1, x2 & xs] [|1|]
  STRys : [:: y1, y2 & ys] [|0|] <= [:: y1, y2 & ys] [|1|]
  n : nat
  NEQ : y2 < x2
  ============================
  y2 - y1 < x2 - x1

----------------------------------------------------------------------------- *)


          rewrite -(ltn_add2r x1) subnK // subh1 // -(ltn_add2r y1) subnK.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 912)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2 & ys] <= len.+1
  x1, x2 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2 & xs] <= len.+1
  FLE : x1 <= y1
  Sxs : 1 < size [:: x1, x2 & xs]
  Sys : 1 < size [:: y1, y2 & ys]
  SIZEEQ : size [:: x1, x2 & xs] = size [:: y1, y2 & ys]
  STRxs : [:: x1, x2 & xs] [|0|] <= [:: x1, x2 & xs] [|1|]
  STRys : [:: y1, y2 & ys] [|0|] <= [:: y1, y2 & ys] [|1|]
  n : nat
  NEQ : y2 < x2
  ============================
  y2 + x1 < x2 + y1

subgoal 2 (ID 913) is:
 y1 <= y2 + x1

----------------------------------------------------------------------------- *)


          - by eapply leq_ltn_trans; [erewrite leq_add2l | erewrite ltn_add2r].

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 913)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2 & ys] <= len.+1
  x1, x2 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2 & xs] <= len.+1
  FLE : x1 <= y1
  Sxs : 1 < size [:: x1, x2 & xs]
  Sys : 1 < size [:: y1, y2 & ys]
  SIZEEQ : size [:: x1, x2 & xs] = size [:: y1, y2 & ys]
  STRxs : [:: x1, x2 & xs] [|0|] <= [:: x1, x2 & xs] [|1|]
  STRys : [:: y1, y2 & ys] [|0|] <= [:: y1, y2 & ys] [|1|]
  n : nat
  NEQ : y2 < x2
  ============================
  y1 <= y2 + x1

----------------------------------------------------------------------------- *)


          - by apply leq_trans with y2; auto using leq_addr.

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 752) is:
 [:: x1, x2 & xs] [|n|] <= [:: y1, y2 & ys] [|n|]

----------------------------------------------------------------------------- *)


        }

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 752)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2 & ys] <= len.+1
  x1, x2 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2 & xs] <= len.+1
  FLE : first0 [:: x1, x2 & xs] <= first0 [:: y1, y2 & ys]
  Sxs : 1 < size [:: x1, x2 & xs]
  Sys : 1 < size [:: y1, y2 & ys]
  SIZEEQ : size [:: x1, x2 & xs] = size [:: y1, y2 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2 & xs]
  STRys : nondecreasing_sequence [:: y1, y2 & ys]
  LE : forall n : nat,
       distances [:: x1, x2 & xs] [|n|] <= distances [:: y1, y2 & ys] [|n|]
  n : nat
  F : x2 <= y2
  ============================
  [:: x1, x2 & xs] [|n|] <= [:: y1, y2 & ys] [|n|]

----------------------------------------------------------------------------- *)


        destruct xs as [ | x3 xs], ys as [ | y3 ys]; try by done.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 998)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2 : nat
  LycSIZE : size [:: y1; y2] <= len.+1
  x1, x2 : nat
  LxSIZE : size [:: x1; x2] <= len.+1
  FLE : first0 [:: x1; x2] <= first0 [:: y1; y2]
  Sxs : 1 < size [:: x1; x2]
  Sys : 1 < size [:: y1; y2]
  SIZEEQ : size [:: x1; x2] = size [:: y1; y2]
  STRxs : nondecreasing_sequence [:: x1; x2]
  STRys : nondecreasing_sequence [:: y1; y2]
  LE : forall n : nat,
       distances [:: x1; x2] [|n|] <= distances [:: y1; y2] [|n|]
  n : nat
  F : x2 <= y2
  ============================
  [:: x1; x2] [|n|] <= [:: y1; y2] [|n|]

subgoal 2 (ID 1060) is:
 [:: x1, x2, x3 & xs] [|n|] <= [:: y1, y2, y3 & ys] [|n|]

----------------------------------------------------------------------------- *)


        {
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 998)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2 : nat
  LycSIZE : size [:: y1; y2] <= len.+1
  x1, x2 : nat
  LxSIZE : size [:: x1; x2] <= len.+1
  FLE : first0 [:: x1; x2] <= first0 [:: y1; y2]
  Sxs : 1 < size [:: x1; x2]
  Sys : 1 < size [:: y1; y2]
  SIZEEQ : size [:: x1; x2] = size [:: y1; y2]
  STRxs : nondecreasing_sequence [:: x1; x2]
  STRys : nondecreasing_sequence [:: y1; y2]
  LE : forall n : nat,
       distances [:: x1; x2] [|n|] <= distances [:: y1; y2] [|n|]
  n : nat
  F : x2 <= y2
  ============================
  [:: x1; x2] [|n|] <= [:: y1; y2] [|n|]

----------------------------------------------------------------------------- *)


by destruct n; [ | destruct n].
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal

subgoal 1 (ID 1060) is:
 [:: x1, x2, x3 & xs] [|n|] <= [:: y1, y2, y3 & ys] [|n|]

----------------------------------------------------------------------------- *)


}

(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 1060)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2, y3 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2, y3 & ys] <= len.+1
  x1, x2, x3 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2, x3 & xs] <= len.+1
  FLE : first0 [:: x1, x2, x3 & xs] <= first0 [:: y1, y2, y3 & ys]
  Sxs : 1 < size [:: x1, x2, x3 & xs]
  Sys : 1 < size [:: y1, y2, y3 & ys]
  SIZEEQ : size [:: x1, x2, x3 & xs] = size [:: y1, y2, y3 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2, x3 & xs]
  STRys : nondecreasing_sequence [:: y1, y2, y3 & ys]
  LE : forall n : nat,
       distances [:: x1, x2, x3 & xs] [|n|] <=
       distances [:: y1, y2, y3 & ys] [|n|]
  n : nat
  F : x2 <= y2
  ============================
  [:: x1, x2, x3 & xs] [|n|] <= [:: y1, y2, y3 & ys] [|n|]

----------------------------------------------------------------------------- *)


        destruct n; first by done.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 1165)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2, y3 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2, y3 & ys] <= len.+1
  x1, x2, x3 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2, x3 & xs] <= len.+1
  FLE : first0 [:: x1, x2, x3 & xs] <= first0 [:: y1, y2, y3 & ys]
  Sxs : 1 < size [:: x1, x2, x3 & xs]
  Sys : 1 < size [:: y1, y2, y3 & ys]
  SIZEEQ : size [:: x1, x2, x3 & xs] = size [:: y1, y2, y3 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2, x3 & xs]
  STRys : nondecreasing_sequence [:: y1, y2, y3 & ys]
  LE : forall n : nat,
       distances [:: x1, x2, x3 & xs] [|n|] <=
       distances [:: y1, y2, y3 & ys] [|n|]
  n : nat
  F : x2 <= y2
  ============================
  [:: x1, x2, x3 & xs] [|n.+1|] <= [:: y1, y2, y3 & ys] [|n.+1|]

----------------------------------------------------------------------------- *)


        simpl; apply IHlen; try done.
(* ----------------------------------[ coqtop ]---------------------------------

4 subgoals (ID 1174)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2, y3 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2, y3 & ys] <= len.+1
  x1, x2, x3 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2, x3 & xs] <= len.+1
  FLE : first0 [:: x1, x2, x3 & xs] <= first0 [:: y1, y2, y3 & ys]
  Sxs : 1 < size [:: x1, x2, x3 & xs]
  Sys : 1 < size [:: y1, y2, y3 & ys]
  SIZEEQ : size [:: x1, x2, x3 & xs] = size [:: y1, y2, y3 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2, x3 & xs]
  STRys : nondecreasing_sequence [:: y1, y2, y3 & ys]
  LE : forall n : nat,
       distances [:: x1, x2, x3 & xs] [|n|] <=
       distances [:: y1, y2, y3 & ys] [|n|]
  n : nat
  F : x2 <= y2
  ============================
  size [:: x2, x3 & xs] = size [:: y2, y3 & ys]

subgoal 2 (ID 1175) is:
 nondecreasing_sequence [:: x2, x3 & xs]
subgoal 3 (ID 1176) is:
 nondecreasing_sequence [:: y2, y3 & ys]
subgoal 4 (ID 1177) is:
 forall n0 : nat,
 distances [:: x2, x3 & xs] [|n0|] <= distances [:: y2, y3 & ys] [|n0|]

----------------------------------------------------------------------------- *)


        - by apply/eqP; rewrite -(eqn_add2r 1) !addn1; apply/eqP.

(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 1175)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2, y3 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2, y3 & ys] <= len.+1
  x1, x2, x3 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2, x3 & xs] <= len.+1
  FLE : first0 [:: x1, x2, x3 & xs] <= first0 [:: y1, y2, y3 & ys]
  Sxs : 1 < size [:: x1, x2, x3 & xs]
  Sys : 1 < size [:: y1, y2, y3 & ys]
  SIZEEQ : size [:: x1, x2, x3 & xs] = size [:: y1, y2, y3 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2, x3 & xs]
  STRys : nondecreasing_sequence [:: y1, y2, y3 & ys]
  LE : forall n : nat,
       distances [:: x1, x2, x3 & xs] [|n|] <=
       distances [:: y1, y2, y3 & ys] [|n|]
  n : nat
  F : x2 <= y2
  ============================
  nondecreasing_sequence [:: x2, x3 & xs]

subgoal 2 (ID 1176) is:
 nondecreasing_sequence [:: y2, y3 & ys]
subgoal 3 (ID 1177) is:
 forall n0 : nat,
 distances [:: x2, x3 & xs] [|n0|] <= distances [:: y2, y3 & ys] [|n0|]

----------------------------------------------------------------------------- *)


        - movem1 m2 /andP [B1 B2].

(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 1405)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2, y3 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2, y3 & ys] <= len.+1
  x1, x2, x3 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2, x3 & xs] <= len.+1
  FLE : first0 [:: x1, x2, x3 & xs] <= first0 [:: y1, y2, y3 & ys]
  Sxs : 1 < size [:: x1, x2, x3 & xs]
  Sys : 1 < size [:: y1, y2, y3 & ys]
  SIZEEQ : size [:: x1, x2, x3 & xs] = size [:: y1, y2, y3 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2, x3 & xs]
  STRys : nondecreasing_sequence [:: y1, y2, y3 & ys]
  LE : forall n : nat,
       distances [:: x1, x2, x3 & xs] [|n|] <=
       distances [:: y1, y2, y3 & ys] [|n|]
  n : nat
  F : x2 <= y2
  m1, m2 : nat
  B1 : m1 <= m2
  B2 : m2 < size [:: x2, x3 & xs]
  ============================
  [:: x2, x3 & xs] [|m1|] <= [:: x2, x3 & xs] [|m2|]

subgoal 2 (ID 1176) is:
 nondecreasing_sequence [:: y2, y3 & ys]
subgoal 3 (ID 1177) is:
 forall n0 : nat,
 distances [:: x2, x3 & xs] [|n0|] <= distances [:: y2, y3 & ys] [|n0|]

----------------------------------------------------------------------------- *)


          apply (STRxs m1.+1 m2.+1); apply/andP; split.

(* ----------------------------------[ coqtop ]---------------------------------

4 subgoals (ID 1432)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2, y3 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2, y3 & ys] <= len.+1
  x1, x2, x3 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2, x3 & xs] <= len.+1
  FLE : first0 [:: x1, x2, x3 & xs] <= first0 [:: y1, y2, y3 & ys]
  Sxs : 1 < size [:: x1, x2, x3 & xs]
  Sys : 1 < size [:: y1, y2, y3 & ys]
  SIZEEQ : size [:: x1, x2, x3 & xs] = size [:: y1, y2, y3 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2, x3 & xs]
  STRys : nondecreasing_sequence [:: y1, y2, y3 & ys]
  LE : forall n : nat,
       distances [:: x1, x2, x3 & xs] [|n|] <=
       distances [:: y1, y2, y3 & ys] [|n|]
  n : nat
  F : x2 <= y2
  m1, m2 : nat
  B1 : m1 <= m2
  B2 : m2 < size [:: x2, x3 & xs]
  ============================
  m1 < m2.+1

subgoal 2 (ID 1433) is:
 m2.+1 < size [:: x1, x2, x3 & xs]
subgoal 3 (ID 1176) is:
 nondecreasing_sequence [:: y2, y3 & ys]
subgoal 4 (ID 1177) is:
 forall n0 : nat,
 distances [:: x2, x3 & xs] [|n0|] <= distances [:: y2, y3 & ys] [|n0|]

----------------------------------------------------------------------------- *)


          + by rewrite ltnS.

(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 1433)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2, y3 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2, y3 & ys] <= len.+1
  x1, x2, x3 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2, x3 & xs] <= len.+1
  FLE : first0 [:: x1, x2, x3 & xs] <= first0 [:: y1, y2, y3 & ys]
  Sxs : 1 < size [:: x1, x2, x3 & xs]
  Sys : 1 < size [:: y1, y2, y3 & ys]
  SIZEEQ : size [:: x1, x2, x3 & xs] = size [:: y1, y2, y3 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2, x3 & xs]
  STRys : nondecreasing_sequence [:: y1, y2, y3 & ys]
  LE : forall n : nat,
       distances [:: x1, x2, x3 & xs] [|n|] <=
       distances [:: y1, y2, y3 & ys] [|n|]
  n : nat
  F : x2 <= y2
  m1, m2 : nat
  B1 : m1 <= m2
  B2 : m2 < size [:: x2, x3 & xs]
  ============================
  m2.+1 < size [:: x1, x2, x3 & xs]

subgoal 2 (ID 1176) is:
 nondecreasing_sequence [:: y2, y3 & ys]
subgoal 3 (ID 1177) is:
 forall n0 : nat,
 distances [:: x2, x3 & xs] [|n0|] <= distances [:: y2, y3 & ys] [|n0|]

----------------------------------------------------------------------------- *)


          + by rewrite -(ltn_add2r 1) !addn1 in B2.
(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 1176)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2, y3 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2, y3 & ys] <= len.+1
  x1, x2, x3 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2, x3 & xs] <= len.+1
  FLE : first0 [:: x1, x2, x3 & xs] <= first0 [:: y1, y2, y3 & ys]
  Sxs : 1 < size [:: x1, x2, x3 & xs]
  Sys : 1 < size [:: y1, y2, y3 & ys]
  SIZEEQ : size [:: x1, x2, x3 & xs] = size [:: y1, y2, y3 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2, x3 & xs]
  STRys : nondecreasing_sequence [:: y1, y2, y3 & ys]
  LE : forall n : nat,
       distances [:: x1, x2, x3 & xs] [|n|] <=
       distances [:: y1, y2, y3 & ys] [|n|]
  n : nat
  F : x2 <= y2
  ============================
  nondecreasing_sequence [:: y2, y3 & ys]

subgoal 2 (ID 1177) is:
 forall n0 : nat,
 distances [:: x2, x3 & xs] [|n0|] <= distances [:: y2, y3 & ys] [|n0|]

----------------------------------------------------------------------------- *)


        - movem1 m2 /andP [B1 B2].

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 1522)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2, y3 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2, y3 & ys] <= len.+1
  x1, x2, x3 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2, x3 & xs] <= len.+1
  FLE : first0 [:: x1, x2, x3 & xs] <= first0 [:: y1, y2, y3 & ys]
  Sxs : 1 < size [:: x1, x2, x3 & xs]
  Sys : 1 < size [:: y1, y2, y3 & ys]
  SIZEEQ : size [:: x1, x2, x3 & xs] = size [:: y1, y2, y3 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2, x3 & xs]
  STRys : nondecreasing_sequence [:: y1, y2, y3 & ys]
  LE : forall n : nat,
       distances [:: x1, x2, x3 & xs] [|n|] <=
       distances [:: y1, y2, y3 & ys] [|n|]
  n : nat
  F : x2 <= y2
  m1, m2 : nat
  B1 : m1 <= m2
  B2 : m2 < size [:: y2, y3 & ys]
  ============================
  [:: y2, y3 & ys] [|m1|] <= [:: y2, y3 & ys] [|m2|]

subgoal 2 (ID 1177) is:
 forall n0 : nat,
 distances [:: x2, x3 & xs] [|n0|] <= distances [:: y2, y3 & ys] [|n0|]

----------------------------------------------------------------------------- *)


          apply (STRys m1.+1 m2.+1); apply/andP; split.

(* ----------------------------------[ coqtop ]---------------------------------

3 subgoals (ID 1549)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2, y3 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2, y3 & ys] <= len.+1
  x1, x2, x3 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2, x3 & xs] <= len.+1
  FLE : first0 [:: x1, x2, x3 & xs] <= first0 [:: y1, y2, y3 & ys]
  Sxs : 1 < size [:: x1, x2, x3 & xs]
  Sys : 1 < size [:: y1, y2, y3 & ys]
  SIZEEQ : size [:: x1, x2, x3 & xs] = size [:: y1, y2, y3 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2, x3 & xs]
  STRys : nondecreasing_sequence [:: y1, y2, y3 & ys]
  LE : forall n : nat,
       distances [:: x1, x2, x3 & xs] [|n|] <=
       distances [:: y1, y2, y3 & ys] [|n|]
  n : nat
  F : x2 <= y2
  m1, m2 : nat
  B1 : m1 <= m2
  B2 : m2 < size [:: y2, y3 & ys]
  ============================
  m1 < m2.+1

subgoal 2 (ID 1550) is:
 m2.+1 < size [:: y1, y2, y3 & ys]
subgoal 3 (ID 1177) is:
 forall n0 : nat,
 distances [:: x2, x3 & xs] [|n0|] <= distances [:: y2, y3 & ys] [|n0|]

----------------------------------------------------------------------------- *)


          + by rewrite ltnS.

(* ----------------------------------[ coqtop ]---------------------------------

2 subgoals (ID 1550)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2, y3 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2, y3 & ys] <= len.+1
  x1, x2, x3 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2, x3 & xs] <= len.+1
  FLE : first0 [:: x1, x2, x3 & xs] <= first0 [:: y1, y2, y3 & ys]
  Sxs : 1 < size [:: x1, x2, x3 & xs]
  Sys : 1 < size [:: y1, y2, y3 & ys]
  SIZEEQ : size [:: x1, x2, x3 & xs] = size [:: y1, y2, y3 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2, x3 & xs]
  STRys : nondecreasing_sequence [:: y1, y2, y3 & ys]
  LE : forall n : nat,
       distances [:: x1, x2, x3 & xs] [|n|] <=
       distances [:: y1, y2, y3 & ys] [|n|]
  n : nat
  F : x2 <= y2
  m1, m2 : nat
  B1 : m1 <= m2
  B2 : m2 < size [:: y2, y3 & ys]
  ============================
  m2.+1 < size [:: y1, y2, y3 & ys]

subgoal 2 (ID 1177) is:
 forall n0 : nat,
 distances [:: x2, x3 & xs] [|n0|] <= distances [:: y2, y3 & ys] [|n0|]

----------------------------------------------------------------------------- *)


          + by rewrite -(ltn_add2r 1) !addn1 in B2.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 1177)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2, y3 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2, y3 & ys] <= len.+1
  x1, x2, x3 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2, x3 & xs] <= len.+1
  FLE : first0 [:: x1, x2, x3 & xs] <= first0 [:: y1, y2, y3 & ys]
  Sxs : 1 < size [:: x1, x2, x3 & xs]
  Sys : 1 < size [:: y1, y2, y3 & ys]
  SIZEEQ : size [:: x1, x2, x3 & xs] = size [:: y1, y2, y3 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2, x3 & xs]
  STRys : nondecreasing_sequence [:: y1, y2, y3 & ys]
  LE : forall n : nat,
       distances [:: x1, x2, x3 & xs] [|n|] <=
       distances [:: y1, y2, y3 & ys] [|n|]
  n : nat
  F : x2 <= y2
  ============================
  forall n0 : nat,
  distances [:: x2, x3 & xs] [|n0|] <= distances [:: y2, y3 & ys] [|n0|]

----------------------------------------------------------------------------- *)


        - intros.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 1598)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2, y3 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2, y3 & ys] <= len.+1
  x1, x2, x3 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2, x3 & xs] <= len.+1
  FLE : first0 [:: x1, x2, x3 & xs] <= first0 [:: y1, y2, y3 & ys]
  Sxs : 1 < size [:: x1, x2, x3 & xs]
  Sys : 1 < size [:: y1, y2, y3 & ys]
  SIZEEQ : size [:: x1, x2, x3 & xs] = size [:: y1, y2, y3 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2, x3 & xs]
  STRys : nondecreasing_sequence [:: y1, y2, y3 & ys]
  LE : forall n : nat,
       distances [:: x1, x2, x3 & xs] [|n|] <=
       distances [:: y1, y2, y3 & ys] [|n|]
  n : nat
  F : x2 <= y2
  n0 : nat
  ============================
  distances [:: x2, x3 & xs] [|n0|] <= distances [:: y2, y3 & ys] [|n0|]

----------------------------------------------------------------------------- *)


specialize (LE n0.+1).
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 1600)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2, y3 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2, y3 & ys] <= len.+1
  x1, x2, x3 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2, x3 & xs] <= len.+1
  FLE : first0 [:: x1, x2, x3 & xs] <= first0 [:: y1, y2, y3 & ys]
  Sxs : 1 < size [:: x1, x2, x3 & xs]
  Sys : 1 < size [:: y1, y2, y3 & ys]
  SIZEEQ : size [:: x1, x2, x3 & xs] = size [:: y1, y2, y3 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2, x3 & xs]
  STRys : nondecreasing_sequence [:: y1, y2, y3 & ys]
  n0 : nat
  LE : distances [:: x1, x2, x3 & xs] [|n0.+1|] <=
       distances [:: y1, y2, y3 & ys] [|n0.+1|]
  n : nat
  F : x2 <= y2
  ============================
  distances [:: x2, x3 & xs] [|n0|] <= distances [:: y2, y3 & ys] [|n0|]

----------------------------------------------------------------------------- *)


simpl in LE.
(* ----------------------------------[ coqtop ]---------------------------------

1 subgoal (ID 1615)
  
  len : nat
  IHlen : forall ys : seq nat,
          size ys <= len ->
          forall xs : seq nat,
          size xs <= len ->
          first0 xs <= first0 ys ->
          1 < size xs ->
          1 < size ys ->
          size xs = size ys ->
          nondecreasing_sequence xs ->
          nondecreasing_sequence ys ->
          (forall n : nat, distances xs [|n|] <= distances ys [|n|]) ->
          forall n : nat, xs [|n|] <= ys [|n|]
  y1, y2, y3 : nat
  ys : seq nat
  LycSIZE : size [:: y1, y2, y3 & ys] <= len.+1
  x1, x2, x3 : nat
  xs : seq nat
  LxSIZE : size [:: x1, x2, x3 & xs] <= len.+1
  FLE : first0 [:: x1, x2, x3 & xs] <= first0 [:: y1, y2, y3 & ys]
  Sxs : 1 < size [:: x1, x2, x3 & xs]
  Sys : 1 < size [:: y1, y2, y3 & ys]
  SIZEEQ : size [:: x1, x2, x3 & xs] = size [:: y1, y2, y3 & ys]
  STRxs : nondecreasing_sequence [:: x1, x2, x3 & xs]
  STRys : nondecreasing_sequence [:: y1, y2, y3 & ys]
  n0 : nat
  LE : (x3 - x2
        :: [seq (let '(x1, x2) := pat in x2 - x1) | pat <- zip (x3 :: xs) xs])
       [|n0|] <=
       (y3 - y2
        :: [seq (let '(x1, x2) := pat in x2 - x1) | pat <- zip (y3 :: ys) ys])
       [|n0|]
  n : nat
  F : x2 <= y2
  ============================
  distances [:: x2, x3 & xs] [|n0|] <= distances [:: y2, y3 & ys] [|n0|]

----------------------------------------------------------------------------- *)


by done.

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


      }

(* ----------------------------------[ coqtop ]---------------------------------

No more subgoals.

----------------------------------------------------------------------------- *)


    Qed.

  End DistancesOfNonDecreasingSequence.

End NondecreasingSequence.