Library Waterproof.Libs.Analysis.Subsequences


Require Import Coq.Reals.Reals.
Require Import ZArith.
Require Import Lra.
Require Import Classical.
Require Import Classical_Pred_Type.
Require Import ClassicalChoice.

Require Import Automation.
Require Import Libs.Negation.
Require Import Notations.
Require Import Tactics.

Require Import Waterprove.

Waterproof Enable Automation RealsAndIntegers.

# Creating a subsequence of elements satisfying a certain property
The purpose of this section is to provide a somewhat general strategy to construct subsequences of elements satisfying a certain property. # From existence of a next element to a function producing this element The next lemma is quite technical, and is usually not so visible in classical analysis. We rely here on a version of the axiom of choice.
Lemma existence_next_el_to_fun :
     (a : ) (P : Prop),
    ( (m : ) (N : ), k : , (N k)%nat (P m (a k)))
       f : , (m : ) (N : ), (N f m N)%nat P m (a (f m N)).
Proof.
    Take a : ( ).
    Take P : ( Prop).
    Assume that (for all m N : , there exists k : , (N k)%nat P m (a k)) (i).
    We claim that ( (m : ), g : , N : , (N g N)%nat (P m (a (g N)))) (ii).
    {
        Take m : .
        apply choice with (R := fun (k : ) (l : ) ((k l)%nat P m (a l))).
        apply (i).
    }
    apply choice with (R := fun (m : ) (h : ) ( N : , (N h N)%nat P m (a (h N)) ) ).
    apply (ii).
Qed.

The next definition captures what it means to be an index sequence.
Definition is_index_seq (n : ) :=
     k : , (n k < n (S k))%nat.
Given the function that produces 'good' elements, we can use it to construct a subsequence by induction.
Fixpoint create_seq
  (f : ) (l : ) :=
  match l with
  | O => f O O
  | S k => f l (S (create_seq f k))
  end.

If the function that produces 'good' elements is such that the produced elements are far enough in the sequence, it is certain that the produced sequence is an index sequence.
Lemma created_seq_is_index_seq :
   (g : ),
    ( (m N : ), (g m N N)%nat )
      is_index_seq (create_seq g).
Proof.
    Take g : ( ).
    Assume that ( (m N : ), (g m N N)%nat) (i).
    We need to show that (for all k : , (create_seq g k < create_seq g (S k))%nat).
    Take k : .
    By (i) it holds that (g (S k) (S (create_seq g k)) S(create_seq g k))%nat.
    We conclude that (& create_seq g k < g (S k) (S (create_seq g k)) = create_seq g (S k))%nat.
Qed.

The next lemma records that indeed the elements in the subsequence satisfy the desired property.
Lemma subseq_sat_rel :
   (a : ) (g : ) (P : Prop),
    ( m N : , P m (a (g m N)) )
       k : , P k (a (create_seq g k)).
Proof.
    Take a : ( ).
    Take g : ( ).
    Take P : ( Prop).
    Assume that ( m N : , P m (a (g m N))) (i).
    induction k.     - We need to show that (P 0%nat (a (g 0%nat 0%nat))).
      By (i) we conclude that (P 0%nat (a (g 0%nat 0%nat))).
    - We need to show that (P (S k) (a (g (S k) (S (create_seq g k))))).
      By (i) we conclude that (P (S k) (a (g (S k) (S (create_seq g k))))).
Qed.

Lemma exists_good_subseq :
   (a : ) (P : Prop),
    ( (m : ) (N₀ : ), k : , (N₀ k)%nat (P m (a k)))
       n : , is_index_seq n k : , P k (a (n k)).
