l3lab/ntp-mathlib huggingface dataset:
theorem eq_of_perm_of_sorted [IsAntisymm α r] {l₁ l₂ : List α} (p : l₁ ~ l₂) (s₁ : Sorted r l₁)
    (s₂ : Sorted r l₂) : l₁ = l₂ := by
  induction' s₁ with a l₁ h₁ s₁ IH generalizing l₂
  · exact p.nil_eq
  · have : a ∈ l₂ := p.subset (mem_cons_self _ _)
    rcases mem_split this with ⟨u₂, v₂, rfl⟩
    have p' := (perm_cons a).1 (p.trans perm_middle)
    obtain rfl := IH p' (s₂.sublist <| by simp)
    change a :: u₂ ++ v₂ = u₂ ++ ([a] ++ v₂)
    rw [← append_assoc]
    congr
    

Proof state:
case cons.intro.intro.e_a
α : Type uu
r : α → α → Prop
a✝ : α
l : List α
inst✝ : IsAntisymm α r
l₁ : List α
a : α
u₂ v₂ : List α
s₂ : Sorted r (u₂ ++ a :: v₂)
this : a ∈ u₂ ++ a :: v₂
h₁ : ∀ a' ∈ u₂ ++ v₂, r a a'
s₁ : Pairwise r (u₂ ++ v₂)
IH : ∀ {l₂ : List α}, u₂ ++ v₂ ~ l₂ → Sorted r l₂ → u₂ ++ v₂ = l₂
p : a :: (u₂ ++ v₂) ~ u₂ ++ a :: v₂
p' : u₂ ++ v₂ ~ u₂ ++ v₂
⊢ a :: u₂ = u₂ ++ [a]

Next tactic:
have : ∀ x ∈ u₂, x = a := fun x m =>
      antisymm ((pairwise_append.1 s₂).2.2 _ m a (mem_cons_self _ _)) (h₁ _ (by simp [m]))
