l3lab/ntp-mathlib huggingface dataset:
/-- If `f` and `g` are two exact solutions of the same ODE, then the distance between them
can't grow faster than exponentially. This is a simple corollary of Grönwall's inequality, and some
people call this Grönwall's inequality too.

This version assumes all inequalities to be true in some time-dependent set `s t`,
and assumes that the solutions never leave this set. -/
theorem dist_le_of_trajectories_ODE_of_mem_set {v : ℝ → E → E} {s : ℝ → Set E} {K : ℝ≥0}
    (hv : ∀ t, LipschitzOnWith K (v t) (s t))
    {f g : ℝ → E} {a b : ℝ} {δ : ℝ} (hf : ContinuousOn f (Icc a b))
    (hf' : ∀ t ∈ Ico a b, HasDerivWithinAt f (v t (f t)) (Ici t) t) (hfs : ∀ t ∈ Ico a b, f t ∈ s t)
    (hg : ContinuousOn g (Icc a b)) (hg' : ∀ t ∈ Ico a b, HasDerivWithinAt g (v t (g t)) (Ici t) t)
    (hgs : ∀ t ∈ Ico a b, g t ∈ s t) (ha : dist (f a) (g a) ≤ δ) :
    ∀ t ∈ Icc a b, dist (f t) (g t) ≤ δ * exp (K * (t - a)) := by
  have f_bound : ∀ t ∈ Ico a b, dist (v t (f t)) (v t (f t)) ≤ 0 := by intros; rw [dist_self]
  

Proof state:
E : Type u_1
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
F : Type u_2
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
v : ℝ → E → E
s : ℝ → Set E
K : ℝ≥0
hv : ∀ (t : ℝ), LipschitzOnWith K (v t) (s t)
f g : ℝ → E
a b δ : ℝ
hf : ContinuousOn f (Icc a b)
hf' : ∀ t ∈ Ico a b, HasDerivWithinAt f (v t (f t)) (Ici t) t
hfs : ∀ t ∈ Ico a b, f t ∈ s t
hg : ContinuousOn g (Icc a b)
hg' : ∀ t ∈ Ico a b, HasDerivWithinAt g (v t (g t)) (Ici t) t
hgs : ∀ t ∈ Ico a b, g t ∈ s t
ha : dist (f a) (g a) ≤ δ
f_bound : ∀ t ∈ Ico a b, dist (v t (f t)) (v t (f t)) ≤ 0
⊢ ∀ t ∈ Icc a b, dist (f t) (g t) ≤ δ * rexp (↑K * (t - a))

Next tactic:
have g_bound : ∀ t ∈ Ico a b, dist (v t (g t)) (v t (g t)) ≤ 0 := by intros; rw [dist_self]
/-- If `f` and `g` are two exact solutions of the same ODE, then the distance between them
can't grow faster than exponentially. This is a simple corollary of Grönwall's inequality, and some
people call this Grönwall's inequality too.

This version assumes all inequalities to be true in some time-dependent set `s t`,
and assumes that the solutions never leave this set. -/
theorem dist_le_of_trajectories_ODE_of_mem_set {v : ℝ → E → E} {s : ℝ → Set E} {K : ℝ≥0}
    (hv : ∀ t, LipschitzOnWith K (v t) (s t))
    {f g : ℝ → E} {a b : ℝ} {δ : ℝ} (hf : ContinuousOn f (Icc a b))
    (hf' : ∀ t ∈ Ico a b, HasDerivWithinAt f (v t (f t)) (Ici t) t) (hfs : ∀ t ∈ Ico a b, f t ∈ s t)
    (hg : ContinuousOn g (Icc a b)) (hg' : ∀ t ∈ Ico a b, HasDerivWithinAt g (v t (g t)) (Ici t) t)
    (hgs : ∀ t ∈ Ico a b, g t ∈ s t) (ha : dist (f a) (g a) ≤ δ) :
    ∀ t ∈ Icc a b, dist (f t) (g t) ≤ δ * exp (K * (t - a)) := by
  have f_bound : ∀ t ∈ Ico a b, dist (v t (f t)) (v t (f t)) ≤ 0 := by intros; rw [dist_self]
  have g_bound : ∀ t ∈ Ico a b, dist (v t (g t)) (v t (g t)) ≤ 0 := by 

Proof state:
E : Type u_1
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
F : Type u_2
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
v : ℝ → E → E
s : ℝ → Set E
K : ℝ≥0
hv : ∀ (t : ℝ), LipschitzOnWith K (v t) (s t)
f g : ℝ → E
a b δ : ℝ
hf : ContinuousOn f (Icc a b)
hf' : ∀ t ∈ Ico a b, HasDerivWithinAt f (v t (f t)) (Ici t) t
hfs : ∀ t ∈ Ico a b, f t ∈ s t
hg : ContinuousOn g (Icc a b)
hg' : ∀ t ∈ Ico a b, HasDerivWithinAt g (v t (g t)) (Ici t) t
hgs : ∀ t ∈ Ico a b, g t ∈ s t
ha : dist (f a) (g a) ≤ δ
f_bound : ∀ t ∈ Ico a b, dist (v t (f t)) (v t (f t)) ≤ 0
⊢ ∀ t ∈ Ico a b, dist (v t (g t)) (v t (g t)) ≤ 0

Next tactic:
intros
/-- If `f` and `g` are two exact solutions of the same ODE, then the distance between them
can't grow faster than exponentially. This is a simple corollary of Grönwall's inequality, and some
people call this Grönwall's inequality too.

This version assumes all inequalities to be true in some time-dependent set `s t`,
and assumes that the solutions never leave this set. -/
theorem dist_le_of_trajectories_ODE_of_mem_set {v : ℝ → E → E} {s : ℝ → Set E} {K : ℝ≥0}
    (hv : ∀ t, LipschitzOnWith K (v t) (s t))
    {f g : ℝ → E} {a b : ℝ} {δ : ℝ} (hf : ContinuousOn f (Icc a b))
    (hf' : ∀ t ∈ Ico a b, HasDerivWithinAt f (v t (f t)) (Ici t) t) (hfs : ∀ t ∈ Ico a b, f t ∈ s t)
    (hg : ContinuousOn g (Icc a b)) (hg' : ∀ t ∈ Ico a b, HasDerivWithinAt g (v t (g t)) (Ici t) t)
    (hgs : ∀ t ∈ Ico a b, g t ∈ s t) (ha : dist (f a) (g a) ≤ δ) :
    ∀ t ∈ Icc a b, dist (f t) (g t) ≤ δ * exp (K * (t - a)) := by
  have f_bound : ∀ t ∈ Ico a b, dist (v t (f t)) (v t (f t)) ≤ 0 := by intros; rw [dist_self]
  have g_bound : ∀ t ∈ Ico a b, dist (v t (g t)) (v t (g t)) ≤ 0 := by intros; 

Proof state:
E : Type u_1
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
F : Type u_2
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
v : ℝ → E → E
s : ℝ → Set E
K : ℝ≥0
hv : ∀ (t : ℝ), LipschitzOnWith K (v t) (s t)
f g : ℝ → E
a b δ : ℝ
hf : ContinuousOn f (Icc a b)
hf' : ∀ t ∈ Ico a b, HasDerivWithinAt f (v t (f t)) (Ici t) t
hfs : ∀ t ∈ Ico a b, f t ∈ s t
hg : ContinuousOn g (Icc a b)
hg' : ∀ t ∈ Ico a b, HasDerivWithinAt g (v t (g t)) (Ici t) t
hgs : ∀ t ∈ Ico a b, g t ∈ s t
ha : dist (f a) (g a) ≤ δ
f_bound : ∀ t ∈ Ico a b, dist (v t (f t)) (v t (f t)) ≤ 0
t✝ : ℝ
a✝ : t✝ ∈ Ico a b
⊢ dist (v t✝ (g t✝)) (v t✝ (g t✝)) ≤ 0

Next tactic:
rw [dist_self]
/-- If `f` and `g` are two exact solutions of the same ODE, then the distance between them
can't grow faster than exponentially. This is a simple corollary of Grönwall's inequality, and some
people call this Grönwall's inequality too.

This version assumes all inequalities to be true in some time-dependent set `s t`,
and assumes that the solutions never leave this set. -/
theorem dist_le_of_trajectories_ODE_of_mem_set {v : ℝ → E → E} {s : ℝ → Set E} {K : ℝ≥0}
    (hv : ∀ t, LipschitzOnWith K (v t) (s t))
    {f g : ℝ → E} {a b : ℝ} {δ : ℝ} (hf : ContinuousOn f (Icc a b))
    (hf' : ∀ t ∈ Ico a b, HasDerivWithinAt f (v t (f t)) (Ici t) t) (hfs : ∀ t ∈ Ico a b, f t ∈ s t)
    (hg : ContinuousOn g (Icc a b)) (hg' : ∀ t ∈ Ico a b, HasDerivWithinAt g (v t (g t)) (Ici t) t)
    (hgs : ∀ t ∈ Ico a b, g t ∈ s t) (ha : dist (f a) (g a) ≤ δ) :
    ∀ t ∈ Icc a b, dist (f t) (g t) ≤ δ * exp (K * (t - a)) := by
  have f_bound : ∀ t ∈ Ico a b, dist (v t (f t)) (v t (f t)) ≤ 0 := by intros; rw [dist_self]
  have g_bound : ∀ t ∈ Ico a b, dist (v t (g t)) (v t (g t)) ≤ 0 := by intros; rw [dist_self]
  

Proof state:
E : Type u_1
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
F : Type u_2
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
v : ℝ → E → E
s : ℝ → Set E
K : ℝ≥0
hv : ∀ (t : ℝ), LipschitzOnWith K (v t) (s t)
f g : ℝ → E
a b δ : ℝ
hf : ContinuousOn f (Icc a b)
hf' : ∀ t ∈ Ico a b, HasDerivWithinAt f (v t (f t)) (Ici t) t
hfs : ∀ t ∈ Ico a b, f t ∈ s t
hg : ContinuousOn g (Icc a b)
hg' : ∀ t ∈ Ico a b, HasDerivWithinAt g (v t (g t)) (Ici t) t
hgs : ∀ t ∈ Ico a b, g t ∈ s t
ha : dist (f a) (g a) ≤ δ
f_bound : ∀ t ∈ Ico a b, dist (v t (f t)) (v t (f t)) ≤ 0
g_bound : ∀ t ∈ Ico a b, dist (v t (g t)) (v t (g t)) ≤ 0
⊢ ∀ t ∈ Icc a b, dist (f t) (g t) ≤ δ * rexp (↑K * (t - a))

Next tactic:
intro t ht
/-- If `f` and `g` are two exact solutions of the same ODE, then the distance between them
can't grow faster than exponentially. This is a simple corollary of Grönwall's inequality, and some
people call this Grönwall's inequality too.

This version assumes all inequalities to be true in some time-dependent set `s t`,
and assumes that the solutions never leave this set. -/
theorem dist_le_of_trajectories_ODE_of_mem_set {v : ℝ → E → E} {s : ℝ → Set E} {K : ℝ≥0}
    (hv : ∀ t, LipschitzOnWith K (v t) (s t))
    {f g : ℝ → E} {a b : ℝ} {δ : ℝ} (hf : ContinuousOn f (Icc a b))
    (hf' : ∀ t ∈ Ico a b, HasDerivWithinAt f (v t (f t)) (Ici t) t) (hfs : ∀ t ∈ Ico a b, f t ∈ s t)
    (hg : ContinuousOn g (Icc a b)) (hg' : ∀ t ∈ Ico a b, HasDerivWithinAt g (v t (g t)) (Ici t) t)
    (hgs : ∀ t ∈ Ico a b, g t ∈ s t) (ha : dist (f a) (g a) ≤ δ) :
    ∀ t ∈ Icc a b, dist (f t) (g t) ≤ δ * exp (K * (t - a)) := by
  have f_bound : ∀ t ∈ Ico a b, dist (v t (f t)) (v t (f t)) ≤ 0 := by intros; rw [dist_self]
  have g_bound : ∀ t ∈ Ico a b, dist (v t (g t)) (v t (g t)) ≤ 0 := by intros; rw [dist_self]
  intro t ht
  

Proof state:
E : Type u_1
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
F : Type u_2
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
v : ℝ → E → E
s : ℝ → Set E
K : ℝ≥0
hv : ∀ (t : ℝ), LipschitzOnWith K (v t) (s t)
f g : ℝ → E
a b δ : ℝ
hf : ContinuousOn f (Icc a b)
hf' : ∀ t ∈ Ico a b, HasDerivWithinAt f (v t (f t)) (Ici t) t
hfs : ∀ t ∈ Ico a b, f t ∈ s t
hg : ContinuousOn g (Icc a b)
hg' : ∀ t ∈ Ico a b, HasDerivWithinAt g (v t (g t)) (Ici t) t
hgs : ∀ t ∈ Ico a b, g t ∈ s t
ha : dist (f a) (g a) ≤ δ
f_bound : ∀ t ∈ Ico a b, dist (v t (f t)) (v t (f t)) ≤ 0
g_bound : ∀ t ∈ Ico a b, dist (v t (g t)) (v t (g t)) ≤ 0
t : ℝ
ht : t ∈ Icc a b
⊢ dist (f t) (g t) ≤ δ * rexp (↑K * (t - a))

Next tactic:
have :=
    dist_le_of_approx_trajectories_ODE_of_mem_set hv hf hf' f_bound hfs hg hg' g_bound hgs ha t ht
/-- If `f` and `g` are two exact solutions of the same ODE, then the distance between them
can't grow faster than exponentially. This is a simple corollary of Grönwall's inequality, and some
people call this Grönwall's inequality too.

This version assumes all inequalities to be true in some time-dependent set `s t`,
and assumes that the solutions never leave this set. -/
theorem dist_le_of_trajectories_ODE_of_mem_set {v : ℝ → E → E} {s : ℝ → Set E} {K : ℝ≥0}
    (hv : ∀ t, LipschitzOnWith K (v t) (s t))
    {f g : ℝ → E} {a b : ℝ} {δ : ℝ} (hf : ContinuousOn f (Icc a b))
    (hf' : ∀ t ∈ Ico a b, HasDerivWithinAt f (v t (f t)) (Ici t) t) (hfs : ∀ t ∈ Ico a b, f t ∈ s t)
    (hg : ContinuousOn g (Icc a b)) (hg' : ∀ t ∈ Ico a b, HasDerivWithinAt g (v t (g t)) (Ici t) t)
    (hgs : ∀ t ∈ Ico a b, g t ∈ s t) (ha : dist (f a) (g a) ≤ δ) :
    ∀ t ∈ Icc a b, dist (f t) (g t) ≤ δ * exp (K * (t - a)) := by
  have f_bound : ∀ t ∈ Ico a b, dist (v t (f t)) (v t (f t)) ≤ 0 := by intros; rw [dist_self]
  have g_bound : ∀ t ∈ Ico a b, dist (v t (g t)) (v t (g t)) ≤ 0 := by intros; rw [dist_self]
  intro t ht
  have :=
    dist_le_of_approx_trajectories_ODE_of_mem_set hv hf hf' f_bound hfs hg hg' g_bound hgs ha t ht
  

Proof state:
E : Type u_1
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
F : Type u_2
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
v : ℝ → E → E
s : ℝ → Set E
K : ℝ≥0
hv : ∀ (t : ℝ), LipschitzOnWith K (v t) (s t)
f g : ℝ → E
a b δ : ℝ
hf : ContinuousOn f (Icc a b)
hf' : ∀ t ∈ Ico a b, HasDerivWithinAt f (v t (f t)) (Ici t) t
hfs : ∀ t ∈ Ico a b, f t ∈ s t
hg : ContinuousOn g (Icc a b)
hg' : ∀ t ∈ Ico a b, HasDerivWithinAt g (v t (g t)) (Ici t) t
hgs : ∀ t ∈ Ico a b, g t ∈ s t
ha : dist (f a) (g a) ≤ δ
f_bound : ∀ t ∈ Ico a b, dist (v t (f t)) (v t (f t)) ≤ 0
g_bound : ∀ t ∈ Ico a b, dist (v t (g t)) (v t (g t)) ≤ 0
t : ℝ
ht : t ∈ Icc a b
this : dist (f t) (g t) ≤ gronwallBound δ (↑K) (0 + 0) (t - a)
⊢ dist (f t) (g t) ≤ δ * rexp (↑K * (t - a))

Next tactic:
rwa [zero_add, gronwallBound_ε0] at this
/-- There exists only one solution of an ODE \(\dot x=v(t, x)\) in a set `s ⊆ ℝ × E` with
a given initial value provided that the RHS is Lipschitz continuous in `x` within `s`,
and we consider only solutions included in `s`.

This version shows uniqueness in a closed interval `Icc a b`, where `a` is the initial time. -/
theorem ODE_solution_unique_of_mem_set {v : ℝ → E → E} {s : ℝ → Set E} {K : ℝ≥0}
    (hv : ∀ t, LipschitzOnWith K (v t) (s t))
    {f g : ℝ → E} {a b : ℝ} (hf : ContinuousOn f (Icc a b))
    (hf' : ∀ t ∈ Ico a b, HasDerivWithinAt f (v t (f t)) (Ici t) t) (hfs : ∀ t ∈ Ico a b, f t ∈ s t)
    (hg : ContinuousOn g (Icc a b)) (hg' : ∀ t ∈ Ico a b, HasDerivWithinAt g (v t (g t)) (Ici t) t)
    (hgs : ∀ t ∈ Ico a b, g t ∈ s t) (ha : f a = g a) : EqOn f g (Icc a b) := fun t ht ↦ by
  

Proof state:
E : Type u_1
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
F : Type u_2
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
v : ℝ → E → E
s : ℝ → Set E
K : ℝ≥0
hv : ∀ (t : ℝ), LipschitzOnWith K (v t) (s t)
f g : ℝ → E
a b : ℝ
hf : ContinuousOn f (Icc a b)
hf' : ∀ t ∈ Ico a b, HasDerivWithinAt f (v t (f t)) (Ici t) t
hfs : ∀ t ∈ Ico a b, f t ∈ s t
hg : ContinuousOn g (Icc a b)
hg' : ∀ t ∈ Ico a b, HasDerivWithinAt g (v t (g t)) (Ici t) t
hgs : ∀ t ∈ Ico a b, g t ∈ s t
ha : f a = g a
t : ℝ
ht : t ∈ Icc a b
⊢ f t = g t

Next tactic:
have := dist_le_of_trajectories_ODE_of_mem_set hv hf hf' hfs hg hg' hgs (dist_le_zero.2 ha) t ht
/-- There exists only one solution of an ODE \(\dot x=v(t, x)\) in a set `s ⊆ ℝ × E` with
a given initial value provided that the RHS is Lipschitz continuous in `x` within `s`,
and we consider only solutions included in `s`.

This version shows uniqueness in a closed interval `Icc a b`, where `a` is the initial time. -/
theorem ODE_solution_unique_of_mem_set {v : ℝ → E → E} {s : ℝ → Set E} {K : ℝ≥0}
    (hv : ∀ t, LipschitzOnWith K (v t) (s t))
    {f g : ℝ → E} {a b : ℝ} (hf : ContinuousOn f (Icc a b))
    (hf' : ∀ t ∈ Ico a b, HasDerivWithinAt f (v t (f t)) (Ici t) t) (hfs : ∀ t ∈ Ico a b, f t ∈ s t)
    (hg : ContinuousOn g (Icc a b)) (hg' : ∀ t ∈ Ico a b, HasDerivWithinAt g (v t (g t)) (Ici t) t)
    (hgs : ∀ t ∈ Ico a b, g t ∈ s t) (ha : f a = g a) : EqOn f g (Icc a b) := fun t ht ↦ by
  have := dist_le_of_trajectories_ODE_of_mem_set hv hf hf' hfs hg hg' hgs (dist_le_zero.2 ha) t ht
  

Proof state:
E : Type u_1
inst✝³ : NormedAddCommGroup E
inst✝² : NormedSpace ℝ E
F : Type u_2
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace ℝ F
v : ℝ → E → E
s : ℝ → Set E
K : ℝ≥0
hv : ∀ (t : ℝ), LipschitzOnWith K (v t) (s t)
f g : ℝ → E
a b : ℝ
hf : ContinuousOn f (Icc a b)
hf' : ∀ t ∈ Ico a b, HasDerivWithinAt f (v t (f t)) (Ici t) t
hfs : ∀ t ∈ Ico a b, f t ∈ s t
hg : ContinuousOn g (Icc a b)
hg' : ∀ t ∈ Ico a b, HasDerivWithinAt g (v t (g t)) (Ici t) t
hgs : ∀ t ∈ Ico a b, g t ∈ s t
ha : f a = g a
t : ℝ
ht : t ∈ Icc a b
this : dist (f t) (g t) ≤ 0 * rexp (↑K * (t - a))
⊢ f t = g t

Next tactic:
rwa [zero_mul, dist_le_zero] at this
@[simp]
theorem rdrop_nil : rdrop ([] : List α) n = [] := by 

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
⊢ rdrop [] n = []

Next tactic:
simp [rdrop]
@[simp]
theorem rdrop_zero : rdrop l 0 = l := by 

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
⊢ rdrop l 0 = l

Next tactic:
simp [rdrop]
theorem rdrop_eq_reverse_drop_reverse : l.rdrop n = reverse (l.reverse.drop n) := by
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
⊢ rdrop l n = reverse (drop n (reverse l))

Next tactic:
rw [rdrop]
theorem rdrop_eq_reverse_drop_reverse : l.rdrop n = reverse (l.reverse.drop n) := by
  rw [rdrop]
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
⊢ take (length l - n) l = reverse (drop n (reverse l))

Next tactic:
induction' l using List.reverseRecOn with xs x IH generalizing n
theorem rdrop_eq_reverse_drop_reverse : l.rdrop n = reverse (l.reverse.drop n) := by
  rw [rdrop]
  induction' l using List.reverseRecOn with xs x IH generalizing n
  · 

Proof state:
case H0
α : Type u_1
p : α → Bool
n : ℕ
⊢ take (length [] - n) [] = reverse (drop n (reverse []))

Next tactic:
simp
theorem rdrop_eq_reverse_drop_reverse : l.rdrop n = reverse (l.reverse.drop n) := by
  rw [rdrop]
  induction' l using List.reverseRecOn with xs x IH generalizing n
  · simp
  · 

Proof state:
case H1
α : Type u_1
p : α → Bool
xs : List α
x : α
IH : ∀ (n : ℕ), take (length xs - n) xs = reverse (drop n (reverse xs))
n : ℕ
⊢ take (length (xs ++ [x]) - n) (xs ++ [x]) = reverse (drop n (reverse (xs ++ [x])))

Next tactic:
cases n
theorem rdrop_eq_reverse_drop_reverse : l.rdrop n = reverse (l.reverse.drop n) := by
  rw [rdrop]
  induction' l using List.reverseRecOn with xs x IH generalizing n
  · simp
  · cases n
    · 

Proof state:
case H1.zero
α : Type u_1
p : α → Bool
xs : List α
x : α
IH : ∀ (n : ℕ), take (length xs - n) xs = reverse (drop n (reverse xs))
⊢ take (length (xs ++ [x]) - Nat.zero) (xs ++ [x]) = reverse (drop Nat.zero (reverse (xs ++ [x])))

Next tactic:
simp [take_append]
theorem rdrop_eq_reverse_drop_reverse : l.rdrop n = reverse (l.reverse.drop n) := by
  rw [rdrop]
  induction' l using List.reverseRecOn with xs x IH generalizing n
  · simp
  · cases n
    · simp [take_append]
    · 

Proof state:
case H1.succ
α : Type u_1
p : α → Bool
xs : List α
x : α
IH : ∀ (n : ℕ), take (length xs - n) xs = reverse (drop n (reverse xs))
n✝ : ℕ
⊢ take (length (xs ++ [x]) - Nat.succ n✝) (xs ++ [x]) = reverse (drop (Nat.succ n✝) (reverse (xs ++ [x])))

Next tactic:
simp [take_append_eq_append_take, IH]
@[simp]
theorem rdrop_concat_succ (x : α) : rdrop (l ++ [x]) (n + 1) = rdrop l n := by
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
x : α
⊢ rdrop (l ++ [x]) (n + 1) = rdrop l n

Next tactic:
simp [rdrop_eq_reverse_drop_reverse]
@[simp]
theorem rtake_nil : rtake ([] : List α) n = [] := by 

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
⊢ rtake [] n = []

Next tactic:
simp [rtake]
@[simp]
theorem rtake_zero : rtake l 0 = [] := by 

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
⊢ rtake l 0 = []

Next tactic:
simp [rtake]
theorem rtake_eq_reverse_take_reverse : l.rtake n = reverse (l.reverse.take n) := by
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
⊢ rtake l n = reverse (take n (reverse l))

Next tactic:
rw [rtake]
theorem rtake_eq_reverse_take_reverse : l.rtake n = reverse (l.reverse.take n) := by
  rw [rtake]
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
⊢ drop (length l - n) l = reverse (take n (reverse l))

Next tactic:
induction' l using List.reverseRecOn with xs x IH generalizing n
theorem rtake_eq_reverse_take_reverse : l.rtake n = reverse (l.reverse.take n) := by
  rw [rtake]
  induction' l using List.reverseRecOn with xs x IH generalizing n
  · 

Proof state:
case H0
α : Type u_1
p : α → Bool
n : ℕ
⊢ drop (length [] - n) [] = reverse (take n (reverse []))

Next tactic:
simp
theorem rtake_eq_reverse_take_reverse : l.rtake n = reverse (l.reverse.take n) := by
  rw [rtake]
  induction' l using List.reverseRecOn with xs x IH generalizing n
  · simp
  · 

Proof state:
case H1
α : Type u_1
p : α → Bool
xs : List α
x : α
IH : ∀ (n : ℕ), drop (length xs - n) xs = reverse (take n (reverse xs))
n : ℕ
⊢ drop (length (xs ++ [x]) - n) (xs ++ [x]) = reverse (take n (reverse (xs ++ [x])))

Next tactic:
cases n
theorem rtake_eq_reverse_take_reverse : l.rtake n = reverse (l.reverse.take n) := by
  rw [rtake]
  induction' l using List.reverseRecOn with xs x IH generalizing n
  · simp
  · cases n
    · 

Proof state:
case H1.zero
α : Type u_1
p : α → Bool
xs : List α
x : α
IH : ∀ (n : ℕ), drop (length xs - n) xs = reverse (take n (reverse xs))
⊢ drop (length (xs ++ [x]) - Nat.zero) (xs ++ [x]) = reverse (take Nat.zero (reverse (xs ++ [x])))

Next tactic:
exact drop_length _
theorem rtake_eq_reverse_take_reverse : l.rtake n = reverse (l.reverse.take n) := by
  rw [rtake]
  induction' l using List.reverseRecOn with xs x IH generalizing n
  · simp
  · cases n
    · exact drop_length _
    · 

Proof state:
case H1.succ
α : Type u_1
p : α → Bool
xs : List α
x : α
IH : ∀ (n : ℕ), drop (length xs - n) xs = reverse (take n (reverse xs))
n✝ : ℕ
⊢ drop (length (xs ++ [x]) - Nat.succ n✝) (xs ++ [x]) = reverse (take (Nat.succ n✝) (reverse (xs ++ [x])))

Next tactic:
simp [drop_append_eq_append_drop, IH]
@[simp]
theorem rtake_concat_succ (x : α) : rtake (l ++ [x]) (n + 1) = rtake l n ++ [x] := by
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
x : α
⊢ rtake (l ++ [x]) (n + 1) = rtake l n ++ [x]

Next tactic:
simp [rtake_eq_reverse_take_reverse]
@[simp]
theorem rdropWhile_nil : rdropWhile p ([] : List α) = [] := by 

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
⊢ rdropWhile p [] = []

Next tactic:
simp [rdropWhile, dropWhile]
theorem rdropWhile_concat (x : α) :
    rdropWhile p (l ++ [x]) = if p x then rdropWhile p l else l ++ [x] := by
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
x : α
⊢ rdropWhile p (l ++ [x]) = if p x = true then rdropWhile p l else l ++ [x]

Next tactic:
simp only [rdropWhile, dropWhile, reverse_append, reverse_singleton, singleton_append]
theorem rdropWhile_concat (x : α) :
    rdropWhile p (l ++ [x]) = if p x then rdropWhile p l else l ++ [x] := by
  simp only [rdropWhile, dropWhile, reverse_append, reverse_singleton, singleton_append]
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
x : α
⊢ reverse
      (match p x with
      | true => dropWhile p (reverse l)
      | false => x :: reverse l) =
    if p x = true then reverse (dropWhile p (reverse l)) else l ++ [x]

Next tactic:
split_ifs with h
theorem rdropWhile_concat (x : α) :
    rdropWhile p (l ++ [x]) = if p x then rdropWhile p l else l ++ [x] := by
  simp only [rdropWhile, dropWhile, reverse_append, reverse_singleton, singleton_append]
  split_ifs with h <;> 

Proof state:
case pos
α : Type u_1
p : α → Bool
l : List α
n : ℕ
x : α
h : p x = true
⊢ reverse
      (match p x with
      | true => dropWhile p (reverse l)
      | false => x :: reverse l) =
    reverse (dropWhile p (reverse l))

Next tactic:
simp [h]
theorem rdropWhile_concat (x : α) :
    rdropWhile p (l ++ [x]) = if p x then rdropWhile p l else l ++ [x] := by
  simp only [rdropWhile, dropWhile, reverse_append, reverse_singleton, singleton_append]
  split_ifs with h <;> 

Proof state:
case neg
α : Type u_1
p : α → Bool
l : List α
n : ℕ
x : α
h : ¬p x = true
⊢ reverse
      (match p x with
      | true => dropWhile p (reverse l)
      | false => x :: reverse l) =
    l ++ [x]

Next tactic:
simp [h]
@[simp]
theorem rdropWhile_concat_pos (x : α) (h : p x) : rdropWhile p (l ++ [x]) = rdropWhile p l := by
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
x : α
h : p x = true
⊢ rdropWhile p (l ++ [x]) = rdropWhile p l

Next tactic:
rw [rdropWhile_concat, if_pos h]
@[simp]
theorem rdropWhile_concat_neg (x : α) (h : ¬p x) : rdropWhile p (l ++ [x]) = l ++ [x] := by
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
x : α
h : ¬p x = true
⊢ rdropWhile p (l ++ [x]) = l ++ [x]

Next tactic:
rw [rdropWhile_concat, if_neg h]
theorem rdropWhile_singleton (x : α) : rdropWhile p [x] = if p x then [] else [x] := by
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
x : α
⊢ rdropWhile p [x] = if p x = true then [] else [x]

Next tactic:
rw [← nil_append [x], rdropWhile_concat, rdropWhile_nil]
theorem rdropWhile_last_not (hl : l.rdropWhile p ≠ []) : ¬p ((rdropWhile p l).getLast hl) := by
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
hl : rdropWhile p l ≠ []
⊢ ¬p (getLast (rdropWhile p l) hl) = true

Next tactic:
simp_rw [rdropWhile]
theorem rdropWhile_last_not (hl : l.rdropWhile p ≠ []) : ¬p ((rdropWhile p l).getLast hl) := by
  simp_rw [rdropWhile]
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
hl : rdropWhile p l ≠ []
⊢ ¬p (getLast (reverse (dropWhile p (reverse l))) (_ : reverse (dropWhile p (reverse l)) ≠ [])) = true

Next tactic:
rw [getLast_reverse]
theorem rdropWhile_last_not (hl : l.rdropWhile p ≠ []) : ¬p ((rdropWhile p l).getLast hl) := by
  simp_rw [rdropWhile]
  rw [getLast_reverse]
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
hl : rdropWhile p l ≠ []
⊢ ¬p (get (dropWhile p (reverse l)) { val := 0, isLt := (_ : 0 < length (dropWhile p (reverse l))) }) = true

Next tactic:
exact dropWhile_nthLe_zero_not _ _ _
theorem rdropWhile_prefix : l.rdropWhile p <+: l := by
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
⊢ rdropWhile p l <+: l

Next tactic:
rw [← reverse_suffix, rdropWhile, reverse_reverse]
theorem rdropWhile_prefix : l.rdropWhile p <+: l := by
  rw [← reverse_suffix, rdropWhile, reverse_reverse]
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
⊢ dropWhile p (reverse l) <:+ reverse l

Next tactic:
exact dropWhile_suffix _
@[simp]
theorem rdropWhile_eq_nil_iff : rdropWhile p l = [] ↔ ∀ x ∈ l, p x := by 

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
⊢ rdropWhile p l = [] ↔ ∀ (x : α), x ∈ l → p x = true

Next tactic:
simp [rdropWhile]
@[simp]
theorem dropWhile_eq_self_iff : dropWhile p l = l ↔ ∀ hl : 0 < l.length, ¬p (l.nthLe 0 hl) := by
  

Proof state:
α : Type u_1
p : α → Bool
l : List α
n : ℕ
⊢ dropWhile p l = l ↔ ∀ (hl : 0 < length l), ¬p (nthLe l 0 hl) = true

Next tactic:
cases' l with hd tl