Proof.
    Take a : ( ).
    Take P : ( Prop).
    Assume that (for all m N : , there exists k : , (N k)%nat P m (a k)).
    By existence_next_el_to_fun it holds that
      ( g : , (m : ) (N : ), (N g m N)%nat P m (a (g m N))).
    Obtain such a g. It holds that
      ( (m : ) (N : ), (N g m N)%nat P m (a (g m N))) (i).
    Choose n := (create_seq g).
    We show both statements.
    - We need to show that (is_index_seq n).
      We need to show that (is_index_seq (create_seq g)).
      By created_seq_is_index_seq it suffices to show that
        (for all m M : , (g m M M)%nat).
      Take m, M : nat.
      By (i) it holds that ((M g m M)%nat P m (a (g m M))).
      We conclude that (g m M >= M)%nat.
    - We need to show that (for all k : , P k (a (n k))).
      We need to show that (for all k : , P k (a ((create_seq g) k))).
      Fail By subseq_sat_rel it suffices to show that
        (for all m M : , P m (a (g m M))).       apply subseq_sat_rel.
      Take m : .
      We need to show that (for all M : , P(m, a (g(m, M)))).
      Take M : .
      By (i) it holds that ((M g m M)%nat P m (a (g m M))) (ii).
      Because (ii) both (M g m M)%nat and (P m (a (g m M))) hold.
      We conclude that (P m (a (g m M))).
Qed.

Definition is_increasing (f : ) :=
   k : , (f k f (S k))%nat.
Lemma incr_loc_to_glob :
   g : ,
    is_increasing g
       ( k l : , (k l)%nat (g k g l)%nat).
Proof.
    Take g : ( ).
    We need to show that ((for all k : , (g k g (S k))%nat)
       for all k l : , (k l)%nat (g k g l)%nat).
    Assume that ( k : , (g k g (S k))%nat).
    Take k : .
    induction l as [|l IH_l].
We first need to show that if then .
    Assume that (k 0)%nat.
    It holds that (k = 0)%nat.
    We conclude that (& g k = g 0 <= g 0)%nat.

Next, we need to show that if then .
    Assume that (k S l)%nat.
    destruct (lt_eq_lt_dec k (S l)) as [temp | k_gt_Sl].
    destruct temp as [k_lt_Sl | k_eq_Sl].
We first consider the case that .
    It holds that (k l)%nat.
    By IH_l it holds that (g k g l)%nat.
    It holds that (g l g (S l))%nat.
    We conclude that (g k <= g (S l))%nat.
We now consider the case . We need to show that .
    We conclude that (& g k = g (S l) <= g (S l))%nat.
Finally we consider the case . However, this case is in contradiction with .
    It holds that (¬(S l < k)%nat).
    Contradiction.
Qed.

Lemma index_seq_strictly_incr :
   n : , is_index_seq n (is_increasing (fun (k : ) (n k - k)%nat)).
Proof.
    Take n : ( ); such that (is_index_seq n).
    We need to show that (for all k : , (n(k) - k n(S(k)) - S(k))%nat).
    Take k : .
    It holds that (for all k0 : , (n k0 < n (S k0))%nat).
    It holds that (n k < n (S k))%nat.
    We conclude that (n k - k n (S k) - S k)%nat.
Qed.

Lemma index_seq_grows_0 :
   n : , is_index_seq n k : , (n k k)%nat.
Proof.
    Take n : ( ); such that (is_index_seq n).
    induction k as [|k IH].
    - We conclude that (n 0 >= 0)%nat.
    - It holds that (for all k0 : , (n k0 < n (S k0))%nat).
      It holds that (n k < n (S k))%nat.
      We conclude that (n (S k) S k)%nat.
Qed.

Lemma index_seq_grows :
   n : , is_index_seq n ( k l : , (k l)%nat (n k - k n l - l)%nat).
Proof.
    Take n : ( ); such that (is_index_seq n).
    Define g := (fun (k : ) (n k - k)%nat).
    By index_seq_strictly_incr it holds that (is_increasing g).
    By incr_loc_to_glob it holds that ( k l : , (k l)%nat (g k g l)%nat).
    Take k : and l : ; such that(k l)%nat.
    We need to show that (g k <= g l)%nat.
    We conclude that (g k <= g l)%nat.
Qed.

# Constructing a subsequence with elements satisfying a particular property
Given a property , and given that it holds for infinitely many elements in the sequence, we want to find a subsequence with all elements satisfying the property. # Finding the smallest element satisfying the property This seems to require some decidability on the property
Fixpoint first_satisfying_element_helper
  (rel : bool)
  (k : )
  (N : ) :=
  match k with
  | O => N
  | S l => if (rel (N-k)%nat (N-k)%nat)
                then k
                else (first_satisfying_element_helper rel l N)
  end.
