l3lab/ntp-mathlib huggingface dataset:
theorem Sized.balance' {l x r} (hl : @Sized α l) (hr : Sized r) : Sized (balance' l x r) := by
  unfold balance'; split_ifs
  · 

Proof state:
case pos
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
hl : Sized l
hr : Sized r
h✝ : size l + size r ≤ 1
⊢ Sized (Ordnode.node' l x r)

Next tactic:
exact hl.node' hr
theorem Sized.balance' {l x r} (hl : @Sized α l) (hr : Sized r) : Sized (balance' l x r) := by
  unfold balance'; split_ifs
  · exact hl.node' hr
  · 

Proof state:
case pos
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
hl : Sized l
hr : Sized r
h✝¹ : ¬size l + size r ≤ 1
h✝ : size r > delta * size l
⊢ Sized (Ordnode.rotateL l x r)

Next tactic:
exact hl.rotateL hr
theorem Sized.balance' {l x r} (hl : @Sized α l) (hr : Sized r) : Sized (balance' l x r) := by
  unfold balance'; split_ifs
  · exact hl.node' hr
  · exact hl.rotateL hr
  · 

Proof state:
case pos
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
hl : Sized l
hr : Sized r
h✝² : ¬size l + size r ≤ 1
h✝¹ : ¬size r > delta * size l
h✝ : size l > delta * size r
⊢ Sized (Ordnode.rotateR l x r)

Next tactic:
exact hl.rotateR hr
theorem Sized.balance' {l x r} (hl : @Sized α l) (hr : Sized r) : Sized (balance' l x r) := by
  unfold balance'; split_ifs
  · exact hl.node' hr
  · exact hl.rotateL hr
  · exact hl.rotateR hr
  · 