theorem eq_of_perm_of_sorted [IsAntisymm α r] {l₁ l₂ : List α} (p : l₁ ~ l₂) (s₁ : Sorted r l₁)
    (s₂ : Sorted r l₂) : l₁ = l₂ := by
  induction' s₁ with a l₁ h₁ s₁ IH generalizing l₂
  · exact p.nil_eq
  · have : a ∈ l₂ := p.subset (mem_cons_self _ _)
    rcases mem_split this with ⟨u₂, v₂, rfl⟩
    have p' := (perm_cons a).1 (p.trans perm_middle)
    obtain rfl := IH p' (s₂.sublist <| by simp)
    change a :: u₂ ++ v₂ = u₂ ++ ([a] ++ v₂)
    rw [← append_assoc]
    congr
    have : ∀ x ∈ u₂, x = a := fun x m =>
      antisymm ((pairwise_append.1 s₂).2.2 _ m a (mem_cons_self _ _)) (h₁ _ (by 

Proof state:
α : Type uu
r : α → α → Prop
a✝ : α
l : List α
inst✝ : IsAntisymm α r
l₁ : List α
a : α
u₂ v₂ : List α
s₂ : Sorted r (u₂ ++ a :: v₂)
this : a ∈ u₂ ++ a :: v₂
h₁ : ∀ a' ∈ u₂ ++ v₂, r a a'
s₁ : Pairwise r (u₂ ++ v₂)
IH : ∀ {l₂ : List α}, u₂ ++ v₂ ~ l₂ → Sorted r l₂ → u₂ ++ v₂ = l₂
p : a :: (u₂ ++ v₂) ~ u₂ ++ a :: v₂
p' : u₂ ++ v₂ ~ u₂ ++ v₂
x : α
m : x ∈ u₂
⊢ x ∈ u₂ ++ v₂

Next tactic:
simp [m]
theorem eq_of_perm_of_sorted [IsAntisymm α r] {l₁ l₂ : List α} (p : l₁ ~ l₂) (s₁ : Sorted r l₁)
    (s₂ : Sorted r l₂) : l₁ = l₂ := by
  induction' s₁ with a l₁ h₁ s₁ IH generalizing l₂
  · exact p.nil_eq
  · have : a ∈ l₂ := p.subset (mem_cons_self _ _)
    rcases mem_split this with ⟨u₂, v₂, rfl⟩
    have p' := (perm_cons a).1 (p.trans perm_middle)
    obtain rfl := IH p' (s₂.sublist <| by simp)
    change a :: u₂ ++ v₂ = u₂ ++ ([a] ++ v₂)
    rw [← append_assoc]
    congr
    have : ∀ x ∈ u₂, x = a := fun x m =>
      antisymm ((pairwise_append.1 s₂).2.2 _ m a (mem_cons_self _ _)) (h₁ _ (by simp [m]))
    

Proof state:
case cons.intro.intro.e_a
α : Type uu
r : α → α → Prop
a✝ : α
l : List α
inst✝ : IsAntisymm α r
l₁ : List α
a : α
u₂ v₂ : List α
s₂ : Sorted r (u₂ ++ a :: v₂)
this✝ : a ∈ u₂ ++ a :: v₂
h₁ : ∀ a' ∈ u₂ ++ v₂, r a a'
s₁ : Pairwise r (u₂ ++ v₂)
IH : ∀ {l₂ : List α}, u₂ ++ v₂ ~ l₂ → Sorted r l₂ → u₂ ++ v₂ = l₂
p : a :: (u₂ ++ v₂) ~ u₂ ++ a :: v₂
p' : u₂ ++ v₂ ~ u₂ ++ v₂
this : ∀ x ∈ u₂, x = a
⊢ a :: u₂ = u₂ ++ [a]

Next tactic:
rw [(@eq_replicate _ a (length u₂ + 1) (a :: u₂)).2,
          (@eq_replicate _ a (length u₂ + 1) (u₂ ++ [a])).2]
theorem eq_of_perm_of_sorted [IsAntisymm α r] {l₁ l₂ : List α} (p : l₁ ~ l₂) (s₁ : Sorted r l₁)
    (s₂ : Sorted r l₂) : l₁ = l₂ := by
  induction' s₁ with a l₁ h₁ s₁ IH generalizing l₂
  · exact p.nil_eq
  · have : a ∈ l₂ := p.subset (mem_cons_self _ _)
    rcases mem_split this with ⟨u₂, v₂, rfl⟩
    have p' := (perm_cons a).1 (p.trans perm_middle)
    obtain rfl := IH p' (s₂.sublist <| by simp)
    change a :: u₂ ++ v₂ = u₂ ++ ([a] ++ v₂)
    rw [← append_assoc]
    congr
    have : ∀ x ∈ u₂, x = a := fun x m =>
      antisymm ((pairwise_append.1 s₂).2.2 _ m a (mem_cons_self _ _)) (h₁ _ (by simp [m]))
    rw [(@eq_replicate _ a (length u₂ + 1) (a :: u₂)).2,
          (@eq_replicate _ a (length u₂ + 1) (u₂ ++ [a])).2] <;>
        

Proof state:
case cons.intro.intro.e_a
α : Type uu
r : α → α → Prop
a✝ : α
l : List α
inst✝ : IsAntisymm α r
l₁ : List α
a : α
u₂ v₂ : List α
s₂ : Sorted r (u₂ ++ a :: v₂)
this✝ : a ∈ u₂ ++ a :: v₂
h₁ : ∀ a' ∈ u₂ ++ v₂, r a a'
s₁ : Pairwise r (u₂ ++ v₂)
IH : ∀ {l₂ : List α}, u₂ ++ v₂ ~ l₂ → Sorted r l₂ → u₂ ++ v₂ = l₂
p : a :: (u₂ ++ v₂) ~ u₂ ++ a :: v₂
p' : u₂ ++ v₂ ~ u₂ ++ v₂
this : ∀ x ∈ u₂, x = a
⊢ length (u₂ ++ [a]) = length u₂ + 1 ∧ ∀ b ∈ u₂ ++ [a], b = a

Next tactic:
constructor
theorem eq_of_perm_of_sorted [IsAntisymm α r] {l₁ l₂ : List α} (p : l₁ ~ l₂) (s₁ : Sorted r l₁)
    (s₂ : Sorted r l₂) : l₁ = l₂ := by
  induction' s₁ with a l₁ h₁ s₁ IH generalizing l₂
  · exact p.nil_eq
  · have : a ∈ l₂ := p.subset (mem_cons_self _ _)
    rcases mem_split this with ⟨u₂, v₂, rfl⟩
    have p' := (perm_cons a).1 (p.trans perm_middle)
    obtain rfl := IH p' (s₂.sublist <| by simp)
    change a :: u₂ ++ v₂ = u₂ ++ ([a] ++ v₂)
    rw [← append_assoc]
    congr
    have : ∀ x ∈ u₂, x = a := fun x m =>
      antisymm ((pairwise_append.1 s₂).2.2 _ m a (mem_cons_self _ _)) (h₁ _ (by simp [m]))
    rw [(@eq_replicate _ a (length u₂ + 1) (a :: u₂)).2,
          (@eq_replicate _ a (length u₂ + 1) (u₂ ++ [a])).2] <;>
        

Proof state:
case cons.intro.intro.e_a
α : Type uu
r : α → α → Prop
a✝ : α
l : List α
inst✝ : IsAntisymm α r
l₁ : List α
a : α
u₂ v₂ : List α
s₂ : Sorted r (u₂ ++ a :: v₂)
this✝ : a ∈ u₂ ++ a :: v₂
h₁ : ∀ a' ∈ u₂ ++ v₂, r a a'
s₁ : Pairwise r (u₂ ++ v₂)
IH : ∀ {l₂ : List α}, u₂ ++ v₂ ~ l₂ → Sorted r l₂ → u₂ ++ v₂ = l₂
p : a :: (u₂ ++ v₂) ~ u₂ ++ a :: v₂
p' : u₂ ++ v₂ ~ u₂ ++ v₂
this : ∀ x ∈ u₂, x = a
⊢ length (a :: u₂) = length u₂ + 1 ∧ ∀ b ∈ a :: u₂, b = a

Next tactic:
constructor
theorem eq_of_perm_of_sorted [IsAntisymm α r] {l₁ l₂ : List α} (p : l₁ ~ l₂) (s₁ : Sorted r l₁)
    (s₂ : Sorted r l₂) : l₁ = l₂ := by
  induction' s₁ with a l₁ h₁ s₁ IH generalizing l₂
  · exact p.nil_eq
  · have : a ∈ l₂ := p.subset (mem_cons_self _ _)
    rcases mem_split this with ⟨u₂, v₂, rfl⟩
    have p' := (perm_cons a).1 (p.trans perm_middle)
    obtain rfl := IH p' (s₂.sublist <| by simp)
    change a :: u₂ ++ v₂ = u₂ ++ ([a] ++ v₂)
    rw [← append_assoc]
    congr
    have : ∀ x ∈ u₂, x = a := fun x m =>
      antisymm ((pairwise_append.1 s₂).2.2 _ m a (mem_cons_self _ _)) (h₁ _ (by simp [m]))
    rw [(@eq_replicate _ a (length u₂ + 1) (a :: u₂)).2,
          (@eq_replicate _ a (length u₂ + 1) (u₂ ++ [a])).2] <;>
        constructor <;>
      

Proof state:
case cons.intro.intro.e_a.left
α : Type uu
r : α → α → Prop
a✝ : α
l : List α
inst✝ : IsAntisymm α r
l₁ : List α
a : α
u₂ v₂ : List α
s₂ : Sorted r (u₂ ++ a :: v₂)
this✝ : a ∈ u₂ ++ a :: v₂
h₁ : ∀ a' ∈ u₂ ++ v₂, r a a'
s₁ : Pairwise r (u₂ ++ v₂)
IH : ∀ {l₂ : List α}, u₂ ++ v₂ ~ l₂ → Sorted r l₂ → u₂ ++ v₂ = l₂
p : a :: (u₂ ++ v₂) ~ u₂ ++ a :: v₂
p' : u₂ ++ v₂ ~ u₂ ++ v₂
this : ∀ x ∈ u₂, x = a
⊢ length (u₂ ++ [a]) = length u₂ + 1

Next tactic:
simp [iff_true_intro this, or_comm]
theorem eq_of_perm_of_sorted [IsAntisymm α r] {l₁ l₂ : List α} (p : l₁ ~ l₂) (s₁ : Sorted r l₁)
    (s₂ : Sorted r l₂) : l₁ = l₂ := by
  induction' s₁ with a l₁ h₁ s₁ IH generalizing l₂
  · exact p.nil_eq
  · have : a ∈ l₂ := p.subset (mem_cons_self _ _)
    rcases mem_split this with ⟨u₂, v₂, rfl⟩
    have p' := (perm_cons a).1 (p.trans perm_middle)
    obtain rfl := IH p' (s₂.sublist <| by simp)
    change a :: u₂ ++ v₂ = u₂ ++ ([a] ++ v₂)
    rw [← append_assoc]
    congr
    have : ∀ x ∈ u₂, x = a := fun x m =>
      antisymm ((pairwise_append.1 s₂).2.2 _ m a (mem_cons_self _ _)) (h₁ _ (by simp [m]))
    rw [(@eq_replicate _ a (length u₂ + 1) (a :: u₂)).2,
          (@eq_replicate _ a (length u₂ + 1) (u₂ ++ [a])).2] <;>
        constructor <;>
      

Proof state:
case cons.intro.intro.e_a.right
α : Type uu
r : α → α → Prop
a✝ : α
l : List α
inst✝ : IsAntisymm α r
l₁ : List α
a : α
u₂ v₂ : List α
s₂ : Sorted r (u₂ ++ a :: v₂)
this✝ : a ∈ u₂ ++ a :: v₂
h₁ : ∀ a' ∈ u₂ ++ v₂, r a a'
s₁ : Pairwise r (u₂ ++ v₂)
IH : ∀ {l₂ : List α}, u₂ ++ v₂ ~ l₂ → Sorted r l₂ → u₂ ++ v₂ = l₂
p : a :: (u₂ ++ v₂) ~ u₂ ++ a :: v₂
p' : u₂ ++ v₂ ~ u₂ ++ v₂
this : ∀ x ∈ u₂, x = a
⊢ ∀ b ∈ u₂ ++ [a], b = a

Next tactic:
simp [iff_true_intro this, or_comm]
theorem eq_of_perm_of_sorted [IsAntisymm α r] {l₁ l₂ : List α} (p : l₁ ~ l₂) (s₁ : Sorted r l₁)
    (s₂ : Sorted r l₂) : l₁ = l₂ := by
  induction' s₁ with a l₁ h₁ s₁ IH generalizing l₂
  · exact p.nil_eq
  · have : a ∈ l₂ := p.subset (mem_cons_self _ _)
    rcases mem_split this with ⟨u₂, v₂, rfl⟩
    have p' := (perm_cons a).1 (p.trans perm_middle)
    obtain rfl := IH p' (s₂.sublist <| by simp)
    change a :: u₂ ++ v₂ = u₂ ++ ([a] ++ v₂)
    rw [← append_assoc]
    congr
    have : ∀ x ∈ u₂, x = a := fun x m =>
      antisymm ((pairwise_append.1 s₂).2.2 _ m a (mem_cons_self _ _)) (h₁ _ (by simp [m]))
    rw [(@eq_replicate _ a (length u₂ + 1) (a :: u₂)).2,
          (@eq_replicate _ a (length u₂ + 1) (u₂ ++ [a])).2] <;>
        constructor <;>
      

Proof state:
case cons.intro.intro.e_a.left
α : Type uu
r : α → α → Prop
a✝ : α
l : List α
inst✝ : IsAntisymm α r
l₁ : List α
a : α
u₂ v₂ : List α
s₂ : Sorted r (u₂ ++ a :: v₂)
this✝ : a ∈ u₂ ++ a :: v₂
h₁ : ∀ a' ∈ u₂ ++ v₂, r a a'
s₁ : Pairwise r (u₂ ++ v₂)
IH : ∀ {l₂ : List α}, u₂ ++ v₂ ~ l₂ → Sorted r l₂ → u₂ ++ v₂ = l₂
p : a :: (u₂ ++ v₂) ~ u₂ ++ a :: v₂
p' : u₂ ++ v₂ ~ u₂ ++ v₂
this : ∀ x ∈ u₂, x = a
⊢ length (a :: u₂) = length u₂ + 1

Next tactic:
simp [iff_true_intro this, or_comm]
theorem eq_of_perm_of_sorted [IsAntisymm α r] {l₁ l₂ : List α} (p : l₁ ~ l₂) (s₁ : Sorted r l₁)
    (s₂ : Sorted r l₂) : l₁ = l₂ := by
  induction' s₁ with a l₁ h₁ s₁ IH generalizing l₂
  · exact p.nil_eq
  · have : a ∈ l₂ := p.subset (mem_cons_self _ _)
    rcases mem_split this with ⟨u₂, v₂, rfl⟩
    have p' := (perm_cons a).1 (p.trans perm_middle)
    obtain rfl := IH p' (s₂.sublist <| by simp)
    change a :: u₂ ++ v₂ = u₂ ++ ([a] ++ v₂)
    rw [← append_assoc]
    congr
    have : ∀ x ∈ u₂, x = a := fun x m =>
      antisymm ((pairwise_append.1 s₂).2.2 _ m a (mem_cons_self _ _)) (h₁ _ (by simp [m]))
    rw [(@eq_replicate _ a (length u₂ + 1) (a :: u₂)).2,
          (@eq_replicate _ a (length u₂ + 1) (u₂ ++ [a])).2] <;>
        constructor <;>
      

Proof state:
case cons.intro.intro.e_a.right
α : Type uu
r : α → α → Prop
a✝ : α
l : List α
inst✝ : IsAntisymm α r
l₁ : List α
a : α
u₂ v₂ : List α
s₂ : Sorted r (u₂ ++ a :: v₂)
this✝ : a ∈ u₂ ++ a :: v₂
h₁ : ∀ a' ∈ u₂ ++ v₂, r a a'
s₁ : Pairwise r (u₂ ++ v₂)
IH : ∀ {l₂ : List α}, u₂ ++ v₂ ~ l₂ → Sorted r l₂ → u₂ ++ v₂ = l₂
p : a :: (u₂ ++ v₂) ~ u₂ ++ a :: v₂
p' : u₂ ++ v₂ ~ u₂ ++ v₂
this : ∀ x ∈ u₂, x = a
⊢ ∀ b ∈ a :: u₂, b = a

Next tactic:
simp [iff_true_intro this, or_comm]
theorem sublist_of_subperm_of_sorted [IsAntisymm α r] {l₁ l₂ : List α} (p : l₁ <+~ l₂)
    (s₁ : l₁.Sorted r) (s₂ : l₂.Sorted r) : l₁ <+ l₂ := by
  

Proof state:
α : Type uu
r : α → α → Prop
a : α
l : List α
inst✝ : IsAntisymm α r
l₁ l₂ : List α
p : l₁ <+~ l₂
s₁ : Sorted r l₁
s₂ : Sorted r l₂
⊢ l₁ <+ l₂

Next tactic:
let ⟨_, h, h'⟩ := p
theorem sublist_of_subperm_of_sorted [IsAntisymm α r] {l₁ l₂ : List α} (p : l₁ <+~ l₂)
    (s₁ : l₁.Sorted r) (s₂ : l₂.Sorted r) : l₁ <+ l₂ := by
  let ⟨_, h, h'⟩ := p
  

Proof state:
α : Type uu
r : α → α → Prop
a : α
l : List α
inst✝ : IsAntisymm α r
l₁ l₂ : List α
p : l₁ <+~ l₂
s₁ : Sorted r l₁
s₂ : Sorted r l₂
w✝ : List α
h : w✝ ~ l₁
h' : w✝ <+ l₂
⊢ l₁ <+ l₂

Next tactic:
rwa [← eq_of_perm_of_sorted h (s₂.sublist h') s₁]
theorem Sorted.rel_get_of_le [IsRefl α r] {l : List α} (h : l.Sorted r) {a b : Fin l.length}
    (hab : a ≤ b) : r (l.get a) (l.get b) := by
  

Proof state:
α : Type uu
r : α → α → Prop
a✝ : α
l✝ : List α
inst✝ : IsRefl α r
l : List α
h : Sorted r l
a b : Fin (length l)
hab : a ≤ b
⊢ r (get l a) (get l b)

Next tactic:
rcases hab.eq_or_lt with (rfl | hlt)
theorem Sorted.rel_get_of_le [IsRefl α r] {l : List α} (h : l.Sorted r) {a b : Fin l.length}
    (hab : a ≤ b) : r (l.get a) (l.get b) := by
  rcases hab.eq_or_lt with (rfl | hlt)
  

Proof state:
case inl
α : Type uu
r : α → α → Prop
a✝ : α
l✝ : List α
inst✝ : IsRefl α r
l : List α
h : Sorted r l
a : Fin (length l)
hab : a ≤ a
⊢ r (get l a) (get l a)
case inr
α : Type uu
r : α → α → Prop
a✝ : α
l✝ : List α
inst✝ : IsRefl α r
l : List α
h : Sorted r l
a b : Fin (length l)
hab : a ≤ b
hlt : a < b
⊢ r (get l a) (get l b)

Next tactic:
exacts [refl _, h.rel_get_of_lt hlt]
theorem Sorted.rel_of_mem_take_of_mem_drop {l : List α} (h : List.Sorted r l) {k : ℕ} {x y : α}
    (hx : x ∈ List.take k l) (hy : y ∈ List.drop k l) : r x y := by
  

Proof state:
α : Type uu
r : α → α → Prop
a : α
l✝ l : List α
h : Sorted r l
k : ℕ
x y : α
hx : x ∈ take k l
hy : y ∈ drop k l
⊢ r x y

Next tactic:
obtain ⟨⟨iy, hiy⟩, rfl⟩ := get_of_mem hy
theorem Sorted.rel_of_mem_take_of_mem_drop {l : List α} (h : List.Sorted r l) {k : ℕ} {x y : α}
    (hx : x ∈ List.take k l) (hy : y ∈ List.drop k l) : r x y := by
  obtain ⟨⟨iy, hiy⟩, rfl⟩ := get_of_mem hy
  

Proof state:
case intro.mk
α : Type uu
r : α → α → Prop
a : α
l✝ l : List α
h : Sorted r l
k : ℕ
x : α
hx : x ∈ take k l
iy : ℕ
hiy : iy < length (drop k l)
hy : get (drop k l) { val := iy, isLt := hiy } ∈ drop k l
⊢ r x (get (drop k l) { val := iy, isLt := hiy })

Next tactic:
obtain ⟨⟨ix, hix⟩, rfl⟩ := get_of_mem hx
theorem Sorted.rel_of_mem_take_of_mem_drop {l : List α} (h : List.Sorted r l) {k : ℕ} {x y : α}
    (hx : x ∈ List.take k l) (hy : y ∈ List.drop k l) : r x y := by
  obtain ⟨⟨iy, hiy⟩, rfl⟩ := get_of_mem hy
  obtain ⟨⟨ix, hix⟩, rfl⟩ := get_of_mem hx
  

Proof state:
case intro.mk.intro.mk
α : Type uu
r : α → α → Prop
a : α
l✝ l : List α
h : Sorted r l
k iy : ℕ
hiy : iy < length (drop k l)
hy : get (drop k l) { val := iy, isLt := hiy } ∈ drop k l
ix : ℕ
hix : ix < length (take k l)
hx : get (take k l) { val := ix, isLt := hix } ∈ take k l
⊢ r (get (take k l) { val := ix, isLt := hix }) (get (drop k l) { val := iy, isLt := hiy })

Next tactic:
rw [get_take', get_drop']
theorem Sorted.rel_of_mem_take_of_mem_drop {l : List α} (h : List.Sorted r l) {k : ℕ} {x y : α}
    (hx : x ∈ List.take k l) (hy : y ∈ List.drop k l) : r x y := by
  obtain ⟨⟨iy, hiy⟩, rfl⟩ := get_of_mem hy
  obtain ⟨⟨ix, hix⟩, rfl⟩ := get_of_mem hx
  rw [get_take', get_drop']
  

Proof state:
case intro.mk.intro.mk
α : Type uu
r : α → α → Prop
a : α
l✝ l : List α
h : Sorted r l
k iy : ℕ
hiy : iy < length (drop k l)
hy : get (drop k l) { val := iy, isLt := hiy } ∈ drop k l
ix : ℕ
hix : ix < length (take k l)
hx : get (take k l) { val := ix, isLt := hix } ∈ take k l
⊢ r (get l { val := ↑{ val := ix, isLt := hix }, isLt := (_ : ↑{ val := ix, isLt := hix } < length l) })
    (get l { val := k + ↑{ val := iy, isLt := hiy }, isLt := (_ : k + ↑{ val := iy, isLt := hiy } < length l) })

Next tactic:
rw [length_take] at hix
theorem Sorted.rel_of_mem_take_of_mem_drop {l : List α} (h : List.Sorted r l) {k : ℕ} {x y : α}
    (hx : x ∈ List.take k l) (hy : y ∈ List.drop k l) : r x y := by
  obtain ⟨⟨iy, hiy⟩, rfl⟩ := get_of_mem hy
  obtain ⟨⟨ix, hix⟩, rfl⟩ := get_of_mem hx
  rw [get_take', get_drop']
  rw [length_take] at hix
  

Proof state:
case intro.mk.intro.mk
α : Type uu
r : α → α → Prop
a : α
l✝ l : List α
h : Sorted r l
k iy : ℕ
hiy : iy < length (drop k l)
hy : get (drop k l) { val := iy, isLt := hiy } ∈ drop k l
ix : ℕ
hix✝ : ix < length (take k l)
hix : ix < min k (length l)
hx : get (take k l) { val := ix, isLt := hix✝ } ∈ take k l
⊢ r (get l { val := ↑{ val := ix, isLt := hix✝ }, isLt := (_ : ↑{ val := ix, isLt := hix✝ } < length l) })
    (get l { val := k + ↑{ val := iy, isLt := hiy }, isLt := (_ : k + ↑{ val := iy, isLt := hiy } < length l) })

Next tactic:
exact h.rel_nthLe_of_lt _ _ (Nat.lt_add_right _ (lt_min_iff.mp hix).left)
theorem sorted_ofFn_iff {r : α → α → Prop} : (ofFn f).Sorted r ↔ ((· < ·) ⇒ r) f f := by
  

Proof state:
n : ℕ
α : Type uu
inst✝ : Preorder α
f : Fin n → α
r : α → α → Prop
⊢ Sorted r (ofFn f) ↔ ((fun x x_1 => x < x_1) ⇒ r) f f

Next tactic:
simp_rw [Sorted, pairwise_iff_get, get_ofFn, Relator.LiftFun]
theorem sorted_ofFn_iff {r : α → α → Prop} : (ofFn f).Sorted r ↔ ((· < ·) ⇒ r) f f := by
  simp_rw [Sorted, pairwise_iff_get, get_ofFn, Relator.LiftFun]
  

Proof state:
n : ℕ
α : Type uu
inst✝ : Preorder α
f : Fin n → α
r : α → α → Prop
⊢ (∀ (i j : Fin (length (ofFn f))),
      i < j → r (f (Fin.cast (_ : length (ofFn f) = n) i)) (f (Fin.cast (_ : length (ofFn f) = n) j))) ↔
    ∀ ⦃a b : Fin n⦄, a < b → r (f a) (f b)

Next tactic:
exact Iff.symm (Fin.rightInverse_cast _).surjective.forall₂
theorem orderedInsert_length : ∀ (L : List α) (a : α), (L.orderedInsert r a).length = L.length + 1
  | [], a => rfl
  | hd :: tl, a => by
    

Proof state:
α : Type uu
r : α → α → Prop
inst✝ : DecidableRel r
hd : α
tl : List α
a : α
⊢ length (orderedInsert r a (hd :: tl)) = length (hd :: tl) + 1

Next tactic:
dsimp [orderedInsert]
theorem orderedInsert_length : ∀ (L : List α) (a : α), (L.orderedInsert r a).length = L.length + 1
  | [], a => rfl
  | hd :: tl, a => by
    dsimp [orderedInsert]
    

Proof state:
α : Type uu
r : α → α → Prop
inst✝ : DecidableRel r
hd : α
tl : List α
a : α
⊢ length (if r a hd then a :: hd :: tl else hd :: orderedInsert r a tl) = Nat.succ (length tl) + 1

Next tactic:
split_ifs
theorem orderedInsert_length : ∀ (L : List α) (a : α), (L.orderedInsert r a).length = L.length + 1
  | [], a => rfl
  | hd :: tl, a => by
    dsimp [orderedInsert]
    split_ifs <;> 

Proof state:
case pos
α : Type uu
r : α → α → Prop
inst✝ : DecidableRel r
hd : α
tl : List α
a : α
h✝ : r a hd
⊢ length (a :: hd :: tl) = Nat.succ (length tl) + 1

Next tactic:
simp [orderedInsert_length tl]
theorem orderedInsert_length : ∀ (L : List α) (a : α), (L.orderedInsert r a).length = L.length + 1
  | [], a => rfl
  | hd :: tl, a => by
    dsimp [orderedInsert]
    split_ifs <;> 

Proof state:
case neg
α : Type uu
r : α → α → Prop
inst✝ : DecidableRel r
hd : α
tl : List α
a : α
h✝ : ¬r a hd
⊢ length (hd :: orderedInsert r a tl) = Nat.succ (length tl) + 1

Next tactic:
simp [orderedInsert_length tl]
/-- An alternative definition of `orderedInsert` using `takeWhile` and `dropWhile`. -/
theorem orderedInsert_eq_take_drop (a : α) :
    ∀ l : List α,
      l.orderedInsert r a = (l.takeWhile fun b => ¬a ≼ b) ++ a :: l.dropWhile fun b => ¬a ≼ b
  | [] => rfl
  | b :: l => by
    

Proof state:
α : Type uu
r : α → α → Prop
inst✝ : DecidableRel r
a b : α
l : List α
⊢ orderedInsert r a (b :: l) =
    takeWhile (fun b => decide ¬r a b) (b :: l) ++ a :: dropWhile (fun b => decide ¬r a b) (b :: l)

Next tactic:
dsimp only [orderedInsert]
/-- An alternative definition of `orderedInsert` using `takeWhile` and `dropWhile`. -/
theorem orderedInsert_eq_take_drop (a : α) :
    ∀ l : List α,
      l.orderedInsert r a = (l.takeWhile fun b => ¬a ≼ b) ++ a :: l.dropWhile fun b => ¬a ≼ b
  | [] => rfl
  | b :: l => by
    dsimp only [orderedInsert]
    

Proof state:
α : Type uu
r : α → α → Prop
inst✝ : DecidableRel r
a b : α
l : List α
⊢ (if r a b then a :: b :: l else b :: orderedInsert r a l) =
    takeWhile (fun b => decide ¬r a b) (b :: l) ++ a :: dropWhile (fun b => decide ¬r a b) (b :: l)

Next tactic:
split_ifs with h
/-- An alternative definition of `orderedInsert` using `takeWhile` and `dropWhile`. -/
theorem orderedInsert_eq_take_drop (a : α) :
    ∀ l : List α,
      l.orderedInsert r a = (l.takeWhile fun b => ¬a ≼ b) ++ a :: l.dropWhile fun b => ¬a ≼ b
  | [] => rfl
  | b :: l => by
    dsimp only [orderedInsert]
    split_ifs with h <;> 

Proof state:
case pos
α : Type uu
r : α → α → Prop
inst✝ : DecidableRel r
a b : α
l : List α
h : r a b
⊢ a :: b :: l = takeWhile (fun b => decide ¬r a b) (b :: l) ++ a :: dropWhile (fun b => decide ¬r a b) (b :: l)

Next tactic:
simp [takeWhile, dropWhile, *, orderedInsert_eq_take_drop a l]
/-- An alternative definition of `orderedInsert` using `takeWhile` and `dropWhile`. -/
theorem orderedInsert_eq_take_drop (a : α) :
    ∀ l : List α,
      l.orderedInsert r a = (l.takeWhile fun b => ¬a ≼ b) ++ a :: l.dropWhile fun b => ¬a ≼ b
  | [] => rfl
  | b :: l => by
    dsimp only [orderedInsert]
    split_ifs with h <;> 

Proof state:
case neg
α : Type uu
r : α → α → Prop
inst✝ : DecidableRel r
a b : α
l : List α
h : ¬r a b
⊢ b :: orderedInsert r a l =
    takeWhile (fun b => decide ¬r a b) (b :: l) ++ a :: dropWhile (fun b => decide ¬r a b) (b :: l)

Next tactic:
simp [takeWhile, dropWhile, *, orderedInsert_eq_take_drop a l]
theorem perm_orderedInsert (a) : ∀ l : List α, orderedInsert r a l ~ a :: l
  | [] => Perm.refl _
  | b :: l => by
    

Proof state:
α : Type uu
r : α → α → Prop
inst✝ : DecidableRel r
a b : α
l : List α
⊢ orderedInsert r a (b :: l) ~ a :: b :: l

Next tactic:
by_cases h : a ≼ b
theorem perm_orderedInsert (a) : ∀ l : List α, orderedInsert r a l ~ a :: l
  | [] => Perm.refl _
  | b :: l => by
    by_cases h : a ≼ b
    · 

Proof state:
case pos
α : Type uu
r : α → α → Prop
inst✝ : DecidableRel r
a b : α
l : List α
h : r a b
⊢ orderedInsert r a (b :: l) ~ a :: b :: l

Next tactic:
simp [orderedInsert, h]
theorem perm_orderedInsert (a) : ∀ l : List α, orderedInsert r a l ~ a :: l
  | [] => Perm.refl _
  | b :: l => by
    by_cases h : a ≼ b
    · simp [orderedInsert, h]
    · 

Proof state:
case neg
α : Type uu
r : α → α → Prop
inst✝ : DecidableRel r
a b : α
l : List α
h : ¬r a b
⊢ orderedInsert r a (b :: l) ~ a :: b :: l

Next tactic:
simpa [orderedInsert, h] using ((perm_orderedInsert a l).cons _).trans (Perm.swap _ _ _)
theorem orderedInsert_count [DecidableEq α] (L : List α) (a b : α) :
    count a (L.orderedInsert r b) = count a L + if a = b then 1 else 0 := by
  

Proof state:
α : Type uu
r : α → α → Prop
inst✝¹ : DecidableRel r
inst✝ : DecidableEq α
L : List α
a b : α
⊢ count a (orderedInsert r b L) = count a L + if a = b then 1 else 0

Next tactic:
rw [(L.perm_orderedInsert r b).count_eq, count_cons]
theorem perm_insertionSort : ∀ l : List α, insertionSort r l ~ l
  | [] => Perm.nil
  | b :: l => by
    

Proof state:
α : Type uu
r : α → α → Prop
inst✝ : DecidableRel r
b : α
l : List α
⊢ insertionSort r (b :: l) ~ b :: l

Next tactic:
simpa [insertionSort] using (perm_orderedInsert _ _ _).trans ((perm_insertionSort l).cons b)
/-- If `l` is already `List.Sorted` with respect to `r`, then `insertionSort` does not change
it. -/
theorem Sorted.insertionSort_eq : ∀ {l : List α}, Sorted r l → insertionSort r l = l
  | [], _ => rfl
  | [a], _ => rfl
  | a :: b :: l, h => by
    

Proof state:
α : Type uu
r : α → α → Prop
inst✝ : DecidableRel r
a b : α
l : List α
h : Sorted r (a :: b :: l)
⊢ insertionSort r (a :: b :: l) = a :: b :: l

Next tactic:
rw [insertionSort, Sorted.insertionSort_eq, orderedInsert, if_pos]
/-- If `l` is already `List.Sorted` with respect to `r`, then `insertionSort` does not change
it. -/
theorem Sorted.insertionSort_eq : ∀ {l : List α}, Sorted r l → insertionSort r l = l
  | [], _ => rfl
  | [a], _ => rfl
  | a :: b :: l, h => by
    rw [insertionSort, Sorted.insertionSort_eq, orderedInsert, if_pos]
    

Proof state:
case hc
α : Type uu
r : α → α → Prop
inst✝ : DecidableRel r
a b : α
l : List α
h : Sorted r (a :: b :: l)
⊢ r a b
α : Type uu r : α → α → Prop inst✝ : DecidableRel r a b : α l : List α h : Sorted r (a :: b :: l) ⊢ Sorted r (b :: l)

Next tactic:
exacts [rel_of_sorted_cons h _ (mem_cons_self _ _), h.tail]
theorem Sorted.orderedInsert (a : α) : ∀ l, Sorted r l → Sorted r (orderedInsert r a l)
  | [], _ => sorted_singleton a
  | b :: l, h => by
    

Proof state:
α : Type uu
r : α → α → Prop
inst✝² : DecidableRel r
inst✝¹ : IsTotal α r
inst✝ : IsTrans α r
a b : α
l : List α
h : Sorted r (b :: l)
⊢ Sorted r (List.orderedInsert r a (b :: l))

Next tactic:
by_cases h' : a ≼ b
theorem Sorted.orderedInsert (a : α) : ∀ l, Sorted r l → Sorted r (orderedInsert r a l)
  | [], _ => sorted_singleton a
  | b :: l, h => by
    by_cases h' : a ≼ b
    · -- Porting note: was
      -- `simpa [orderedInsert, h', h] using fun b' bm => trans h' (rel_of_sorted_cons h _ bm)`
      

Proof state:
case pos
α : Type uu
r : α → α → Prop
inst✝² : DecidableRel r
inst✝¹ : IsTotal α r
inst✝ : IsTrans α r
a b : α
l : List α
h : Sorted r (b :: l)
h' : r a b
⊢ Sorted r (List.orderedInsert r a (b :: l))

Next tactic:
rw [List.orderedInsert, if_pos h', sorted_cons]