l3lab/ntp-mathlib huggingface dataset:
theorem Valid'.merge_aux {l r o₁ o₂} (hl : Valid' o₁ l o₂) (hr : Valid' o₁ r o₂)
    (sep : l.All fun x => r.All fun y => x < y) :
    Valid' o₁ (@merge α l r) o₂ ∧ size (merge l r) = size l + size r := by
  induction' l with ls ll lx lr _ IHlr generalizing o₁ o₂ r
  · exact ⟨hr, (zero_add _).symm⟩
  

Proof state:
case node
α : Type u_1
inst✝ : Preorder α
ls : ℕ
ll : Ordnode α
lx : α
lr : Ordnode α
l_ih✝ :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ ll o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) ll → Valid' o₁ (merge ll r) o₂ ∧ size (merge ll r) = size ll + size r
IHlr :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ lr o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) lr → Valid' o₁ (merge lr r) o₂ ∧ size (merge lr r) = size lr + size r
r : Ordnode α
o₁ : WithBot α
o₂ : WithTop α
hl : Valid' o₁ (Ordnode.node ls ll lx lr) o₂
hr : Valid' o₁ r o₂
sep : All (fun x => All (fun y => x < y) r) (Ordnode.node ls ll lx lr)
⊢ Valid' o₁ (merge (Ordnode.node ls ll lx lr) r) o₂ ∧
    size (merge (Ordnode.node ls ll lx lr) r) = size (Ordnode.node ls ll lx lr) + size r

Next tactic:
induction' r with rs rl rx rr IHrl _ generalizing o₁ o₂
theorem Valid'.merge_aux {l r o₁ o₂} (hl : Valid' o₁ l o₂) (hr : Valid' o₁ r o₂)
    (sep : l.All fun x => r.All fun y => x < y) :
    Valid' o₁ (@merge α l r) o₂ ∧ size (merge l r) = size l + size r := by
  induction' l with ls ll lx lr _ IHlr generalizing o₁ o₂ r
  · exact ⟨hr, (zero_add _).symm⟩
  induction' r with rs rl rx rr IHrl _ generalizing o₁ o₂
  · 

Proof state:
case node.nil
α : Type u_1
inst✝ : Preorder α
ls : ℕ
ll : Ordnode α
lx : α
lr : Ordnode α
l_ih✝ :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ ll o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) ll → Valid' o₁ (merge ll r) o₂ ∧ size (merge ll r) = size ll + size r
IHlr :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ lr o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) lr → Valid' o₁ (merge lr r) o₂ ∧ size (merge lr r) = size lr + size r
o₁ : WithBot α
o₂ : WithTop α
hl : Valid' o₁ (Ordnode.node ls ll lx lr) o₂
hr : Valid' o₁ nil o₂
sep : All (fun x => All (fun y => x < y) nil) (Ordnode.node ls ll lx lr)
⊢ Valid' o₁ (merge (Ordnode.node ls ll lx lr) nil) o₂ ∧
    size (merge (Ordnode.node ls ll lx lr) nil) = size (Ordnode.node ls ll lx lr) + size nil