Proof state:
case neg
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
hl : Sized l
hr : Sized r
h✝² : ¬size l + size r ≤ 1
h✝¹ : ¬size r > delta * size l
h✝ : ¬size l > delta * size r
⊢ Sized (Ordnode.node' l x r)

Next tactic:
exact hl.node' hr
theorem size_balance' {l x r} (hl : @Sized α l) (hr : Sized r) :
    size (@balance' α l x r) = size l + size r + 1 := by
  

Proof state:
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
hl : Sized l
hr : Sized r
⊢ size (balance' l x r) = size l + size r + 1

Next tactic:
unfold balance'
theorem size_balance' {l x r} (hl : @Sized α l) (hr : Sized r) :
    size (@balance' α l x r) = size l + size r + 1 := by
  unfold balance'; 

Proof state:
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
hl : Sized l
hr : Sized r
⊢ size
      (if size l + size r ≤ 1 then node' l x r
      else
        if size r > delta * size l then rotateL l x r
        else if size l > delta * size r then rotateR l x r else node' l x r) =
    size l + size r + 1

Next tactic:
split_ifs
theorem size_balance' {l x r} (hl : @Sized α l) (hr : Sized r) :
    size (@balance' α l x r) = size l + size r + 1 := by
  unfold balance'; split_ifs
  · 

Proof state:
case pos
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
hl : Sized l
hr : Sized r
h✝ : size l + size r ≤ 1
⊢ size (node' l x r) = size l + size r + 1

Next tactic:
rfl
theorem size_balance' {l x r} (hl : @Sized α l) (hr : Sized r) :
    size (@balance' α l x r) = size l + size r + 1 := by
  unfold balance'; split_ifs
  · rfl
  · 

Proof state:
case pos
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
hl : Sized l
hr : Sized r
h✝¹ : ¬size l + size r ≤ 1
h✝ : size r > delta * size l
⊢ size (rotateL l x r) = size l + size r + 1

Next tactic:
exact hr.rotateL_size
theorem size_balance' {l x r} (hl : @Sized α l) (hr : Sized r) :
    size (@balance' α l x r) = size l + size r + 1 := by
  unfold balance'; split_ifs
  · rfl
  · exact hr.rotateL_size
  · 

Proof state:
case pos
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
hl : Sized l
hr : Sized r
h✝² : ¬size l + size r ≤ 1
h✝¹ : ¬size r > delta * size l
h✝ : size l > delta * size r
⊢ size (rotateR l x r) = size l + size r + 1

Next tactic:
exact hl.rotateR_size
theorem size_balance' {l x r} (hl : @Sized α l) (hr : Sized r) :
    size (@balance' α l x r) = size l + size r + 1 := by
  unfold balance'; split_ifs
  · rfl
  · exact hr.rotateL_size
  · exact hl.rotateR_size
  · 

Proof state:
case neg
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
hl : Sized l
hr : Sized r
h✝² : ¬size l + size r ≤ 1
h✝¹ : ¬size r > delta * size l
h✝ : ¬size l > delta * size r
⊢ size (node' l x r) = size l + size r + 1

Next tactic:
rfl
theorem any_singleton {P : α → Prop} {x : α} : Any P (singleton x) ↔ P x :=
  ⟨by 

Proof state:
α : Type u_1
P : α → Prop
x : α
⊢ Any P {x} → P x

Next tactic:
rintro (⟨⟨⟩⟩ | h | ⟨⟨⟩⟩)
theorem any_singleton {P : α → Prop} {x : α} : Any P (singleton x) ↔ P x :=
  ⟨by rintro (⟨⟨⟩⟩ | h | ⟨⟨⟩⟩); 

Proof state:
case inr.inl
α : Type u_1
P : α → Prop
x : α
h : P x
⊢ P x

Next tactic:
exact h
theorem all_iff_forall {P : α → Prop} : ∀ {t}, All P t ↔ ∀ x, Emem x t → P x
  | nil => (iff_true_intro <| by 

Proof state:
α : Type u_1
P : α → Prop
⊢ ∀ (x : α), Emem x nil → P x

Next tactic:
rintro _ ⟨⟩
theorem all_iff_forall {P : α → Prop} : ∀ {t}, All P t ↔ ∀ x, Emem x t → P x
  | nil => (iff_true_intro <| by rintro _ ⟨⟩).symm
  | node _ l x r => by 

Proof state:
α : Type u_1
P : α → Prop
size✝ : ℕ
l : Ordnode α
x : α
r : Ordnode α
⊢ All P (node size✝ l x r) ↔ ∀ (x_1 : α), Emem x_1 (node size✝ l x r) → P x_1

Next tactic:
simp [All, Emem, all_iff_forall, Any, or_imp, forall_and]
theorem any_iff_exists {P : α → Prop} : ∀ {t}, Any P t ↔ ∃ x, Emem x t ∧ P x
  | nil => ⟨by 

Proof state:
α : Type u_1
P : α → Prop
⊢ Any P nil → ∃ x, Emem x nil ∧ P x

Next tactic:
rintro ⟨⟩
theorem any_iff_exists {P : α → Prop} : ∀ {t}, Any P t ↔ ∃ x, Emem x t ∧ P x
  | nil => ⟨by rintro ⟨⟩, by 

Proof state:
α : Type u_1
P : α → Prop
⊢ (∃ x, Emem x nil ∧ P x) → Any P nil

Next tactic:
rintro ⟨_, ⟨⟩, _⟩
theorem any_iff_exists {P : α → Prop} : ∀ {t}, Any P t ↔ ∃ x, Emem x t ∧ P x
  | nil => ⟨by rintro ⟨⟩, by rintro ⟨_, ⟨⟩, _⟩⟩
  | node _ l x r => by 

Proof state:
α : Type u_1
P : α → Prop
size✝ : ℕ
l : Ordnode α
x : α
r : Ordnode α
⊢ Any P (node size✝ l x r) ↔ ∃ x_1, Emem x_1 (node size✝ l x r) ∧ P x_1

Next tactic:
simp only [Emem]
theorem any_iff_exists {P : α → Prop} : ∀ {t}, Any P t ↔ ∃ x, Emem x t ∧ P x
  | nil => ⟨by rintro ⟨⟩, by rintro ⟨_, ⟨⟩, _⟩⟩
  | node _ l x r => by simp only [Emem]; 

Proof state:
α : Type u_1
P : α → Prop
size✝ : ℕ
l : Ordnode α
x : α
r : Ordnode α
⊢ Any P (node size✝ l x r) ↔ ∃ x_1, Any (Eq x_1) (node size✝ l x r) ∧ P x_1

Next tactic:
simp [Any, any_iff_exists, or_and_right, exists_or]
theorem all_node3L {P l x m y r} :
    @All α P (node3L l x m y r) ↔ All P l ∧ P x ∧ All P m ∧ P y ∧ All P r := by
  

Proof state:
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
m : Ordnode α
y : α
r : Ordnode α
⊢ All P (node3L l x m y r) ↔ All P l ∧ P x ∧ All P m ∧ P y ∧ All P r

Next tactic:
simp [node3L, all_node', and_assoc]
theorem all_node4L {P l x m y r} :
    @All α P (node4L l x m y r) ↔ All P l ∧ P x ∧ All P m ∧ P y ∧ All P r := by
  

Proof state:
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
m : Ordnode α
y : α
r : Ordnode α
⊢ All P (node4L l x m y r) ↔ All P l ∧ P x ∧ All P m ∧ P y ∧ All P r

Next tactic:
cases m
theorem all_node4L {P l x m y r} :
    @All α P (node4L l x m y r) ↔ All P l ∧ P x ∧ All P m ∧ P y ∧ All P r := by
  cases m <;> 

Proof state:
case nil
α : Type u_1
P : α → Prop
l : Ordnode α
x y : α
r : Ordnode α
⊢ All P (node4L l x nil y r) ↔ All P l ∧ P x ∧ All P nil ∧ P y ∧ All P r

Next tactic:
simp [node4L, all_node', All, all_node3L, and_assoc]
theorem all_node4L {P l x m y r} :
    @All α P (node4L l x m y r) ↔ All P l ∧ P x ∧ All P m ∧ P y ∧ All P r := by
  cases m <;> 

Proof state:
case node
α : Type u_1
P : α → Prop
l : Ordnode α
x y : α
r : Ordnode α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
⊢ All P (node4L l x (node size✝ l✝ x✝ r✝) y r) ↔ All P l ∧ P x ∧ All P (node size✝ l✝ x✝ r✝) ∧ P y ∧ All P r

Next tactic:
simp [node4L, all_node', All, all_node3L, and_assoc]
theorem all_node4R {P l x m y r} :
    @All α P (node4R l x m y r) ↔ All P l ∧ P x ∧ All P m ∧ P y ∧ All P r := by
  

Proof state:
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
m : Ordnode α
y : α
r : Ordnode α
⊢ All P (node4R l x m y r) ↔ All P l ∧ P x ∧ All P m ∧ P y ∧ All P r

Next tactic:
cases m
theorem all_node4R {P l x m y r} :
    @All α P (node4R l x m y r) ↔ All P l ∧ P x ∧ All P m ∧ P y ∧ All P r := by
  cases m <;> 

Proof state:
case nil
α : Type u_1
P : α → Prop
l : Ordnode α
x y : α
r : Ordnode α
⊢ All P (node4R l x nil y r) ↔ All P l ∧ P x ∧ All P nil ∧ P y ∧ All P r

Next tactic:
simp [node4R, all_node', All, all_node3R, and_assoc]
theorem all_node4R {P l x m y r} :
    @All α P (node4R l x m y r) ↔ All P l ∧ P x ∧ All P m ∧ P y ∧ All P r := by
  cases m <;> 

Proof state:
case node
α : Type u_1
P : α → Prop
l : Ordnode α
x y : α
r : Ordnode α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
⊢ All P (node4R l x (node size✝ l✝ x✝ r✝) y r) ↔ All P l ∧ P x ∧ All P (node size✝ l✝ x✝ r✝) ∧ P y ∧ All P r

Next tactic:
simp [node4R, all_node', All, all_node3R, and_assoc]
theorem all_rotateL {P l x r} : @All α P (rotateL l x r) ↔ All P l ∧ P x ∧ All P r := by
  

Proof state:
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
r : Ordnode α
⊢ All P (rotateL l x r) ↔ All P l ∧ P x ∧ All P r

Next tactic:
cases r
theorem all_rotateL {P l x r} : @All α P (rotateL l x r) ↔ All P l ∧ P x ∧ All P r := by
  cases r <;> 

Proof state:
case nil
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
⊢ All P (rotateL l x nil) ↔ All P l ∧ P x ∧ All P nil

Next tactic:
simp [rotateL, all_node']
theorem all_rotateL {P l x r} : @All α P (rotateL l x r) ↔ All P l ∧ P x ∧ All P r := by
  cases r <;> 

Proof state:
case node
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
⊢ All P (rotateL l x (node size✝ l✝ x✝ r✝)) ↔ All P l ∧ P x ∧ All P (node size✝ l✝ x✝ r✝)

Next tactic:
simp [rotateL, all_node']
theorem all_rotateL {P l x r} : @All α P (rotateL l x r) ↔ All P l ∧ P x ∧ All P r := by
  cases r <;> simp [rotateL, all_node']; 

Proof state:
case node
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
⊢ All P (if size l✝ < ratio * size r✝ then node3L l x l✝ x✝ r✝ else node4L l x l✝ x✝ r✝) ↔
    All P l ∧ P x ∧ All P (node size✝ l✝ x✝ r✝)

Next tactic:
split_ifs
theorem all_rotateL {P l x r} : @All α P (rotateL l x r) ↔ All P l ∧ P x ∧ All P r := by
  cases r <;> simp [rotateL, all_node']; split_ifs <;>
    

Proof state:
case pos
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
h✝ : size l✝ < ratio * size r✝
⊢ All P (node3L l x l✝ x✝ r✝) ↔ All P l ∧ P x ∧ All P (node size✝ l✝ x✝ r✝)

Next tactic:
simp [all_node3L, all_node4L, All, and_assoc]
theorem all_rotateL {P l x r} : @All α P (rotateL l x r) ↔ All P l ∧ P x ∧ All P r := by
  cases r <;> simp [rotateL, all_node']; split_ifs <;>
    

Proof state:
case neg
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
h✝ : ¬size l✝ < ratio * size r✝
⊢ All P (node4L l x l✝ x✝ r✝) ↔ All P l ∧ P x ∧ All P (node size✝ l✝ x✝ r✝)

Next tactic:
simp [all_node3L, all_node4L, All, and_assoc]
theorem all_rotateR {P l x r} : @All α P (rotateR l x r) ↔ All P l ∧ P x ∧ All P r := by
  

Proof state:
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
r : Ordnode α
⊢ All P (rotateR l x r) ↔ All P l ∧ P x ∧ All P r

Next tactic:
rw [← all_dual, dual_rotateR, all_rotateL]
theorem all_rotateR {P l x r} : @All α P (rotateR l x r) ↔ All P l ∧ P x ∧ All P r := by
  rw [← all_dual, dual_rotateR, all_rotateL]; 

Proof state:
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
r : Ordnode α
⊢ All P (dual r) ∧ P x ∧ All P (dual l) ↔ All P l ∧ P x ∧ All P r

Next tactic:
simp [all_dual, and_comm, and_left_comm, and_assoc]
theorem all_balance' {P l x r} : @All α P (balance' l x r) ↔ All P l ∧ P x ∧ All P r := by
  

Proof state:
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
r : Ordnode α
⊢ All P (balance' l x r) ↔ All P l ∧ P x ∧ All P r

Next tactic:
rw [balance']
theorem all_balance' {P l x r} : @All α P (balance' l x r) ↔ All P l ∧ P x ∧ All P r := by
  rw [balance']; 

Proof state:
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
r : Ordnode α
⊢ All P
      (if size l + size r ≤ 1 then node' l x r
      else
        if size r > delta * size l then rotateL l x r
        else if size l > delta * size r then rotateR l x r else node' l x r) ↔
    All P l ∧ P x ∧ All P r

Next tactic:
split_ifs
theorem all_balance' {P l x r} : @All α P (balance' l x r) ↔ All P l ∧ P x ∧ All P r := by
  rw [balance']; split_ifs <;> 

Proof state:
case pos
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
r : Ordnode α
h✝ : size l + size r ≤ 1
⊢ All P (node' l x r) ↔ All P l ∧ P x ∧ All P r

Next tactic:
simp [all_node', all_rotateL, all_rotateR]
theorem all_balance' {P l x r} : @All α P (balance' l x r) ↔ All P l ∧ P x ∧ All P r := by
  rw [balance']; split_ifs <;> 

Proof state:
case pos
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
r : Ordnode α
h✝¹ : ¬size l + size r ≤ 1
h✝ : size r > delta * size l
⊢ All P (rotateL l x r) ↔ All P l ∧ P x ∧ All P r

Next tactic:
simp [all_node', all_rotateL, all_rotateR]
theorem all_balance' {P l x r} : @All α P (balance' l x r) ↔ All P l ∧ P x ∧ All P r := by
  rw [balance']; split_ifs <;> 

Proof state:
case pos
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
r : Ordnode α
h✝² : ¬size l + size r ≤ 1
h✝¹ : ¬size r > delta * size l
h✝ : size l > delta * size r
⊢ All P (rotateR l x r) ↔ All P l ∧ P x ∧ All P r

Next tactic:
simp [all_node', all_rotateL, all_rotateR]
theorem all_balance' {P l x r} : @All α P (balance' l x r) ↔ All P l ∧ P x ∧ All P r := by
  rw [balance']; split_ifs <;> 

Proof state:
case neg
α : Type u_1
P : α → Prop
l : Ordnode α
x : α
r : Ordnode α
h✝² : ¬size l + size r ≤ 1
h✝¹ : ¬size r > delta * size l
h✝ : ¬size l > delta * size r
⊢ All P (node' l x r) ↔ All P l ∧ P x ∧ All P r

Next tactic:
simp [all_node', all_rotateL, all_rotateR]
theorem foldr_cons_eq_toList : ∀ (t : Ordnode α) (r : List α), t.foldr List.cons r = toList t ++ r
  | nil, r => rfl
  | node _ l x r, r' => by
    

Proof state:
α : Type u_1
size✝ : ℕ
l : Ordnode α
x : α
r : Ordnode α
r' : List α
⊢ foldr List.cons (node size✝ l x r) r' = toList (node size✝ l x r) ++ r'

Next tactic:
rw [foldr, foldr_cons_eq_toList l, foldr_cons_eq_toList r, ← List.cons_append,
        ← List.append_assoc, ← foldr_cons_eq_toList l]
theorem foldr_cons_eq_toList : ∀ (t : Ordnode α) (r : List α), t.foldr List.cons r = toList t ++ r
  | nil, r => rfl
  | node _ l x r, r' => by
    rw [foldr, foldr_cons_eq_toList l, foldr_cons_eq_toList r, ← List.cons_append,
        ← List.append_assoc, ← foldr_cons_eq_toList l]; 

Proof state:
α : Type u_1
size✝ : ℕ
l : Ordnode α
x : α
r : Ordnode α
r' : List α
⊢ foldr List.cons l (x :: toList r) ++ r' = toList (node size✝ l x r) ++ r'

Next tactic:
rfl
@[simp]
theorem toList_node (s l x r) : toList (@node α s l x r) = toList l ++ x :: toList r := by
  

Proof state:
α : Type u_1
s : ℕ
l : Ordnode α
x : α
r : Ordnode α
⊢ toList (node s l x r) = toList l ++ x :: toList r

Next tactic:
rw [toList, foldr, foldr_cons_eq_toList]
@[simp]
theorem toList_node (s l x r) : toList (@node α s l x r) = toList l ++ x :: toList r := by
  rw [toList, foldr, foldr_cons_eq_toList]; 

Proof state:
α : Type u_1
s : ℕ
l : Ordnode α
x : α
r : Ordnode α
⊢ toList l ++ x :: foldr List.cons r [] = toList l ++ x :: toList r

Next tactic:
rfl
theorem emem_iff_mem_toList {x : α} {t} : Emem x t ↔ x ∈ toList t := by
  

Proof state:
α : Type u_1
x : α
t : Ordnode α
⊢ Emem x t ↔ x ∈ toList t

Next tactic:
unfold Emem
theorem emem_iff_mem_toList {x : α} {t} : Emem x t ↔ x ∈ toList t := by
  unfold Emem; 

Proof state:
α : Type u_1
x : α
t : Ordnode α
⊢ Any (Eq x) t ↔ x ∈ toList t

Next tactic:
induction t
theorem emem_iff_mem_toList {x : α} {t} : Emem x t ↔ x ∈ toList t := by
  unfold Emem; induction t <;> 

Proof state:
case nil
α : Type u_1
x : α
⊢ Any (Eq x) nil ↔ x ∈ toList nil

Next tactic:
simp [Any, *, or_assoc]
theorem emem_iff_mem_toList {x : α} {t} : Emem x t ↔ x ∈ toList t := by
  unfold Emem; induction t <;> 

Proof state:
case node
α : Type u_1
x : α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
l_ih✝ : Any (Eq x) l✝ ↔ x ∈ toList l✝
r_ih✝ : Any (Eq x) r✝ ↔ x ∈ toList r✝
⊢ Any (Eq x) (node size✝ l✝ x✝ r✝) ↔ x ∈ toList (node size✝ l✝ x✝ r✝)

Next tactic:
simp [Any, *, or_assoc]
theorem length_toList' : ∀ t : Ordnode α, (toList t).length = t.realSize
  | nil => rfl
  | node _ l _ r => by
    

Proof state:
α : Type u_1
size✝ : ℕ
l : Ordnode α
x✝ : α
r : Ordnode α
⊢ List.length (toList (node size✝ l x✝ r)) = realSize (node size✝ l x✝ r)

Next tactic:
rw [toList_node, List.length_append, List.length_cons, length_toList' l,
        length_toList' r]
theorem length_toList' : ∀ t : Ordnode α, (toList t).length = t.realSize
  | nil => rfl
  | node _ l _ r => by
    rw [toList_node, List.length_append, List.length_cons, length_toList' l,
        length_toList' r]; 

Proof state:
α : Type u_1
size✝ : ℕ
l : Ordnode α
x✝ : α
r : Ordnode α
⊢ realSize l + Nat.succ (realSize r) = realSize (node size✝ l x✝ r)

Next tactic:
rfl
theorem length_toList {t : Ordnode α} (h : Sized t) : (toList t).length = t.size := by
  

Proof state:
α : Type u_1
t : Ordnode α
h : Sized t
⊢ List.length (toList t) = size t

Next tactic:
rw [length_toList', size_eq_realSize h]
theorem equiv_iff {t₁ t₂ : Ordnode α} (h₁ : Sized t₁) (h₂ : Sized t₂) :
    Equiv t₁ t₂ ↔ toList t₁ = toList t₂ :=
  and_iff_right_of_imp fun h => by 

Proof state:
α : Type u_1
t₁ t₂ : Ordnode α
h₁ : Sized t₁
h₂ : Sized t₂
h : toList t₁ = toList t₂
⊢ size t₁ = size t₂

Next tactic:
rw [← length_toList h₁, h, length_toList h₂]
theorem pos_size_of_mem [LE α] [@DecidableRel α (· ≤ ·)] {x : α} {t : Ordnode α} (h : Sized t)
    (h_mem : x ∈ t) : 0 < size t := by 

Proof state:
α : Type u_1
inst✝¹ : LE α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
x : α
t : Ordnode α
h : Sized t
h_mem : x ∈ t
⊢ 0 < size t

Next tactic:
cases t
theorem pos_size_of_mem [LE α] [@DecidableRel α (· ≤ ·)] {x : α} {t : Ordnode α} (h : Sized t)
    (h_mem : x ∈ t) : 0 < size t := by cases t; · 

Proof state:
case nil
α : Type u_1
inst✝¹ : LE α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
x : α
h : Sized nil
h_mem : x ∈ nil
⊢ 0 < size nil

Next tactic:
{ contradiction }
theorem pos_size_of_mem [LE α] [@DecidableRel α (· ≤ ·)] {x : α} {t : Ordnode α} (h : Sized t)
    (h_mem : x ∈ t) : 0 < size t := by cases t; · { 

Proof state:
case nil
α : Type u_1
inst✝¹ : LE α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
x : α
h : Sized nil
h_mem : x ∈ nil
⊢ 0 < size nil

Next tactic:
contradiction
theorem pos_size_of_mem [LE α] [@DecidableRel α (· ≤ ·)] {x : α} {t : Ordnode α} (h : Sized t)
    (h_mem : x ∈ t) : 0 < size t := by cases t; · { contradiction }; · 

Proof state:
case node
α : Type u_1
inst✝¹ : LE α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
x : α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
h : Sized (node size✝ l✝ x✝ r✝)
h_mem : x ∈ node size✝ l✝ x✝ r✝
⊢ 0 < size (node size✝ l✝ x✝ r✝)

Next tactic:
{ simp [h.1] }
theorem pos_size_of_mem [LE α] [@DecidableRel α (· ≤ ·)] {x : α} {t : Ordnode α} (h : Sized t)
    (h_mem : x ∈ t) : 0 < size t := by cases t; · { contradiction }; · { 

Proof state:
case node
α : Type u_1
inst✝¹ : LE α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
x : α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
h : Sized (node size✝ l✝ x✝ r✝)
h_mem : x ∈ node size✝ l✝ x✝ r✝
⊢ 0 < size (node size✝ l✝ x✝ r✝)

Next tactic:
simp [h.1]
theorem findMax'_dual (t) (x : α) : findMax' x (dual t) = findMin' t x := by
  

Proof state:
α : Type u_1
t : Ordnode α
x : α
⊢ findMax' x (dual t) = findMin' t x

Next tactic:
rw [← findMin'_dual, dual_dual]
theorem findMax_dual (t : Ordnode α) : findMax (dual t) = findMin t := by
  

Proof state:
α : Type u_1
t : Ordnode α
⊢ findMax (dual t) = findMin t

Next tactic:
rw [← findMin_dual, dual_dual]
theorem dual_eraseMin : ∀ t : Ordnode α, dual (eraseMin t) = eraseMax (dual t)
  | nil => rfl
  | node _ nil x r => rfl
  | node _ (node sz l' y r') x r => by
    

Proof state:
α : Type u_1
size✝ sz : ℕ
l' : Ordnode α
y : α
r' : Ordnode α
x : α
r : Ordnode α
⊢ dual (eraseMin (node size✝ (node sz l' y r') x r)) = eraseMax (dual (node size✝ (node sz l' y r') x r))

Next tactic:
rw [eraseMin, dual_balanceR, dual_eraseMin (node sz l' y r'), dual, dual, dual, eraseMax]
theorem dual_eraseMax (t : Ordnode α) : dual (eraseMax t) = eraseMin (dual t) := by
  

Proof state:
α : Type u_1
t : Ordnode α
⊢ dual (eraseMax t) = eraseMin (dual t)

Next tactic:
rw [← dual_dual (eraseMin _), dual_eraseMin, dual_dual]
theorem splitMin_eq :
    ∀ (s l) (x : α) (r), splitMin' l x r = (findMin' l x, eraseMin (node s l x r))
  | _, nil, x, r => rfl
  | _, node ls ll lx lr, x, r => by 

Proof state:
α : Type u_1
x✝ ls : ℕ
ll : Ordnode α
lx : α
lr : Ordnode α
x : α
r : Ordnode α
⊢ splitMin' (node ls ll lx lr) x r = (findMin' (node ls ll lx lr) x, eraseMin (node x✝ (node ls ll lx lr) x r))

Next tactic:
rw [splitMin', splitMin_eq ls ll lx lr, findMin', eraseMin]
theorem splitMax_eq :
    ∀ (s l) (x : α) (r), splitMax' l x r = (eraseMax (node s l x r), findMax' x r)
  | _, l, x, nil => rfl
  | _, l, x, node ls ll lx lr => by 

Proof state:
α : Type u_1
x✝ : ℕ
l : Ordnode α
x : α
ls : ℕ
ll : Ordnode α
lx : α
lr : Ordnode α
⊢ splitMax' l x (node ls ll lx lr) = (eraseMax (node x✝ l x (node ls ll lx lr)), findMax' x (node ls ll lx lr))

Next tactic:
rw [splitMax', splitMax_eq ls ll lx lr, findMax', eraseMax]
@[simp]
theorem merge_nil_left (t : Ordnode α) : merge t nil = t := by 

Proof state:
α : Type u_1
t : Ordnode α
⊢ merge t nil = t

Next tactic:
cases t
@[simp]
theorem merge_nil_left (t : Ordnode α) : merge t nil = t := by cases t <;> 

Proof state:
case nil
α : Type u_1
⊢ merge nil nil = nil

Next tactic:
rfl
@[simp]
theorem merge_nil_left (t : Ordnode α) : merge t nil = t := by cases t <;> 

Proof state:
case node
α : Type u_1
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
⊢ merge (node size✝ l✝ x✝ r✝) nil = node size✝ l✝ x✝ r✝

Next tactic:
rfl
theorem dual_insert [Preorder α] [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t : Ordnode α, dual (Ordnode.insert x t) = @Ordnode.insert αᵒᵈ _ _ x (dual t)
  | nil => rfl
  | node _ l y r => by
    

Proof state:
α : Type u_1
inst✝² : Preorder α
inst✝¹ : IsTotal α fun x x_1 => x ≤ x_1
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
x : α
size✝ : ℕ
l : Ordnode α
y : α
r : Ordnode α
⊢ dual (Ordnode.insert x (node size✝ l y r)) = Ordnode.insert x (dual (node size✝ l y r))

Next tactic:
have : @cmpLE αᵒᵈ _ _ x y = cmpLE y x := rfl
theorem dual_insert [Preorder α] [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t : Ordnode α, dual (Ordnode.insert x t) = @Ordnode.insert αᵒᵈ _ _ x (dual t)
  | nil => rfl
  | node _ l y r => by
    have : @cmpLE αᵒᵈ _ _ x y = cmpLE y x := rfl
    

Proof state:
α : Type u_1
inst✝² : Preorder α
inst✝¹ : IsTotal α fun x x_1 => x ≤ x_1
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
x : α
size✝ : ℕ
l : Ordnode α
y : α
r : Ordnode α
this : cmpLE x y = cmpLE y x
⊢ dual (Ordnode.insert x (node size✝ l y r)) = Ordnode.insert x (dual (node size✝ l y r))

Next tactic:
rw [Ordnode.insert, dual, Ordnode.insert, this, ← cmpLE_swap x y]
theorem dual_insert [Preorder α] [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t : Ordnode α, dual (Ordnode.insert x t) = @Ordnode.insert αᵒᵈ _ _ x (dual t)
  | nil => rfl
  | node _ l y r => by
    have : @cmpLE αᵒᵈ _ _ x y = cmpLE y x := rfl
    rw [Ordnode.insert, dual, Ordnode.insert, this, ← cmpLE_swap x y]
    

Proof state:
α : Type u_1
inst✝² : Preorder α
inst✝¹ : IsTotal α fun x x_1 => x ≤ x_1
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
x : α
size✝ : ℕ
l : Ordnode α
y : α
r : Ordnode α
this : cmpLE x y = cmpLE y x
⊢ dual
      (match cmpLE x y with
      | Ordering.lt => balanceL (Ordnode.insert x l) y r
      | Ordering.eq => node size✝ l x r
      | Ordering.gt => balanceR l y (Ordnode.insert x r)) =
    match Ordering.swap (cmpLE x y) with
    | Ordering.lt => balanceL (Ordnode.insert x (dual r)) y (dual l)
    | Ordering.eq => node size✝ (dual r) x (dual l)
    | Ordering.gt => balanceR (dual r) y (Ordnode.insert x (dual l))

Next tactic:
cases cmpLE x y