l3lab/ntp-mathlib huggingface dataset:
theorem insertWith.valid_aux [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (f : α → α) (x : α)
    (hf : ∀ y, x ≤ y ∧ y ≤ x → x ≤ f y ∧ f y ≤ x) :
    ∀ {t o₁ o₂},
      Valid' o₁ t o₂ →
        Bounded nil o₁ x →
          Bounded nil x o₂ →
            Valid' o₁ (insertWith f x t) o₂ ∧ Raised (size t) (size (insertWith f x t))
  | nil, o₁, o₂, _, bl, br => ⟨valid'_singleton bl br, Or.inr rfl⟩
  | node sz l y r, o₁, o₂, h, bl, br => by
    rw [insertWith, cmpLE]
    split_ifs with h_1 h_2 <;> dsimp only
    · rcases h with ⟨⟨lx, xr⟩, hs, hb⟩
      rcases hf _ ⟨h_1, h_2⟩ with ⟨xf, fx⟩
      refine'
        ⟨⟨⟨lx.mono_right (le_trans h_2 xf), xr.mono_left (le_trans fx h_1)⟩, hs, hb⟩, Or.inl rfl⟩
    · rcases insertWith.valid_aux f x hf h.left bl (lt_of_le_not_le h_1 h_2) with ⟨vl, e⟩
      suffices H : _ by
        refine' ⟨vl.balanceL h.right H, _⟩
        rw [size_balanceL vl.3 h.3.2.2 vl.2 h.2.2.2 H, h.2.size_eq]
        refine' (e.add_right _).add_right _
      · exact Or.inl ⟨_, e, h.3.1⟩
    · have : y < x := lt_of_le_not_le ((total_of (· ≤ ·) _ _).resolve_left h_1) h_1
      

Proof state:
case neg
α : Type u_1
inst✝² : Preorder α
inst✝¹ : IsTotal α fun x x_1 => x ≤ x_1
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
f : α → α
x : α
hf : ∀ (y : α), x ≤ y ∧ y ≤ x → x ≤ f y ∧ f y ≤ x
sz : ℕ
l : Ordnode α
y : α
r : Ordnode α
o₁ : WithBot α
o₂ : WithTop α
h : Valid' o₁ (node sz l y r) o₂
bl : Bounded nil o₁ ↑x
br : Bounded nil (↑x) o₂
h_1 : ¬x ≤ y
this : y < x
⊢ Valid' o₁ (balanceR l y (insertWith f x r)) o₂ ∧
    Raised (size (node sz l y r)) (size (balanceR l y (insertWith f x r)))

Next tactic:
rcases insertWith.valid_aux f x hf h.right this br with ⟨vr, e⟩
theorem insertWith.valid_aux [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (f : α → α) (x : α)
    (hf : ∀ y, x ≤ y ∧ y ≤ x → x ≤ f y ∧ f y ≤ x) :
    ∀ {t o₁ o₂},
      Valid' o₁ t o₂ →
        Bounded nil o₁ x →
          Bounded nil x o₂ →
            Valid' o₁ (insertWith f x t) o₂ ∧ Raised (size t) (size (insertWith f x t))
  | nil, o₁, o₂, _, bl, br => ⟨valid'_singleton bl br, Or.inr rfl⟩
  | node sz l y r, o₁, o₂, h, bl, br => by
    rw [insertWith, cmpLE]
    split_ifs with h_1 h_2 <;> dsimp only
    · rcases h with ⟨⟨lx, xr⟩, hs, hb⟩
      rcases hf _ ⟨h_1, h_2⟩ with ⟨xf, fx⟩
      refine'
        ⟨⟨⟨lx.mono_right (le_trans h_2 xf), xr.mono_left (le_trans fx h_1)⟩, hs, hb⟩, Or.inl rfl⟩
    · rcases insertWith.valid_aux f x hf h.left bl (lt_of_le_not_le h_1 h_2) with ⟨vl, e⟩
      suffices H : _ by
        refine' ⟨vl.balanceL h.right H, _⟩
        rw [size_balanceL vl.3 h.3.2.2 vl.2 h.2.2.2 H, h.2.size_eq]
        refine' (e.add_right _).add_right _
      · exact Or.inl ⟨_, e, h.3.1⟩
    · have : y < x := lt_of_le_not_le ((total_of (· ≤ ·) _ _).resolve_left h_1) h_1
      rcases insertWith.valid_aux f x hf h.right this br with ⟨vr, e⟩
      

Proof state:
case neg.intro
α : Type u_1
inst✝² : Preorder α
inst✝¹ : IsTotal α fun x x_1 => x ≤ x_1
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
f : α → α
x : α
hf : ∀ (y : α), x ≤ y ∧ y ≤ x → x ≤ f y ∧ f y ≤ x
sz : ℕ
l : Ordnode α
y : α
r : Ordnode α
o₁ : WithBot α
o₂ : WithTop α
h : Valid' o₁ (node sz l y r) o₂
bl : Bounded nil o₁ ↑x
br : Bounded nil (↑x) o₂
h_1 : ¬x ≤ y
this : y < x
vr : Valid' (↑y) (insertWith f x r) o₂
e : Raised (size r) (size (insertWith f x r))
⊢ Valid' o₁ (balanceR l y (insertWith f x r)) o₂ ∧
    Raised (size (node sz l y r)) (size (balanceR l y (insertWith f x r)))

Next tactic:
suffices H : _ by
        refine' ⟨h.left.balanceR vr H, _⟩
        rw [size_balanceR h.3.2.1 vr.3 h.2.2.1 vr.2 H, h.2.size_eq]
        refine' (e.add_left _).add_right _
theorem insertWith.valid_aux [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (f : α → α) (x : α)
    (hf : ∀ y, x ≤ y ∧ y ≤ x → x ≤ f y ∧ f y ≤ x) :
    ∀ {t o₁ o₂},
      Valid' o₁ t o₂ →
        Bounded nil o₁ x →
          Bounded nil x o₂ →
            Valid' o₁ (insertWith f x t) o₂ ∧ Raised (size t) (size (insertWith f x t))
  | nil, o₁, o₂, _, bl, br => ⟨valid'_singleton bl br, Or.inr rfl⟩
  | node sz l y r, o₁, o₂, h, bl, br => by
    rw [insertWith, cmpLE]
    split_ifs with h_1 h_2 <;> dsimp only
    · rcases h with ⟨⟨lx, xr⟩, hs, hb⟩
      rcases hf _ ⟨h_1, h_2⟩ with ⟨xf, fx⟩
      refine'
        ⟨⟨⟨lx.mono_right (le_trans h_2 xf), xr.mono_left (le_trans fx h_1)⟩, hs, hb⟩, Or.inl rfl⟩
    · rcases insertWith.valid_aux f x hf h.left bl (lt_of_le_not_le h_1 h_2) with ⟨vl, e⟩
      suffices H : _ by
        refine' ⟨vl.balanceL h.right H, _⟩
        rw [size_balanceL vl.3 h.3.2.2 vl.2 h.2.2.2 H, h.2.size_eq]
        refine' (e.add_right _).add_right _
      · exact Or.inl ⟨_, e, h.3.1⟩
    · have : y < x := lt_of_le_not_le ((total_of (· ≤ ·) _ _).resolve_left h_1) h_1
      rcases insertWith.valid_aux f x hf h.right this br with ⟨vr, e⟩
      suffices H : _ 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
f : α → α
x : α
hf : ∀ (y : α), x ≤ y ∧ y ≤ x → x ≤ f y ∧ f y ≤ x
sz : ℕ
l : Ordnode α
y : α
r : Ordnode α
o₁ : WithBot α
o₂ : WithTop α
h : Valid' o₁ (node sz l y r) o₂
bl : Bounded nil o₁ ↑x
br : Bounded nil (↑x) o₂
h_1 : ¬x ≤ y
this : y < x
vr : Valid' (↑y) (insertWith f x r) o₂
e : Raised (size r) (size (insertWith f x r))
H : ?m.369682
⊢ Valid' o₁ (balanceR l y (insertWith f x r)) o₂ ∧
    Raised (size (node sz l y r)) (size (balanceR l y (insertWith f x r)))

Next tactic:
refine' ⟨h.left.balanceR vr H, _⟩
theorem insertWith.valid_aux [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (f : α → α) (x : α)
    (hf : ∀ y, x ≤ y ∧ y ≤ x → x ≤ f y ∧ f y ≤ x) :
    ∀ {t o₁ o₂},
      Valid' o₁ t o₂ →
        Bounded nil o₁ x →
          Bounded nil x o₂ →
            Valid' o₁ (insertWith f x t) o₂ ∧ Raised (size t) (size (insertWith f x t))
  | nil, o₁, o₂, _, bl, br => ⟨valid'_singleton bl br, Or.inr rfl⟩
  | node sz l y r, o₁, o₂, h, bl, br => by
    rw [insertWith, cmpLE]
    split_ifs with h_1 h_2 <;> dsimp only
    · rcases h with ⟨⟨lx, xr⟩, hs, hb⟩
      rcases hf _ ⟨h_1, h_2⟩ with ⟨xf, fx⟩
      refine'
        ⟨⟨⟨lx.mono_right (le_trans h_2 xf), xr.mono_left (le_trans fx h_1)⟩, hs, hb⟩, Or.inl rfl⟩
    · rcases insertWith.valid_aux f x hf h.left bl (lt_of_le_not_le h_1 h_2) with ⟨vl, e⟩
      suffices H : _ by
        refine' ⟨vl.balanceL h.right H, _⟩
        rw [size_balanceL vl.3 h.3.2.2 vl.2 h.2.2.2 H, h.2.size_eq]
        refine' (e.add_right _).add_right _
      · exact Or.inl ⟨_, e, h.3.1⟩
    · have : y < x := lt_of_le_not_le ((total_of (· ≤ ·) _ _).resolve_left h_1) h_1
      rcases insertWith.valid_aux f x hf h.right this br with ⟨vr, e⟩
      suffices H : _ by
        refine' ⟨h.left.balanceR vr H, _⟩
        

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
f : α → α
x : α
hf : ∀ (y : α), x ≤ y ∧ y ≤ x → x ≤ f y ∧ f y ≤ x
sz : ℕ
l : Ordnode α
y : α
r : Ordnode α
o₁ : WithBot α
o₂ : WithTop α
h : Valid' o₁ (node sz l y r) o₂
bl : Bounded nil o₁ ↑x
br : Bounded nil (↑x) o₂
h_1 : ¬x ≤ y
this : y < x
vr : Valid' (↑y) (insertWith f x r) o₂
e : Raised (size r) (size (insertWith f x r))
H :
  (∃ l', Raised (size l) l' ∧ BalancedSz l' (size (insertWith f x r))) ∨
    ∃ r', Raised r' (size (insertWith f x r)) ∧ BalancedSz (size l) r'
⊢ Raised (size (node sz l y r)) (size (balanceR l y (insertWith f x r)))

Next tactic:
rw [size_balanceR h.3.2.1 vr.3 h.2.2.1 vr.2 H, h.2.size_eq]
theorem insertWith.valid_aux [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (f : α → α) (x : α)
    (hf : ∀ y, x ≤ y ∧ y ≤ x → x ≤ f y ∧ f y ≤ x) :
    ∀ {t o₁ o₂},
      Valid' o₁ t o₂ →
        Bounded nil o₁ x →
          Bounded nil x o₂ →
            Valid' o₁ (insertWith f x t) o₂ ∧ Raised (size t) (size (insertWith f x t))
  | nil, o₁, o₂, _, bl, br => ⟨valid'_singleton bl br, Or.inr rfl⟩
  | node sz l y r, o₁, o₂, h, bl, br => by
    rw [insertWith, cmpLE]
    split_ifs with h_1 h_2 <;> dsimp only
    · rcases h with ⟨⟨lx, xr⟩, hs, hb⟩
      rcases hf _ ⟨h_1, h_2⟩ with ⟨xf, fx⟩
      refine'
        ⟨⟨⟨lx.mono_right (le_trans h_2 xf), xr.mono_left (le_trans fx h_1)⟩, hs, hb⟩, Or.inl rfl⟩
    · rcases insertWith.valid_aux f x hf h.left bl (lt_of_le_not_le h_1 h_2) with ⟨vl, e⟩
      suffices H : _ by
        refine' ⟨vl.balanceL h.right H, _⟩
        rw [size_balanceL vl.3 h.3.2.2 vl.2 h.2.2.2 H, h.2.size_eq]
        refine' (e.add_right _).add_right _
      · exact Or.inl ⟨_, e, h.3.1⟩
    · have : y < x := lt_of_le_not_le ((total_of (· ≤ ·) _ _).resolve_left h_1) h_1
      rcases insertWith.valid_aux f x hf h.right this br with ⟨vr, e⟩
      suffices H : _ by
        refine' ⟨h.left.balanceR vr H, _⟩
        rw [size_balanceR h.3.2.1 vr.3 h.2.2.1 vr.2 H, h.2.size_eq]
        

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
f : α → α
x : α
hf : ∀ (y : α), x ≤ y ∧ y ≤ x → x ≤ f y ∧ f y ≤ x
sz : ℕ
l : Ordnode α
y : α
r : Ordnode α
o₁ : WithBot α
o₂ : WithTop α
h : Valid' o₁ (node sz l y r) o₂
bl : Bounded nil o₁ ↑x
br : Bounded nil (↑x) o₂
h_1 : ¬x ≤ y
this : y < x
vr : Valid' (↑y) (insertWith f x r) o₂
e : Raised (size r) (size (insertWith f x r))
H :
  (∃ l', Raised (size l) l' ∧ BalancedSz l' (size (insertWith f x r))) ∨
    ∃ r', Raised r' (size (insertWith f x r)) ∧ BalancedSz (size l) r'
⊢ Raised (size l + size r + 1) (size l + size (insertWith f x r) + 1)

Next tactic:
refine' (e.add_left _).add_right _
theorem insertWith.valid_aux [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (f : α → α) (x : α)
    (hf : ∀ y, x ≤ y ∧ y ≤ x → x ≤ f y ∧ f y ≤ x) :
    ∀ {t o₁ o₂},
      Valid' o₁ t o₂ →
        Bounded nil o₁ x →
          Bounded nil x o₂ →
            Valid' o₁ (insertWith f x t) o₂ ∧ Raised (size t) (size (insertWith f x t))
  | nil, o₁, o₂, _, bl, br => ⟨valid'_singleton bl br, Or.inr rfl⟩
  | node sz l y r, o₁, o₂, h, bl, br => by
    rw [insertWith, cmpLE]
    split_ifs with h_1 h_2 <;> dsimp only
    · rcases h with ⟨⟨lx, xr⟩, hs, hb⟩
      rcases hf _ ⟨h_1, h_2⟩ with ⟨xf, fx⟩
      refine'
        ⟨⟨⟨lx.mono_right (le_trans h_2 xf), xr.mono_left (le_trans fx h_1)⟩, hs, hb⟩, Or.inl rfl⟩
    · rcases insertWith.valid_aux f x hf h.left bl (lt_of_le_not_le h_1 h_2) with ⟨vl, e⟩
      suffices H : _ by
        refine' ⟨vl.balanceL h.right H, _⟩
        rw [size_balanceL vl.3 h.3.2.2 vl.2 h.2.2.2 H, h.2.size_eq]
        refine' (e.add_right _).add_right _
      · exact Or.inl ⟨_, e, h.3.1⟩
    · have : y < x := lt_of_le_not_le ((total_of (· ≤ ·) _ _).resolve_left h_1) h_1
      rcases insertWith.valid_aux f x hf h.right this br with ⟨vr, e⟩
      suffices H : _ by
        refine' ⟨h.left.balanceR vr H, _⟩
        rw [size_balanceR h.3.2.1 vr.3 h.2.2.1 vr.2 H, h.2.size_eq]
        refine' (e.add_left _).add_right _
      · 

Proof state:
case neg.intro
α : Type u_1
inst✝² : Preorder α
inst✝¹ : IsTotal α fun x x_1 => x ≤ x_1
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
f : α → α
x : α
hf : ∀ (y : α), x ≤ y ∧ y ≤ x → x ≤ f y ∧ f y ≤ x
sz : ℕ
l : Ordnode α
y : α
r : Ordnode α
o₁ : WithBot α
o₂ : WithTop α
h : Valid' o₁ (node sz l y r) o₂
bl : Bounded nil o₁ ↑x
br : Bounded nil (↑x) o₂
h_1 : ¬x ≤ y
this : y < x
vr : Valid' (↑y) (insertWith f x r) o₂
e : Raised (size r) (size (insertWith f x r))
⊢ (∃ l', Raised (size l) l' ∧ BalancedSz l' (size (insertWith f x r))) ∨
    ∃ r', Raised r' (size (insertWith f x r)) ∧ BalancedSz (size l) r'

Next tactic:
exact Or.inr ⟨_, e, h.3.1⟩
theorem insert_eq_insertWith [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t, Ordnode.insert x t = insertWith (fun _ => x) x t
  | nil => rfl
  | node _ l y r => by
    

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

Next tactic:
unfold Ordnode.insert insertWith
theorem insert_eq_insertWith [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t, Ordnode.insert x t = insertWith (fun _ => x) x t
  | nil => rfl
  | node _ l y r => by
    unfold Ordnode.insert insertWith; 

Proof state:
α : Type u_1
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
x : α
size✝ : ℕ
l : Ordnode α
y : α
r : Ordnode α
⊢ (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 cmpLE x y with
    | Ordering.lt => balanceL (insertWith (fun x_1 => x) x l) y r
    | Ordering.eq => node size✝ l x r
    | Ordering.gt => balanceR l y (insertWith (fun x_1 => x) x r)

Next tactic:
cases cmpLE x y
theorem insert_eq_insertWith [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t, Ordnode.insert x t = insertWith (fun _ => x) x t
  | nil => rfl
  | node _ l y r => by
    unfold Ordnode.insert insertWith; cases cmpLE x y <;> 

Proof state:
case lt
α : Type u_1
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
x : α
size✝ : ℕ
l : Ordnode α
y : α
r : Ordnode α
⊢ (match Ordering.lt 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.lt with
    | Ordering.lt => balanceL (insertWith (fun x_1 => x) x l) y r
    | Ordering.eq => node size✝ l x r
    | Ordering.gt => balanceR l y (insertWith (fun x_1 => x) x r)

Next tactic:
simp [insert_eq_insertWith]
theorem insert_eq_insertWith [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t, Ordnode.insert x t = insertWith (fun _ => x) x t
  | nil => rfl
  | node _ l y r => by
    unfold Ordnode.insert insertWith; cases cmpLE x y <;> 

Proof state:
case eq
α : Type u_1
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
x : α
size✝ : ℕ
l : Ordnode α
y : α
r : Ordnode α
⊢ (match Ordering.eq 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.eq with
    | Ordering.lt => balanceL (insertWith (fun x_1 => x) x l) y r
    | Ordering.eq => node size✝ l x r
    | Ordering.gt => balanceR l y (insertWith (fun x_1 => x) x r)

Next tactic:
simp [insert_eq_insertWith]
theorem insert_eq_insertWith [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t, Ordnode.insert x t = insertWith (fun _ => x) x t
  | nil => rfl
  | node _ l y r => by
    unfold Ordnode.insert insertWith; cases cmpLE x y <;> 

Proof state:
case gt
α : Type u_1
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
x : α
size✝ : ℕ
l : Ordnode α
y : α
r : Ordnode α
⊢ (match Ordering.gt 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.gt with
    | Ordering.lt => balanceL (insertWith (fun x_1 => x) x l) y r
    | Ordering.eq => node size✝ l x r
    | Ordering.gt => balanceR l y (insertWith (fun x_1 => x) x r)

Next tactic:
simp [insert_eq_insertWith]
theorem insert.valid [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (x : α) {t} (h : Valid t) :
    Valid (Ordnode.insert x t) := 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 : α
t : Ordnode α
h : Valid t
⊢ Valid (Ordnode.insert x t)

Next tactic:
rw [insert_eq_insertWith]
theorem insert.valid [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (x : α) {t} (h : Valid t) :
    Valid (Ordnode.insert x t) := by
  rw [insert_eq_insertWith]; 

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 : α
t : Ordnode α
h : Valid t
⊢ Valid (insertWith (fun x_1 => x) x t)

Next tactic:
exact insertWith.valid _ _ (fun _ _ => ⟨le_rfl, le_rfl⟩) h
theorem insert'_eq_insertWith [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t, insert' x t = insertWith id x t
  | nil => rfl
  | node _ l y r => by
    

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

Next tactic:
unfold insert' insertWith
theorem insert'_eq_insertWith [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t, insert' x t = insertWith id x t
  | nil => rfl
  | node _ l y r => by
    unfold insert' insertWith; 

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

Next tactic:
cases cmpLE x y
theorem insert'_eq_insertWith [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t, insert' x t = insertWith id x t
  | nil => rfl
  | node _ l y r => by
    unfold insert' insertWith; cases cmpLE x y <;> 

Proof state:
case lt
α : Type u_1
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
x : α
size✝ : ℕ
l : Ordnode α
y : α
r : Ordnode α
⊢ (match Ordering.lt with
    | Ordering.lt => balanceL (insert' x l) y r
    | Ordering.eq => node size✝ l y r
    | Ordering.gt => balanceR l y (insert' x r)) =
    match Ordering.lt with
    | Ordering.lt => balanceL (insertWith id x l) y r
    | Ordering.eq => node size✝ l (id y) r
    | Ordering.gt => balanceR l y (insertWith id x r)

Next tactic:
simp [insert'_eq_insertWith]
theorem insert'_eq_insertWith [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t, insert' x t = insertWith id x t
  | nil => rfl
  | node _ l y r => by
    unfold insert' insertWith; cases cmpLE x y <;> 

Proof state:
case eq
α : Type u_1
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
x : α
size✝ : ℕ
l : Ordnode α
y : α
r : Ordnode α
⊢ (match Ordering.eq with
    | Ordering.lt => balanceL (insert' x l) y r
    | Ordering.eq => node size✝ l y r
    | Ordering.gt => balanceR l y (insert' x r)) =
    match Ordering.eq with
    | Ordering.lt => balanceL (insertWith id x l) y r
    | Ordering.eq => node size✝ l (id y) r
    | Ordering.gt => balanceR l y (insertWith id x r)

Next tactic:
simp [insert'_eq_insertWith]
theorem insert'_eq_insertWith [@DecidableRel α (· ≤ ·)] (x : α) :
    ∀ t, insert' x t = insertWith id x t
  | nil => rfl
  | node _ l y r => by
    unfold insert' insertWith; cases cmpLE x y <;> 

Proof state:
case gt
α : Type u_1
inst✝¹ : Preorder α
inst✝ : DecidableRel fun x x_1 => x ≤ x_1
x : α
size✝ : ℕ
l : Ordnode α
y : α
r : Ordnode α
⊢ (match Ordering.gt with
    | Ordering.lt => balanceL (insert' x l) y r
    | Ordering.eq => node size✝ l y r
    | Ordering.gt => balanceR l y (insert' x r)) =
    match Ordering.gt with
    | Ordering.lt => balanceL (insertWith id x l) y r
    | Ordering.eq => node size✝ l (id y) r
    | Ordering.gt => balanceR l y (insertWith id x r)

Next tactic:
simp [insert'_eq_insertWith]
theorem insert'.valid [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (x : α) {t} (h : Valid t) :
    Valid (insert' x t) := 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 : α
t : Ordnode α
h : Valid t
⊢ Valid (insert' x t)

Next tactic:
rw [insert'_eq_insertWith]
theorem insert'.valid [IsTotal α (· ≤ ·)] [@DecidableRel α (· ≤ ·)] (x : α) {t} (h : Valid t) :
    Valid (insert' x t) := by
  rw [insert'_eq_insertWith]; 

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 : α
t : Ordnode α
h : Valid t
⊢ Valid (insertWith id x t)

Next tactic:
exact insertWith.valid _ _ (fun _ => id) h
theorem Valid'.map_aux {β} [Preorder β] {f : α → β} (f_strict_mono : StrictMono f) {t a₁ a₂}
    (h : Valid' a₁ t a₂) :
    Valid' (Option.map f a₁) (map f t) (Option.map f a₂) ∧ (map f t).size = t.size := by
  

Proof state:
α : Type u_1
inst✝¹ : Preorder α
β : Type u_2
inst✝ : Preorder β
f : α → β
f_strict_mono : StrictMono f
t : Ordnode α
a₁ : WithBot α
a₂ : WithTop α
h : Valid' a₁ t a₂
⊢ Valid' (Option.map f a₁) (map f t) (Option.map f a₂) ∧ size (map f t) = size t

Next tactic:
induction t generalizing a₁ a₂ with
  | nil =>
    simp [map]; apply valid'_nil
    cases a₁; · trivial
    cases a₂; · trivial
    simp only [Bounded]
    exact f_strict_mono h.ord
  | node _ _ _ _ t_ih_l t_ih_r =>
    have t_ih_l' := t_ih_l h.left
    have t_ih_r' := t_ih_r h.right
    clear t_ih_l t_ih_r
    cases' t_ih_l' with t_l_valid t_l_size
    cases' t_ih_r' with t_r_valid t_r_size
    simp only [map, size_node, and_true]
    constructor
    · exact And.intro t_l_valid.ord t_r_valid.ord
    · constructor
      · rw [t_l_size, t_r_size]; exact h.sz.1
      · constructor
        · exact t_l_valid.sz
        · exact t_r_valid.sz
    · constructor
      · rw [t_l_size, t_r_size]; exact h.bal.1
      · constructor
        · exact t_l_valid.bal
        · exact t_r_valid.bal
theorem Valid'.map_aux {β} [Preorder β] {f : α → β} (f_strict_mono : StrictMono f) {t a₁ a₂}
    (h : Valid' a₁ t a₂) :
    Valid' (Option.map f a₁) (map f t) (Option.map f a₂) ∧ (map f t).size = t.size := by
  induction t generalizing a₁ a₂ with
  

Proof state:
case nil
α : Type u_1
inst✝¹ : Preorder α
β : Type u_2
inst✝ : Preorder β
f : α → β
f_strict_mono : StrictMono f
a₁ : WithBot α
a₂ : WithTop α
h : Valid' a₁ nil a₂
⊢ Valid' (Option.map f a₁) (map f nil) (Option.map f a₂) ∧ size (map f nil) = size nil

Next tactic:
| nil =>
    simp [map]; apply valid'_nil
    cases a₁; · trivial
    cases a₂; · trivial
    simp only [Bounded]
    exact f_strict_mono h.ord
theorem Valid'.map_aux {β} [Preorder β] {f : α → β} (f_strict_mono : StrictMono f) {t a₁ a₂}
    (h : Valid' a₁ t a₂) :
    Valid' (Option.map f a₁) (map f t) (Option.map f a₂) ∧ (map f t).size = t.size := by
  induction t generalizing a₁ a₂ with
  | nil =>
    

Proof state:
case nil
α : Type u_1
inst✝¹ : Preorder α
β : Type u_2
inst✝ : Preorder β
f : α → β
f_strict_mono : StrictMono f
a₁ : WithBot α
a₂ : WithTop α
h : Valid' a₁ nil a₂
⊢ Valid' (Option.map f a₁) (map f nil) (Option.map f a₂) ∧ size (map f nil) = size nil

Next tactic:
simp [map]
theorem Valid'.map_aux {β} [Preorder β] {f : α → β} (f_strict_mono : StrictMono f) {t a₁ a₂}
    (h : Valid' a₁ t a₂) :
    Valid' (Option.map f a₁) (map f t) (Option.map f a₂) ∧ (map f t).size = t.size := by
  induction t generalizing a₁ a₂ with
  | nil =>
    simp [map]; 

Proof state:
case nil
α : Type u_1
inst✝¹ : Preorder α
β : Type u_2
inst✝ : Preorder β
f : α → β
f_strict_mono : StrictMono f
a₁ : WithBot α
a₂ : WithTop α
h : Valid' a₁ nil a₂
⊢ Valid' (Option.map f a₁) nil (Option.map f a₂)

Next tactic:
apply valid'_nil
theorem Valid'.map_aux {β} [Preorder β] {f : α → β} (f_strict_mono : StrictMono f) {t a₁ a₂}
    (h : Valid' a₁ t a₂) :
    Valid' (Option.map f a₁) (map f t) (Option.map f a₂) ∧ (map f t).size = t.size := by
  induction t generalizing a₁ a₂ with
  | nil =>
    simp [map]; apply valid'_nil
    

Proof state:
case nil.h
α : Type u_1
inst✝¹ : Preorder α
β : Type u_2
inst✝ : Preorder β
f : α → β
f_strict_mono : StrictMono f
a₁ : WithBot α
a₂ : WithTop α
h : Valid' a₁ nil a₂
⊢ Bounded nil (Option.map f a₁) (Option.map f a₂)

Next tactic:
cases a₁
theorem Valid'.map_aux {β} [Preorder β] {f : α → β} (f_strict_mono : StrictMono f) {t a₁ a₂}
    (h : Valid' a₁ t a₂) :
    Valid' (Option.map f a₁) (map f t) (Option.map f a₂) ∧ (map f t).size = t.size := by
  induction t generalizing a₁ a₂ with
  | nil =>
    simp [map]; apply valid'_nil
    cases a₁; · 

Proof state:
case nil.h.none
α : Type u_1
inst✝¹ : Preorder α
β : Type u_2
inst✝ : Preorder β
f : α → β
f_strict_mono : StrictMono f
a₂ : WithTop α
h : Valid' none nil a₂
⊢ Bounded nil (Option.map f none) (Option.map f a₂)

Next tactic:
trivial