Definition first_satisfying_element
  (rel : bool)
  (l : )
  (N : )
  := first_satisfying_element_helper rel (N-l) N.
# From infinitely many elements to a function producing those elements
Lemma inf_el_to_fun :
   (a : ) (P : Prop),
    ( N : , k : , (N k)%nat (P N (a k)))
       f : , l : , (l f l)%nat P l (a (f l)).
Proof.
    Take a : ( ).
    Take P : ( Prop).
    apply choice with (R := fun (k : ) (l : ) ((k l)%nat P k (a l))).
Qed.

Fixpoint seq_of_max (f : ) (l : ) :=
  match l with
  | O => f O
  | S k => Nat.max (f l) (seq_of_max f k)
  end.

# The sequence of maxima is increasing
Lemma seq_of_max_is_increasing :
   g : , is_increasing (seq_of_max g).
Proof.
    Take g : ( ).
    We need to show that
      (for all k : , (seq_of_max g k seq_of_max g (S k))%nat).
    Take k : .
    We need to show that (seq_of_max g k Nat.max (g (S k)) (seq_of_max g k))%nat.
    We conclude that (seq_of_max g k Nat.max (g (S k)) (seq_of_max g k))%nat.
Qed.

Lemma elements_le_seq_of_max_pre :
   (g : ) (n : ),
    (g n seq_of_max g n)%nat.
Proof.
    Take g : ( ).
    We use induction on n.
    - We first show the base case (g(0) seq_of_max(g, 0))%nat.
      We need to show that (g 0 g 0)%nat.
      We conclude that (g 0 g 0)%nat.
    - We now show the induction step.
      Assume that (g(n) <= seq_of_max g n)%nat.
      We need to show that (g(n + 1)
        (fix seq_of_max (f : ) (l : ) {struct l} : :=
          match l with
          | 0 => f(0)
          | S k => Nat.max(f(l), seq_of_max(f, k))
          end)(g, n + 1))%nat.
      It holds that (n + 1 = S n)%nat.
      It suffices to show that (g(n) seq_of_max(g, n))%nat.
      We conclude that (g(n) seq_of_max(g, n))%nat.
Qed.

Lemma elements_le_seq_of_max :
   (g : ) (n : ) (k : ),
    (k n)%nat (g k seq_of_max g n)%nat.
Proof.
    Take g : ( ).
    Take n : and k : ; such that (k n)%nat.
    By elements_le_seq_of_max_pre it holds that (g k seq_of_max g k)%nat.
    We claim that (seq_of_max g k seq_of_max g n)%nat.
    { By incr_loc_to_glob it suffices to show that (is_increasing (seq_of_max g)).
      By seq_of_max_is_increasing we conclude that (is_increasing (seq_of_max g)).
    }
    We conclude that (& g k <= seq_of_max g k <= seq_of_max g n)%nat.
Qed.

# From a function producing the correct elements to an index sequence
Fixpoint build_seq
  (f : )
  (k : ) :=
  match k with
  | O => f O
  | S m => f (S (seq_of_max f (build_seq f m)))
  end.
Lemma built_seq_is_index_seq :
   g : ,
    ( k : , (g k k)%nat)
      is_index_seq (build_seq g).
Proof.
    Take g : ( ).
    Assume that (for all k : , (g k k)%nat).
    We need to show that (for all k : , (build_seq g k < build_seq g (S k))%nat).
    Take k : .
    We need to show that (build_seq g k < g (S (seq_of_max g (build_seq g k))))%nat.
    It holds that (g( S(seq_of_max g (build_seq g k))) S(seq_of_max g (build_seq g k)))%nat.
    It holds that (g( S(seq_of_max g (build_seq g k)))> seq_of_max g (build_seq g k))%nat.
    By elements_le_seq_of_max_pre it holds that (seq_of_max g (build_seq g k) g(build_seq g k))%nat.
    It holds that (g(build_seq g k) build_seq g k)%nat.
    We conclude that (& build_seq g k <= g(build_seq g k)
                                      <= seq_of_max g (build_seq g k)
                                      < g( S(seq_of_max g (build_seq g k))))%nat.
Qed.
# Subsequence satisfies relation