Next tactic:
exact ⟨hl, rfl⟩
theorem Valid'.merge_aux {l r o₁ o₂} (hl : Valid' o₁ l o₂) (hr : Valid' o₁ r o₂)
    (sep : l.All fun x => r.All fun y => x < y) :
    Valid' o₁ (@merge α l r) o₂ ∧ size (merge l r) = size l + size r := by
  induction' l with ls ll lx lr _ IHlr generalizing o₁ o₂ r
  · exact ⟨hr, (zero_add _).symm⟩
  induction' r with rs rl rx rr IHrl _ generalizing o₁ o₂
  · exact ⟨hl, rfl⟩
  

Proof state:
case node.node
α : Type u_1
inst✝ : Preorder α
ls : ℕ
ll : Ordnode α
lx : α
lr : Ordnode α
l_ih✝ :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ ll o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) ll → Valid' o₁ (merge ll r) o₂ ∧ size (merge ll r) = size ll + size r
IHlr :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ lr o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) lr → Valid' o₁ (merge lr r) o₂ ∧ size (merge lr r) = size lr + size r
rs : ℕ
rl : Ordnode α
rx : α
rr : Ordnode α
IHrl :
  ∀ {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ (Ordnode.node ls ll lx lr) o₂ →
      Valid' o₁ rl o₂ →
        All (fun x => All (fun y => x < y) rl) (Ordnode.node ls ll lx lr) →
          Valid' o₁ (merge (Ordnode.node ls ll lx lr) rl) o₂ ∧
            size (merge (Ordnode.node ls ll lx lr) rl) = size (Ordnode.node ls ll lx lr) + size rl
r_ih✝ :
  ∀ {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ (Ordnode.node ls ll lx lr) o₂ →
      Valid' o₁ rr o₂ →
        All (fun x => All (fun y => x < y) rr) (Ordnode.node ls ll lx lr) →
          Valid' o₁ (merge (Ordnode.node ls ll lx lr) rr) o₂ ∧
            size (merge (Ordnode.node ls ll lx lr) rr) = size (Ordnode.node ls ll lx lr) + size rr
o₁ : WithBot α
o₂ : WithTop α
hl : Valid' o₁ (Ordnode.node ls ll lx lr) o₂
hr : Valid' o₁ (Ordnode.node rs rl rx rr) o₂
sep : All (fun x => All (fun y => x < y) (Ordnode.node rs rl rx rr)) (Ordnode.node ls ll lx lr)
⊢ Valid' o₁ (merge (Ordnode.node ls ll lx lr) (Ordnode.node rs rl rx rr)) o₂ ∧
    size (merge (Ordnode.node ls ll lx lr) (Ordnode.node rs rl rx rr)) =
      size (Ordnode.node ls ll lx lr) + size (Ordnode.node rs rl rx rr)

Next tactic:
rw [merge_node]
theorem Valid'.merge_aux {l r o₁ o₂} (hl : Valid' o₁ l o₂) (hr : Valid' o₁ r o₂)
    (sep : l.All fun x => r.All fun y => x < y) :
    Valid' o₁ (@merge α l r) o₂ ∧ size (merge l r) = size l + size r := by
  induction' l with ls ll lx lr _ IHlr generalizing o₁ o₂ r
  · exact ⟨hr, (zero_add _).symm⟩
  induction' r with rs rl rx rr IHrl _ generalizing o₁ o₂
  · exact ⟨hl, rfl⟩
  rw [merge_node]; 

Proof state:
case node.node
α : Type u_1
inst✝ : Preorder α
ls : ℕ
ll : Ordnode α
lx : α
lr : Ordnode α
l_ih✝ :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ ll o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) ll → Valid' o₁ (merge ll r) o₂ ∧ size (merge ll r) = size ll + size r
IHlr :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ lr o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) lr → Valid' o₁ (merge lr r) o₂ ∧ size (merge lr r) = size lr + size r
rs : ℕ
rl : Ordnode α
rx : α
rr : Ordnode α
IHrl :
  ∀ {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ (Ordnode.node ls ll lx lr) o₂ →
      Valid' o₁ rl o₂ →
        All (fun x => All (fun y => x < y) rl) (Ordnode.node ls ll lx lr) →
          Valid' o₁ (merge (Ordnode.node ls ll lx lr) rl) o₂ ∧
            size (merge (Ordnode.node ls ll lx lr) rl) = size (Ordnode.node ls ll lx lr) + size rl
r_ih✝ :
  ∀ {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ (Ordnode.node ls ll lx lr) o₂ →
      Valid' o₁ rr o₂ →
        All (fun x => All (fun y => x < y) rr) (Ordnode.node ls ll lx lr) →
          Valid' o₁ (merge (Ordnode.node ls ll lx lr) rr) o₂ ∧
            size (merge (Ordnode.node ls ll lx lr) rr) = size (Ordnode.node ls ll lx lr) + size rr
o₁ : WithBot α
o₂ : WithTop α
hl : Valid' o₁ (Ordnode.node ls ll lx lr) o₂
hr : Valid' o₁ (Ordnode.node rs rl rx rr) o₂
sep : All (fun x => All (fun y => x < y) (Ordnode.node rs rl rx rr)) (Ordnode.node ls ll lx lr)
⊢ Valid' o₁
      (if delta * ls < rs then Ordnode.balanceL (merge (Ordnode.node ls ll lx lr) rl) rx rr
      else
        if delta * rs < ls then Ordnode.balanceR ll lx (merge lr (Ordnode.node rs rl rx rr))
        else Ordnode.glue (Ordnode.node ls ll lx lr) (Ordnode.node rs rl rx rr))
      o₂ ∧
    size
        (if delta * ls < rs then Ordnode.balanceL (merge (Ordnode.node ls ll lx lr) rl) rx rr
        else
          if delta * rs < ls then Ordnode.balanceR ll lx (merge lr (Ordnode.node rs rl rx rr))
          else Ordnode.glue (Ordnode.node ls ll lx lr) (Ordnode.node rs rl rx rr)) =
      size (Ordnode.node ls ll lx lr) + size (Ordnode.node rs rl rx rr)

Next tactic:
split_ifs with h h_1
theorem Valid'.merge_aux {l r o₁ o₂} (hl : Valid' o₁ l o₂) (hr : Valid' o₁ r o₂)
    (sep : l.All fun x => r.All fun y => x < y) :
    Valid' o₁ (@merge α l r) o₂ ∧ size (merge l r) = size l + size r := by
  induction' l with ls ll lx lr _ IHlr generalizing o₁ o₂ r
  · exact ⟨hr, (zero_add _).symm⟩
  induction' r with rs rl rx rr IHrl _ generalizing o₁ o₂
  · exact ⟨hl, rfl⟩
  rw [merge_node]; split_ifs with h h_1
  · 

Proof state:
case pos
α : Type u_1
inst✝ : Preorder α
ls : ℕ
ll : Ordnode α
lx : α
lr : Ordnode α
l_ih✝ :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ ll o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) ll → Valid' o₁ (merge ll r) o₂ ∧ size (merge ll r) = size ll + size r
IHlr :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ lr o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) lr → Valid' o₁ (merge lr r) o₂ ∧ size (merge lr r) = size lr + size r
rs : ℕ
rl : Ordnode α
rx : α
rr : Ordnode α
IHrl :
  ∀ {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ (Ordnode.node ls ll lx lr) o₂ →
      Valid' o₁ rl o₂ →
        All (fun x => All (fun y => x < y) rl) (Ordnode.node ls ll lx lr) →
          Valid' o₁ (merge (Ordnode.node ls ll lx lr) rl) o₂ ∧
            size (merge (Ordnode.node ls ll lx lr) rl) = size (Ordnode.node ls ll lx lr) + size rl
r_ih✝ :
  ∀ {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ (Ordnode.node ls ll lx lr) o₂ →
      Valid' o₁ rr o₂ →
        All (fun x => All (fun y => x < y) rr) (Ordnode.node ls ll lx lr) →
          Valid' o₁ (merge (Ordnode.node ls ll lx lr) rr) o₂ ∧
            size (merge (Ordnode.node ls ll lx lr) rr) = size (Ordnode.node ls ll lx lr) + size rr
o₁ : WithBot α
o₂ : WithTop α
hl : Valid' o₁ (Ordnode.node ls ll lx lr) o₂
hr : Valid' o₁ (Ordnode.node rs rl rx rr) o₂
sep : All (fun x => All (fun y => x < y) (Ordnode.node rs rl rx rr)) (Ordnode.node ls ll lx lr)
h : delta * ls < rs
⊢ Valid' o₁ (Ordnode.balanceL (merge (Ordnode.node ls ll lx lr) rl) rx rr) o₂ ∧
    size (Ordnode.balanceL (merge (Ordnode.node ls ll lx lr) rl) rx rr) =
      size (Ordnode.node ls ll lx lr) + size (Ordnode.node rs rl rx rr)

Next tactic:
cases'
      IHrl (hl.of_lt hr.1.1.to_nil <| sep.imp fun x h => h.2.1) hr.left
        (sep.imp fun x h => h.1) with
      v e
theorem Valid'.merge_aux {l r o₁ o₂} (hl : Valid' o₁ l o₂) (hr : Valid' o₁ r o₂)
    (sep : l.All fun x => r.All fun y => x < y) :
    Valid' o₁ (@merge α l r) o₂ ∧ size (merge l r) = size l + size r := by
  induction' l with ls ll lx lr _ IHlr generalizing o₁ o₂ r
  · exact ⟨hr, (zero_add _).symm⟩
  induction' r with rs rl rx rr IHrl _ generalizing o₁ o₂
  · exact ⟨hl, rfl⟩
  rw [merge_node]; split_ifs with h h_1
  · cases'
      IHrl (hl.of_lt hr.1.1.to_nil <| sep.imp fun x h => h.2.1) hr.left
        (sep.imp fun x h => h.1) with
      v e
    

Proof state:
case pos.intro
α : Type u_1
inst✝ : Preorder α
ls : ℕ
ll : Ordnode α
lx : α
lr : Ordnode α
l_ih✝ :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ ll o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) ll → Valid' o₁ (merge ll r) o₂ ∧ size (merge ll r) = size ll + size r
IHlr :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ lr o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) lr → Valid' o₁ (merge lr r) o₂ ∧ size (merge lr r) = size lr + size r
rs : ℕ
rl : Ordnode α
rx : α
rr : Ordnode α
IHrl :
  ∀ {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ (Ordnode.node ls ll lx lr) o₂ →
      Valid' o₁ rl o₂ →
        All (fun x => All (fun y => x < y) rl) (Ordnode.node ls ll lx lr) →
          Valid' o₁ (merge (Ordnode.node ls ll lx lr) rl) o₂ ∧
            size (merge (Ordnode.node ls ll lx lr) rl) = size (Ordnode.node ls ll lx lr) + size rl
r_ih✝ :
  ∀ {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ (Ordnode.node ls ll lx lr) o₂ →
      Valid' o₁ rr o₂ →
        All (fun x => All (fun y => x < y) rr) (Ordnode.node ls ll lx lr) →
          Valid' o₁ (merge (Ordnode.node ls ll lx lr) rr) o₂ ∧
            size (merge (Ordnode.node ls ll lx lr) rr) = size (Ordnode.node ls ll lx lr) + size rr
o₁ : WithBot α
o₂ : WithTop α
hl : Valid' o₁ (Ordnode.node ls ll lx lr) o₂
hr : Valid' o₁ (Ordnode.node rs rl rx rr) o₂
sep : All (fun x => All (fun y => x < y) (Ordnode.node rs rl rx rr)) (Ordnode.node ls ll lx lr)
h : delta * ls < rs
v : Valid' o₁ (merge (Ordnode.node ls ll lx lr) rl) ↑rx
e : size (merge (Ordnode.node ls ll lx lr) rl) = size (Ordnode.node ls ll lx lr) + size rl
⊢ Valid' o₁ (Ordnode.balanceL (merge (Ordnode.node ls ll lx lr) rl) rx rr) o₂ ∧
    size (Ordnode.balanceL (merge (Ordnode.node ls ll lx lr) rl) rx rr) =
      size (Ordnode.node ls ll lx lr) + size (Ordnode.node rs rl rx rr)

Next tactic:
exact Valid'.merge_aux₁ hl hr h v e
theorem Valid'.merge_aux {l r o₁ o₂} (hl : Valid' o₁ l o₂) (hr : Valid' o₁ r o₂)
    (sep : l.All fun x => r.All fun y => x < y) :
    Valid' o₁ (@merge α l r) o₂ ∧ size (merge l r) = size l + size r := by
  induction' l with ls ll lx lr _ IHlr generalizing o₁ o₂ r
  · exact ⟨hr, (zero_add _).symm⟩
  induction' r with rs rl rx rr IHrl _ generalizing o₁ o₂
  · exact ⟨hl, rfl⟩
  rw [merge_node]; split_ifs with h h_1
  · cases'
      IHrl (hl.of_lt hr.1.1.to_nil <| sep.imp fun x h => h.2.1) hr.left
        (sep.imp fun x h => h.1) with
      v e
    exact Valid'.merge_aux₁ hl hr h v e
  · 

Proof state:
case pos
α : Type u_1
inst✝ : Preorder α
ls : ℕ
ll : Ordnode α
lx : α
lr : Ordnode α
l_ih✝ :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ ll o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) ll → Valid' o₁ (merge ll r) o₂ ∧ size (merge ll r) = size ll + size r
IHlr :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ lr o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) lr → Valid' o₁ (merge lr r) o₂ ∧ size (merge lr r) = size lr + size r
rs : ℕ
rl : Ordnode α
rx : α
rr : Ordnode α
IHrl :
  ∀ {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ (Ordnode.node ls ll lx lr) o₂ →
      Valid' o₁ rl o₂ →
        All (fun x => All (fun y => x < y) rl) (Ordnode.node ls ll lx lr) →
          Valid' o₁ (merge (Ordnode.node ls ll lx lr) rl) o₂ ∧
            size (merge (Ordnode.node ls ll lx lr) rl) = size (Ordnode.node ls ll lx lr) + size rl
r_ih✝ :
  ∀ {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ (Ordnode.node ls ll lx lr) o₂ →
      Valid' o₁ rr o₂ →
        All (fun x => All (fun y => x < y) rr) (Ordnode.node ls ll lx lr) →
          Valid' o₁ (merge (Ordnode.node ls ll lx lr) rr) o₂ ∧
            size (merge (Ordnode.node ls ll lx lr) rr) = size (Ordnode.node ls ll lx lr) + size rr
o₁ : WithBot α
o₂ : WithTop α
hl : Valid' o₁ (Ordnode.node ls ll lx lr) o₂
hr : Valid' o₁ (Ordnode.node rs rl rx rr) o₂
sep : All (fun x => All (fun y => x < y) (Ordnode.node rs rl rx rr)) (Ordnode.node ls ll lx lr)
h : ¬delta * ls < rs
h_1 : delta * rs < ls
⊢ Valid' o₁ (Ordnode.balanceR ll lx (merge lr (Ordnode.node rs rl rx rr))) o₂ ∧
    size (Ordnode.balanceR ll lx (merge lr (Ordnode.node rs rl rx rr))) =
      size (Ordnode.node ls ll lx lr) + size (Ordnode.node rs rl rx rr)

Next tactic:
cases' IHlr hl.right (hr.of_gt hl.1.2.to_nil sep.2.1) sep.2.2 with v e
theorem Valid'.merge_aux {l r o₁ o₂} (hl : Valid' o₁ l o₂) (hr : Valid' o₁ r o₂)
    (sep : l.All fun x => r.All fun y => x < y) :
    Valid' o₁ (@merge α l r) o₂ ∧ size (merge l r) = size l + size r := by
  induction' l with ls ll lx lr _ IHlr generalizing o₁ o₂ r
  · exact ⟨hr, (zero_add _).symm⟩
  induction' r with rs rl rx rr IHrl _ generalizing o₁ o₂
  · exact ⟨hl, rfl⟩
  rw [merge_node]; split_ifs with h h_1
  · cases'
      IHrl (hl.of_lt hr.1.1.to_nil <| sep.imp fun x h => h.2.1) hr.left
        (sep.imp fun x h => h.1) with
      v e
    exact Valid'.merge_aux₁ hl hr h v e
  · cases' IHlr hl.right (hr.of_gt hl.1.2.to_nil sep.2.1) sep.2.2 with v e
    

Proof state:
case pos.intro
α : Type u_1
inst✝ : Preorder α
ls : ℕ
ll : Ordnode α
lx : α
lr : Ordnode α
l_ih✝ :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ ll o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) ll → Valid' o₁ (merge ll r) o₂ ∧ size (merge ll r) = size ll + size r
IHlr :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ lr o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) lr → Valid' o₁ (merge lr r) o₂ ∧ size (merge lr r) = size lr + size r
rs : ℕ
rl : Ordnode α
rx : α
rr : Ordnode α
IHrl :
  ∀ {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ (Ordnode.node ls ll lx lr) o₂ →
      Valid' o₁ rl o₂ →
        All (fun x => All (fun y => x < y) rl) (Ordnode.node ls ll lx lr) →
          Valid' o₁ (merge (Ordnode.node ls ll lx lr) rl) o₂ ∧
            size (merge (Ordnode.node ls ll lx lr) rl) = size (Ordnode.node ls ll lx lr) + size rl
r_ih✝ :
  ∀ {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ (Ordnode.node ls ll lx lr) o₂ →
      Valid' o₁ rr o₂ →
        All (fun x => All (fun y => x < y) rr) (Ordnode.node ls ll lx lr) →
          Valid' o₁ (merge (Ordnode.node ls ll lx lr) rr) o₂ ∧
            size (merge (Ordnode.node ls ll lx lr) rr) = size (Ordnode.node ls ll lx lr) + size rr
o₁ : WithBot α
o₂ : WithTop α
hl : Valid' o₁ (Ordnode.node ls ll lx lr) o₂
hr : Valid' o₁ (Ordnode.node rs rl rx rr) o₂
sep : All (fun x => All (fun y => x < y) (Ordnode.node rs rl rx rr)) (Ordnode.node ls ll lx lr)
h : ¬delta * ls < rs
h_1 : delta * rs < ls
v : Valid' (↑lx) (merge lr (Ordnode.node rs rl rx rr)) o₂
e : size (merge lr (Ordnode.node rs rl rx rr)) = size lr + size (Ordnode.node rs rl rx rr)
⊢ Valid' o₁ (Ordnode.balanceR ll lx (merge lr (Ordnode.node rs rl rx rr))) o₂ ∧
    size (Ordnode.balanceR ll lx (merge lr (Ordnode.node rs rl rx rr))) =
      size (Ordnode.node ls ll lx lr) + size (Ordnode.node rs rl rx rr)

Next tactic:
have := Valid'.merge_aux₁ hr.dual hl.dual h_1 v.dual
theorem Valid'.merge_aux {l r o₁ o₂} (hl : Valid' o₁ l o₂) (hr : Valid' o₁ r o₂)
    (sep : l.All fun x => r.All fun y => x < y) :
    Valid' o₁ (@merge α l r) o₂ ∧ size (merge l r) = size l + size r := by
  induction' l with ls ll lx lr _ IHlr generalizing o₁ o₂ r
  · exact ⟨hr, (zero_add _).symm⟩
  induction' r with rs rl rx rr IHrl _ generalizing o₁ o₂
  · exact ⟨hl, rfl⟩
  rw [merge_node]; split_ifs with h h_1
  · cases'
      IHrl (hl.of_lt hr.1.1.to_nil <| sep.imp fun x h => h.2.1) hr.left
        (sep.imp fun x h => h.1) with
      v e
    exact Valid'.merge_aux₁ hl hr h v e
  · cases' IHlr hl.right (hr.of_gt hl.1.2.to_nil sep.2.1) sep.2.2 with v e
    have := Valid'.merge_aux₁ hr.dual hl.dual h_1 v.dual
    

Proof state:
case pos.intro
α : Type u_1
inst✝ : Preorder α
ls : ℕ
ll : Ordnode α
lx : α
lr : Ordnode α
l_ih✝ :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ ll o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) ll → Valid' o₁ (merge ll r) o₂ ∧ size (merge ll r) = size ll + size r
IHlr :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ lr o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) lr → Valid' o₁ (merge lr r) o₂ ∧ size (merge lr r) = size lr + size r
rs : ℕ
rl : Ordnode α
rx : α
rr : Ordnode α
IHrl :
  ∀ {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ (Ordnode.node ls ll lx lr) o₂ →
      Valid' o₁ rl o₂ →
        All (fun x => All (fun y => x < y) rl) (Ordnode.node ls ll lx lr) →
          Valid' o₁ (merge (Ordnode.node ls ll lx lr) rl) o₂ ∧
            size (merge (Ordnode.node ls ll lx lr) rl) = size (Ordnode.node ls ll lx lr) + size rl
r_ih✝ :
  ∀ {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ (Ordnode.node ls ll lx lr) o₂ →
      Valid' o₁ rr o₂ →
        All (fun x => All (fun y => x < y) rr) (Ordnode.node ls ll lx lr) →
          Valid' o₁ (merge (Ordnode.node ls ll lx lr) rr) o₂ ∧
            size (merge (Ordnode.node ls ll lx lr) rr) = size (Ordnode.node ls ll lx lr) + size rr
o₁ : WithBot α
o₂ : WithTop α
hl : Valid' o₁ (Ordnode.node ls ll lx lr) o₂
hr : Valid' o₁ (Ordnode.node rs rl rx rr) o₂
sep : All (fun x => All (fun y => x < y) (Ordnode.node rs rl rx rr)) (Ordnode.node ls ll lx lr)
h : ¬delta * ls < rs
h_1 : delta * rs < ls
v : Valid' (↑lx) (merge lr (Ordnode.node rs rl rx rr)) o₂
e : size (merge lr (Ordnode.node rs rl rx rr)) = size lr + size (Ordnode.node rs rl rx rr)
this :
  size (Ordnode.dual (merge lr (Ordnode.node rs rl rx rr))) = rs + size (Ordnode.dual lr) →
    Valid' o₂ (Ordnode.balanceL (Ordnode.dual (merge lr (Ordnode.node rs rl rx rr))) lx (Ordnode.dual ll)) o₁ ∧
      size (Ordnode.balanceL (Ordnode.dual (merge lr (Ordnode.node rs rl rx rr))) lx (Ordnode.dual ll)) = rs + ls
⊢ Valid' o₁ (Ordnode.balanceR ll lx (merge lr (Ordnode.node rs rl rx rr))) o₂ ∧
    size (Ordnode.balanceR ll lx (merge lr (Ordnode.node rs rl rx rr))) =
      size (Ordnode.node ls ll lx lr) + size (Ordnode.node rs rl rx rr)

Next tactic:
rw [size_dual, add_comm, size_dual, ← dual_balanceR, ← Valid'.dual_iff, size_dual,
      add_comm rs] at this
theorem Valid'.merge_aux {l r o₁ o₂} (hl : Valid' o₁ l o₂) (hr : Valid' o₁ r o₂)
    (sep : l.All fun x => r.All fun y => x < y) :
    Valid' o₁ (@merge α l r) o₂ ∧ size (merge l r) = size l + size r := by
  induction' l with ls ll lx lr _ IHlr generalizing o₁ o₂ r
  · exact ⟨hr, (zero_add _).symm⟩
  induction' r with rs rl rx rr IHrl _ generalizing o₁ o₂
  · exact ⟨hl, rfl⟩
  rw [merge_node]; split_ifs with h h_1
  · cases'
      IHrl (hl.of_lt hr.1.1.to_nil <| sep.imp fun x h => h.2.1) hr.left
        (sep.imp fun x h => h.1) with
      v e
    exact Valid'.merge_aux₁ hl hr h v e
  · cases' IHlr hl.right (hr.of_gt hl.1.2.to_nil sep.2.1) sep.2.2 with v e
    have := Valid'.merge_aux₁ hr.dual hl.dual h_1 v.dual
    rw [size_dual, add_comm, size_dual, ← dual_balanceR, ← Valid'.dual_iff, size_dual,
      add_comm rs] at this
    

Proof state:
case pos.intro
α : Type u_1
inst✝ : Preorder α
ls : ℕ
ll : Ordnode α
lx : α
lr : Ordnode α
l_ih✝ :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ ll o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) ll → Valid' o₁ (merge ll r) o₂ ∧ size (merge ll r) = size ll + size r
IHlr :
  ∀ {r : Ordnode α} {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ lr o₂ →
      Valid' o₁ r o₂ →
        All (fun x => All (fun y => x < y) r) lr → Valid' o₁ (merge lr r) o₂ ∧ size (merge lr r) = size lr + size r
rs : ℕ
rl : Ordnode α
rx : α
rr : Ordnode α
IHrl :
  ∀ {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ (Ordnode.node ls ll lx lr) o₂ →
      Valid' o₁ rl o₂ →
        All (fun x => All (fun y => x < y) rl) (Ordnode.node ls ll lx lr) →
          Valid' o₁ (merge (Ordnode.node ls ll lx lr) rl) o₂ ∧
            size (merge (Ordnode.node ls ll lx lr) rl) = size (Ordnode.node ls ll lx lr) + size rl
r_ih✝ :
  ∀ {o₁ : WithBot α} {o₂ : WithTop α},
    Valid' o₁ (Ordnode.node ls ll lx lr) o₂ →
      Valid' o₁ rr o₂ →
        All (fun x => All (fun y => x < y) rr) (Ordnode.node ls ll lx lr) →
          Valid' o₁ (merge (Ordnode.node ls ll lx lr) rr) o₂ ∧
            size (merge (Ordnode.node ls ll lx lr) rr) = size (Ordnode.node ls ll lx lr) + size rr
o₁ : WithBot α
o₂ : WithTop α
hl : Valid' o₁ (Ordnode.node ls ll lx lr) o₂
hr : Valid' o₁ (Ordnode.node rs rl rx rr) o₂
sep : All (fun x => All (fun y => x < y) (Ordnode.node rs rl rx rr)) (Ordnode.node ls ll lx lr)
h : ¬delta * ls < rs
h_1 : delta * rs < ls
v : Valid' (↑lx) (merge lr (Ordnode.node rs rl rx rr)) o₂
e : size (merge lr (Ordnode.node rs rl rx rr)) = size lr + size (Ordnode.node rs rl rx rr)
this :
  size (merge lr (Ordnode.node rs rl rx rr)) = size lr + rs →
    Valid' o₁ (Ordnode.balanceR ll lx (merge lr (Ordnode.node rs rl rx rr))) o₂ ∧
      size (Ordnode.balanceR ll lx (merge lr (Ordnode.node rs rl rx rr))) = ls + rs
⊢ Valid' o₁ (Ordnode.balanceR ll lx (merge lr (Ordnode.node rs rl rx rr))) o₂ ∧
    size (Ordnode.balanceR ll lx (merge lr (Ordnode.node rs rl rx rr))) =
      size (Ordnode.node ls ll lx lr) + size (Ordnode.node rs rl rx rr)

Next tactic:
exact this e