l3lab/ntp-mathlib huggingface dataset:
theorem dual_balanceL (l : Ordnode α) (x : α) (r : Ordnode α) :
    dual (balanceL l x r) = balanceR (dual r) x (dual l) := by
  unfold balanceL balanceR
  cases' r with rs rl rx rr
  · cases' l with ls ll lx lr; · rfl
    cases' ll with lls lll llx llr <;> cases' lr with lrs lrl lrx lrr <;> dsimp only [dual, id] <;>
      try rfl
    split_ifs with h <;> repeat simp [h, add_comm]
  · cases' l with ls ll lx lr; · rfl
    dsimp only [dual, id]
    split_ifs; swap; · simp [add_comm]
    cases' ll with lls lll llx llr <;> cases' lr with lrs lrl lrx lrr <;> try 

Proof state:
case pos.node.node
α : Type u_1
x : α
rs : ℕ
rl : Ordnode α
rx : α
rr : Ordnode α
ls : ℕ
lx : α
h✝ : ls > delta * rs
lls : ℕ
lll : Ordnode α
llx : α
llr : Ordnode α
lrs : ℕ
lrl : Ordnode α
lrx : α
lrr : Ordnode α
⊢ dual
      (rec (motive := fun t => node lls lll llx llr = t → Ordnode α) (fun h => nil)
        (fun size l x_1 r l_ih r_ih h =>
          rec (motive := fun t => node lrs lrl lrx lrr = t → Ordnode α) (fun h => nil)
            (fun size_1 l x_2 r l_ih r_ih h =>
              if size_1 < ratio * size then
                node (ls + rs + 1) (node lls lll llx llr) lx
                  (node (rs + size_1 + 1) (node lrs lrl lrx lrr) x (node rs rl rx rr))
              else
                node (ls + rs + 1) (node (size + Ordnode.size l + 1) (node lls lll llx llr) lx l) x_2
                  (node (Ordnode.size r + rs + 1) r x (node rs rl rx rr)))
            (node lrs lrl lrx lrr) (_ : id (node lrs lrl lrx lrr) = id (node lrs lrl lrx lrr)))
        (node lls lll llx llr) (_ : id (node lls lll llx llr) = id (node lls lll llx llr))) =
    rec (motive := fun t => dual (node lls lll llx llr) = t → Ordnode α) (fun h => nil)
      (fun size l x_1 r l_ih r_ih h =>
        rec (motive := fun t => dual (node lrs lrl lrx lrr) = t → Ordnode α) (fun h => nil)
          (fun size_1 l x_2 r l_ih r_ih h =>
            if size_1 < ratio * size then
              node (rs + ls + 1)
                (node (rs + size_1 + 1) (node rs (dual rr) rx (dual rl)) x (dual (node lrs lrl lrx lrr))) lx
                (dual (node lls lll llx llr))
            else
              node (rs + ls + 1) (node (rs + Ordnode.size l + 1) (node rs (dual rr) rx (dual rl)) x l) x_2
                (node (Ordnode.size r + size + 1) r lx (dual (node lls lll llx llr))))
          (dual (node lrs lrl lrx lrr)) (_ : id (dual (node lrs lrl lrx lrr)) = id (dual (node lrs lrl lrx lrr))))
      (dual (node lls lll llx llr)) (_ : id (dual (node lls lll llx llr)) = id (dual (node lls lll llx llr)))

Next tactic:
rfl
theorem dual_balanceL (l : Ordnode α) (x : α) (r : Ordnode α) :
    dual (balanceL l x r) = balanceR (dual r) x (dual l) := by
  unfold balanceL balanceR
  cases' r with rs rl rx rr
  · cases' l with ls ll lx lr; · rfl
    cases' ll with lls lll llx llr <;> cases' lr with lrs lrl lrx lrr <;> dsimp only [dual, id] <;>
      try rfl
    split_ifs with h <;> repeat simp [h, add_comm]
  · cases' l with ls ll lx lr; · rfl
    dsimp only [dual, id]
    split_ifs; swap; · simp [add_comm]
    cases' ll with lls lll llx llr <;> cases' lr with lrs lrl lrx lrr <;> try rfl
    

Proof state:
case pos.node.node
α : Type u_1
x : α
rs : ℕ
rl : Ordnode α
rx : α
rr : Ordnode α
ls : ℕ
lx : α
h✝ : ls > delta * rs
lls : ℕ
lll : Ordnode α
llx : α
llr : Ordnode α
lrs : ℕ
lrl : Ordnode α
lrx : α
lrr : Ordnode α
⊢ dual
      (rec (motive := fun t => node lls lll llx llr = t → Ordnode α) (fun h => nil)
        (fun size l x_1 r l_ih r_ih h =>
          rec (motive := fun t => node lrs lrl lrx lrr = t → Ordnode α) (fun h => nil)
            (fun size_1 l x_2 r l_ih r_ih h =>
              if size_1 < ratio * size then
                node (ls + rs + 1) (node lls lll llx llr) lx
                  (node (rs + size_1 + 1) (node lrs lrl lrx lrr) x (node rs rl rx rr))
              else
                node (ls + rs + 1) (node (size + Ordnode.size l + 1) (node lls lll llx llr) lx l) x_2
                  (node (Ordnode.size r + rs + 1) r x (node rs rl rx rr)))
            (node lrs lrl lrx lrr) (_ : id (node lrs lrl lrx lrr) = id (node lrs lrl lrx lrr)))
        (node lls lll llx llr) (_ : id (node lls lll llx llr) = id (node lls lll llx llr))) =
    rec (motive := fun t => dual (node lls lll llx llr) = t → Ordnode α) (fun h => nil)
      (fun size l x_1 r l_ih r_ih h =>
        rec (motive := fun t => dual (node lrs lrl lrx lrr) = t → Ordnode α) (fun h => nil)
          (fun size_1 l x_2 r l_ih r_ih h =>
            if size_1 < ratio * size then
              node (rs + ls + 1)
                (node (rs + size_1 + 1) (node rs (dual rr) rx (dual rl)) x (dual (node lrs lrl lrx lrr))) lx
                (dual (node lls lll llx llr))
            else
              node (rs + ls + 1) (node (rs + Ordnode.size l + 1) (node rs (dual rr) rx (dual rl)) x l) x_2
                (node (Ordnode.size r + size + 1) r lx (dual (node lls lll llx llr))))
          (dual (node lrs lrl lrx lrr)) (_ : id (dual (node lrs lrl lrx lrr)) = id (dual (node lrs lrl lrx lrr))))
      (dual (node lls lll llx llr)) (_ : id (dual (node lls lll llx llr)) = id (dual (node lls lll llx llr)))

Next tactic:
dsimp only [dual, id]
theorem dual_balanceL (l : Ordnode α) (x : α) (r : Ordnode α) :
    dual (balanceL l x r) = balanceR (dual r) x (dual l) := by
  unfold balanceL balanceR
  cases' r with rs rl rx rr
  · cases' l with ls ll lx lr; · rfl
    cases' ll with lls lll llx llr <;> cases' lr with lrs lrl lrx lrr <;> dsimp only [dual, id] <;>
      try rfl
    split_ifs with h <;> repeat simp [h, add_comm]
  · cases' l with ls ll lx lr; · rfl
    dsimp only [dual, id]
    split_ifs; swap; · simp [add_comm]
    cases' ll with lls lll llx llr <;> cases' lr with lrs lrl lrx lrr <;> try rfl
    dsimp only [dual, id]
    

Proof state:
case pos.node.node
α : Type u_1
x : α
rs : ℕ
rl : Ordnode α
rx : α
rr : Ordnode α
ls : ℕ
lx : α
h✝ : ls > delta * rs
lls : ℕ
lll : Ordnode α
llx : α
llr : Ordnode α
lrs : ℕ
lrl : Ordnode α
lrx : α
lrr : Ordnode α
⊢ dual
      (if lrs < ratio * lls then
        node (ls + rs + 1) (node lls lll llx llr) lx (node (rs + lrs + 1) (node lrs lrl lrx lrr) x (node rs rl rx rr))
      else
        node (ls + rs + 1) (node (lls + size lrl + 1) (node lls lll llx llr) lx lrl) lrx
          (node (size lrr + rs + 1) lrr x (node rs rl rx rr))) =
    if lrs < ratio * lls then
      node (rs + ls + 1) (node (rs + lrs + 1) (node rs (dual rr) rx (dual rl)) x (node lrs (dual lrr) lrx (dual lrl)))
        lx (node lls (dual llr) llx (dual lll))
    else
      node (rs + ls + 1) (node (rs + size (dual lrr) + 1) (node rs (dual rr) rx (dual rl)) x (dual lrr)) lrx
        (node (size (dual lrl) + lls + 1) (dual lrl) lx (node lls (dual llr) llx (dual lll)))

Next tactic:
split_ifs with h
theorem dual_balanceL (l : Ordnode α) (x : α) (r : Ordnode α) :
    dual (balanceL l x r) = balanceR (dual r) x (dual l) := by
  unfold balanceL balanceR
  cases' r with rs rl rx rr
  · cases' l with ls ll lx lr; · rfl
    cases' ll with lls lll llx llr <;> cases' lr with lrs lrl lrx lrr <;> dsimp only [dual, id] <;>
      try rfl
    split_ifs with h <;> repeat simp [h, add_comm]
  · cases' l with ls ll lx lr; · rfl
    dsimp only [dual, id]
    split_ifs; swap; · simp [add_comm]
    cases' ll with lls lll llx llr <;> cases' lr with lrs lrl lrx lrr <;> try rfl
    dsimp only [dual, id]
    split_ifs with h <;> 

Proof state:
case pos
α : Type u_1
x : α
rs : ℕ
rl : Ordnode α
rx : α
rr : Ordnode α
ls : ℕ
lx : α
h✝ : ls > delta * rs
lls : ℕ
lll : Ordnode α
llx : α
llr : Ordnode α
lrs : ℕ
lrl : Ordnode α
lrx : α
lrr : Ordnode α
h : lrs < ratio * lls
⊢ dual
      (node (ls + rs + 1) (node lls lll llx llr) lx (node (rs + lrs + 1) (node lrs lrl lrx lrr) x (node rs rl rx rr))) =
    node (rs + ls + 1) (node (rs + lrs + 1) (node rs (dual rr) rx (dual rl)) x (node lrs (dual lrr) lrx (dual lrl))) lx
      (node lls (dual llr) llx (dual lll))

Next tactic:
simp [h, add_comm]
theorem dual_balanceL (l : Ordnode α) (x : α) (r : Ordnode α) :
    dual (balanceL l x r) = balanceR (dual r) x (dual l) := by
  unfold balanceL balanceR
  cases' r with rs rl rx rr
  · cases' l with ls ll lx lr; · rfl
    cases' ll with lls lll llx llr <;> cases' lr with lrs lrl lrx lrr <;> dsimp only [dual, id] <;>
      try rfl
    split_ifs with h <;> repeat simp [h, add_comm]
  · cases' l with ls ll lx lr; · rfl
    dsimp only [dual, id]
    split_ifs; swap; · simp [add_comm]
    cases' ll with lls lll llx llr <;> cases' lr with lrs lrl lrx lrr <;> try rfl
    dsimp only [dual, id]
    split_ifs with h <;> 

Proof state:
case neg
α : Type u_1
x : α
rs : ℕ
rl : Ordnode α
rx : α
rr : Ordnode α
ls : ℕ
lx : α
h✝ : ls > delta * rs
lls : ℕ
lll : Ordnode α
llx : α
llr : Ordnode α
lrs : ℕ
lrl : Ordnode α
lrx : α
lrr : Ordnode α
h : ¬lrs < ratio * lls
⊢ dual
      (node (ls + rs + 1) (node (lls + size lrl + 1) (node lls lll llx llr) lx lrl) lrx
        (node (size lrr + rs + 1) lrr x (node rs rl rx rr))) =
    node (rs + ls + 1) (node (rs + size (dual lrr) + 1) (node rs (dual rr) rx (dual rl)) x (dual lrr)) lrx
      (node (size (dual lrl) + lls + 1) (dual lrl) lx (node lls (dual llr) llx (dual lll)))

Next tactic:
simp [h, add_comm]
theorem dual_balanceR (l : Ordnode α) (x : α) (r : Ordnode α) :
    dual (balanceR l x r) = balanceL (dual r) x (dual l) := by
  

Proof state:
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
⊢ dual (balanceR l x r) = balanceL (dual r) x (dual l)

Next tactic:
rw [← dual_dual (balanceL _ _ _), dual_balanceL, dual_dual, dual_dual]
theorem Sized.node4L {l x m y r} (hl : @Sized α l) (hm : Sized m) (hr : Sized r) :
    Sized (node4L l x m y r) := by
  

Proof state:
α : Type u_1
l : Ordnode α
x : α
m : Ordnode α
y : α
r : Ordnode α
hl : Sized l
hm : Sized m
hr : Sized r
⊢ Sized (Ordnode.node4L l x m y r)

Next tactic:
cases m <;> [exact (hl.node' hm).node' hr; exact (hl.node' hm.2.1).node' (hm.2.2.node' hr)]
theorem Sized.node4L {l x m y r} (hl : @Sized α l) (hm : Sized m) (hr : Sized r) :
    Sized (node4L l x m y r) := by
  

Proof state:
α : Type u_1
l : Ordnode α
x : α
m : Ordnode α
y : α
r : Ordnode α
hl : Sized l
hm : Sized m
hr : Sized r
⊢ Sized (Ordnode.node4L l x m y r)

Next tactic:
cases m
theorem Sized.node4L {l x m y r} (hl : @Sized α l) (hm : Sized m) (hr : Sized r) :
    Sized (node4L l x m y r) := by
  cases m <;> [

Proof state:
case nil
α : Type u_1
l : Ordnode α
x y : α
r : Ordnode α
hl : Sized l
hr : Sized r
hm : Sized nil
⊢ Sized (Ordnode.node4L l x nil y r)

Next tactic:
exact (hl.node' hm).node' hr
theorem Sized.node4L {l x m y r} (hl : @Sized α l) (hm : Sized m) (hr : Sized r) :
    Sized (node4L l x m y r) := by
  cases m <;> [exact (hl.node' hm).node' hr; 

Proof state:
case node
α : Type u_1
l : Ordnode α
x y : α
r : Ordnode α
hl : Sized l
hr : Sized r
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
hm : Sized (node size✝ l✝ x✝ r✝)
⊢ Sized (Ordnode.node4L l x (node size✝ l✝ x✝ r✝) y r)

Next tactic:
exact (hl.node' hm.2.1).node' (hm.2.2.node' hr)
theorem node3L_size {l x m y r} : size (@node3L α l x m y r) = size l + size m + size r + 2 := by
  

Proof state:
α : Type u_1
l : Ordnode α
x : α
m : Ordnode α
y : α
r : Ordnode α
⊢ size (node3L l x m y r) = size l + size m + size r + 2

Next tactic:
dsimp [node3L, node', size]
theorem node3L_size {l x m y r} : size (@node3L α l x m y r) = size l + size m + size r + 2 := by
  dsimp [node3L, node', size]; 

Proof state:
α : Type u_1
l : Ordnode α
x : α
m : Ordnode α
y : α
r : Ordnode α
⊢ (((match l with
            | nil => 0
            | node sz l x r => sz) +
            match m with
            | nil => 0
            | node sz l x r => sz) +
          1 +
        match r with
        | nil => 0
        | node sz l x r => sz) +
      1 =
    (((match l with
          | nil => 0
          | node sz l x r => sz) +
          match m with
          | nil => 0
          | node sz l x r => sz) +
        match r with
        | nil => 0
        | node sz l x r => sz) +
      2

Next tactic:
rw [add_right_comm _ 1]
theorem node3R_size {l x m y r} : size (@node3R α l x m y r) = size l + size m + size r + 2 := by
  

Proof state:
α : Type u_1
l : Ordnode α
x : α
m : Ordnode α
y : α
r : Ordnode α
⊢ size (node3R l x m y r) = size l + size m + size r + 2

Next tactic:
dsimp [node3R, node', size]
theorem node3R_size {l x m y r} : size (@node3R α l x m y r) = size l + size m + size r + 2 := by
  dsimp [node3R, node', size]; 

Proof state:
α : Type u_1
l : Ordnode α
x : α
m : Ordnode α
y : α
r : Ordnode α
⊢ (match l with
        | nil => 0
        | node sz l x r => sz) +
        (((match m with
            | nil => 0
            | node sz l x r => sz) +
            match r with
            | nil => 0
            | node sz l x r => sz) +
          1) +
      1 =
    (((match l with
          | nil => 0
          | node sz l x r => sz) +
          match m with
          | nil => 0
          | node sz l x r => sz) +
        match r with
        | nil => 0
        | node sz l x r => sz) +
      2

Next tactic:
rw [← add_assoc, ← add_assoc]
theorem node4L_size {l x m y r} (hm : Sized m) :
    size (@node4L α l x m y r) = size l + size m + size r + 2 := by
  

Proof state:
α : Type u_1
l : Ordnode α
x : α
m : Ordnode α
y : α
r : Ordnode α
hm : Sized m
⊢ size (node4L l x m y r) = size l + size m + size r + 2

Next tactic:
cases m <;> simp [node4L, node3L, node'] <;> [skip; simp [size, hm.1]]
theorem node4L_size {l x m y r} (hm : Sized m) :
    size (@node4L α l x m y r) = size l + size m + size r + 2 := by
  

Proof state:
α : Type u_1
l : Ordnode α
x : α
m : Ordnode α
y : α
r : Ordnode α
hm : Sized m
⊢ size (node4L l x m y r) = size l + size m + size r + 2

Next tactic:
cases m
theorem node4L_size {l x m y r} (hm : Sized m) :
    size (@node4L α l x m y r) = size l + size m + size r + 2 := by
  cases m <;> 

Proof state:
case nil
α : Type u_1
l : Ordnode α
x y : α
r : Ordnode α
hm : Sized nil
⊢ size (node4L l x nil y r) = size l + size nil + size r + 2

Next tactic:
simp [node4L, node3L, node']
theorem node4L_size {l x m y r} (hm : Sized m) :
    size (@node4L α l x m y r) = size l + size m + size r + 2 := by
  cases m <;> 

Proof state:
case node
α : Type u_1
l : Ordnode α
x y : α
r : Ordnode α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
hm : Sized (node size✝ l✝ x✝ r✝)
⊢ size (node4L l x (node size✝ l✝ x✝ r✝) y r) = size l + size (node size✝ l✝ x✝ r✝) + size r + 2

Next tactic:
simp [node4L, node3L, node']
theorem node4L_size {l x m y r} (hm : Sized m) :
    size (@node4L α l x m y r) = size l + size m + size r + 2 := by
  cases m <;> simp [node4L, node3L, node'] <;> [

Proof state:
case nil
α : Type u_1
l : Ordnode α
x y : α
r : Ordnode α
hm : Sized nil
⊢ size l + 1 + size r = size l + size r + 1

Next tactic:
skip
theorem node4L_size {l x m y r} (hm : Sized m) :
    size (@node4L α l x m y r) = size l + size m + size r + 2 := by
  cases m <;> simp [node4L, node3L, node'] <;> [skip; 

Proof state:
case node
α : Type u_1
l : Ordnode α
x y : α
r : Ordnode α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
hm : Sized (node size✝ l✝ x✝ r✝)
⊢ size l + size l✝ + 1 + (size r✝ + size r + 1) = size l + size✝ + size r + 1

Next tactic:
simp [size, hm.1]
theorem node4L_size {l x m y r} (hm : Sized m) :
    size (@node4L α l x m y r) = size l + size m + size r + 2 := by
  cases m <;> simp [node4L, node3L, node'] <;> [skip; simp [size, hm.1]] <;> 

Proof state:
case nil
α : Type u_1
l : Ordnode α
x y : α
r : Ordnode α
hm : Sized nil
⊢ size l + 1 + size r = size l + size r + 1

Next tactic:
abel
theorem node4L_size {l x m y r} (hm : Sized m) :
    size (@node4L α l x m y r) = size l + size m + size r + 2 := by
  cases m <;> simp [node4L, node3L, node'] <;> [skip; simp [size, hm.1]] <;> 

Proof state:
case node
α : Type u_1
l : Ordnode α
x y : α
r : Ordnode α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
hm : Sized (node size✝ l✝ x✝ r✝)
⊢ size l + size l✝ + 1 + (size r✝ + size r + 1) = size l + (size l✝ + size r✝ + 1) + size r + 1

Next tactic:
abel
theorem Sized.dual : ∀ {t : Ordnode α}, Sized t → Sized (dual t)
  | nil, _ => ⟨⟩
  | node _ l _ r, ⟨rfl, sl, sr⟩ => ⟨by 

Proof state:
α : Type u_1
l : Ordnode α
x✝ : α
r : Ordnode α
sl : Sized l
sr : Sized r
⊢ size l + size r + 1 = size (Ordnode.dual r) + size (Ordnode.dual l) + 1

Next tactic:
simp [size_dual, add_comm]
theorem Sized.dual_iff {t : Ordnode α} : Sized (.dual t) ↔ Sized t :=
  ⟨fun h => by 

Proof state:
α : Type u_1
t : Ordnode α
h : Sized (Ordnode.dual t)
⊢ Sized t

Next tactic:
rw [← dual_dual t]
theorem Sized.dual_iff {t : Ordnode α} : Sized (.dual t) ↔ Sized t :=
  ⟨fun h => by rw [← dual_dual t]; 

Proof state:
α : Type u_1
t : Ordnode α
h : Sized (Ordnode.dual t)
⊢ Sized (Ordnode.dual (Ordnode.dual t))

Next tactic:
exact h.dual
theorem Sized.rotateL {l x r} (hl : @Sized α l) (hr : Sized r) : Sized (rotateL l x r) := by
  

Proof state:
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
hl : Sized l
hr : Sized r
⊢ Sized (Ordnode.rotateL l x r)

Next tactic:
cases r
theorem Sized.rotateL {l x r} (hl : @Sized α l) (hr : Sized r) : Sized (rotateL l x r) := by
  cases r; · 

Proof state:
case nil
α : Type u_1
l : Ordnode α
x : α
hl : Sized l
hr : Sized nil
⊢ Sized (Ordnode.rotateL l x nil)

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

Proof state:
case node
α : Type u_1
l : Ordnode α
x : α
hl : Sized l
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
hr : Sized (node size✝ l✝ x✝ r✝)
⊢ Sized (Ordnode.rotateL l x (node size✝ l✝ x✝ r✝))

Next tactic:
rw [Ordnode.rotateL]
theorem Sized.rotateL {l x r} (hl : @Sized α l) (hr : Sized r) : Sized (rotateL l x r) := by
  cases r; · exact hl.node' hr
  rw [Ordnode.rotateL]; 

Proof state:
case node
α : Type u_1
l : Ordnode α
x : α
hl : Sized l
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
hr : Sized (node size✝ l✝ x✝ r✝)
⊢ Sized (if size l✝ < ratio * size r✝ then Ordnode.node3L l x l✝ x✝ r✝ else Ordnode.node4L l x l✝ x✝ r✝)

Next tactic:
split_ifs
theorem Sized.rotateL {l x r} (hl : @Sized α l) (hr : Sized r) : Sized (rotateL l x r) := by
  cases r; · exact hl.node' hr
  rw [Ordnode.rotateL]; split_ifs
  · 

Proof state:
case pos
α : Type u_1
l : Ordnode α
x : α
hl : Sized l
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
hr : Sized (node size✝ l✝ x✝ r✝)
h✝ : size l✝ < ratio * size r✝
⊢ Sized (Ordnode.node3L l x l✝ x✝ r✝)

Next tactic:
exact hl.node3L hr.2.1 hr.2.2
theorem Sized.rotateL {l x r} (hl : @Sized α l) (hr : Sized r) : Sized (rotateL l x r) := by
  cases r; · exact hl.node' hr
  rw [Ordnode.rotateL]; split_ifs
  · exact hl.node3L hr.2.1 hr.2.2
  · 

Proof state:
case neg
α : Type u_1
l : Ordnode α
x : α
hl : Sized l
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
hr : Sized (node size✝ l✝ x✝ r✝)
h✝ : ¬size l✝ < ratio * size r✝
⊢ Sized (Ordnode.node4L l x l✝ x✝ r✝)

Next tactic:
exact hl.node4L hr.2.1 hr.2.2
theorem Sized.rotateR {l x r} (hl : @Sized α l) (hr : Sized r) : Sized (rotateR l x r) :=
  Sized.dual_iff.1 <| by 

Proof state:
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
hl : Sized l
hr : Sized r
⊢ Sized (Ordnode.dual (Ordnode.rotateR l x r))

Next tactic:
rw [dual_rotateR]
theorem Sized.rotateR {l x r} (hl : @Sized α l) (hr : Sized r) : Sized (rotateR l x r) :=
  Sized.dual_iff.1 <| by rw [dual_rotateR]; 

Proof state:
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
hl : Sized l
hr : Sized r
⊢ Sized (Ordnode.rotateL (Ordnode.dual r) x (Ordnode.dual l))

Next tactic:
exact hr.dual.rotateL hl.dual
theorem Sized.rotateL_size {l x r} (hm : Sized r) :
    size (@Ordnode.rotateL α l x r) = size l + size r + 1 := by
  

Proof state:
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
hm : Sized r
⊢ size (Ordnode.rotateL l x r) = size l + size r + 1

Next tactic:
cases r
theorem Sized.rotateL_size {l x r} (hm : Sized r) :
    size (@Ordnode.rotateL α l x r) = size l + size r + 1 := by
  cases r <;> 

Proof state:
case nil
α : Type u_1
l : Ordnode α
x : α
hm : Sized nil
⊢ size (Ordnode.rotateL l x nil) = size l + size nil + 1

Next tactic:
simp [Ordnode.rotateL]
theorem Sized.rotateL_size {l x r} (hm : Sized r) :
    size (@Ordnode.rotateL α l x r) = size l + size r + 1 := by
  cases r <;> 

Proof state:
case node
α : Type u_1
l : Ordnode α
x : α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
hm : Sized (node size✝ l✝ x✝ r✝)
⊢ size (Ordnode.rotateL l x (node size✝ l✝ x✝ r✝)) = size l + size (node size✝ l✝ x✝ r✝) + 1

Next tactic:
simp [Ordnode.rotateL]
theorem Sized.rotateL_size {l x r} (hm : Sized r) :
    size (@Ordnode.rotateL α l x r) = size l + size r + 1 := by
  cases r <;> simp [Ordnode.rotateL]
  

Proof state:
case node
α : Type u_1
l : Ordnode α
x : α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
hm : Sized (node size✝ l✝ x✝ r✝)
⊢ size (if size l✝ < ratio * size r✝ then Ordnode.node3L l x l✝ x✝ r✝ else Ordnode.node4L l x l✝ x✝ r✝) =
    size l + size✝ + 1

Next tactic:
simp only [hm.1]
theorem Sized.rotateL_size {l x r} (hm : Sized r) :
    size (@Ordnode.rotateL α l x r) = size l + size r + 1 := by
  cases r <;> simp [Ordnode.rotateL]
  simp only [hm.1]
  

Proof state:
case node
α : Type u_1
l : Ordnode α
x : α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
hm : Sized (node size✝ l✝ x✝ r✝)
⊢ size (if size l✝ < ratio * size r✝ then Ordnode.node3L l x l✝ x✝ r✝ else Ordnode.node4L l x l✝ x✝ r✝) =
    size l + (size l✝ + size r✝ + 1) + 1

Next tactic:
split_ifs
theorem Sized.rotateL_size {l x r} (hm : Sized r) :
    size (@Ordnode.rotateL α l x r) = size l + size r + 1 := by
  cases r <;> simp [Ordnode.rotateL]
  simp only [hm.1]
  split_ifs <;> 

Proof state:
case pos
α : Type u_1
l : Ordnode α
x : α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
hm : Sized (node size✝ l✝ x✝ r✝)
h✝ : size l✝ < ratio * size r✝
⊢ size (Ordnode.node3L l x l✝ x✝ r✝) = size l + (size l✝ + size r✝ + 1) + 1

Next tactic:
simp [node3L_size, node4L_size hm.2.1]
theorem Sized.rotateL_size {l x r} (hm : Sized r) :
    size (@Ordnode.rotateL α l x r) = size l + size r + 1 := by
  cases r <;> simp [Ordnode.rotateL]
  simp only [hm.1]
  split_ifs <;> 

Proof state:
case neg
α : Type u_1
l : Ordnode α
x : α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
hm : Sized (node size✝ l✝ x✝ r✝)
h✝ : ¬size l✝ < ratio * size r✝
⊢ size (Ordnode.node4L l x l✝ x✝ r✝) = size l + (size l✝ + size r✝ + 1) + 1

Next tactic:
simp [node3L_size, node4L_size hm.2.1]
theorem Sized.rotateL_size {l x r} (hm : Sized r) :
    size (@Ordnode.rotateL α l x r) = size l + size r + 1 := by
  cases r <;> simp [Ordnode.rotateL]
  simp only [hm.1]
  split_ifs <;> simp [node3L_size, node4L_size hm.2.1] <;> 

Proof state:
case pos
α : Type u_1
l : Ordnode α
x : α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
hm : Sized (node size✝ l✝ x✝ r✝)
h✝ : size l✝ < ratio * size r✝
⊢ size l + size l✝ + size r✝ + 1 = size l + (size l✝ + size r✝ + 1)

Next tactic:
abel
theorem Sized.rotateL_size {l x r} (hm : Sized r) :
    size (@Ordnode.rotateL α l x r) = size l + size r + 1 := by
  cases r <;> simp [Ordnode.rotateL]
  simp only [hm.1]
  split_ifs <;> simp [node3L_size, node4L_size hm.2.1] <;> 

Proof state:
case neg
α : Type u_1
l : Ordnode α
x : α
size✝ : ℕ
l✝ : Ordnode α
x✝ : α
r✝ : Ordnode α
hm : Sized (node size✝ l✝ x✝ r✝)
h✝ : ¬size l✝ < ratio * size r✝
⊢ size l + size l✝ + size r✝ + 1 = size l + (size l✝ + size r✝ + 1)

Next tactic:
abel
theorem Sized.rotateR_size {l x r} (hl : Sized l) :
    size (@Ordnode.rotateR α l x r) = size l + size r + 1 := by
  

Proof state:
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
hl : Sized l
⊢ size (Ordnode.rotateR l x r) = size l + size r + 1

Next tactic:
rw [← size_dual, dual_rotateR, hl.dual.rotateL_size, size_dual, size_dual, add_comm (size l)]
theorem Sized.balance' {l x r} (hl : @Sized α l) (hr : Sized r) : Sized (balance' l x r) := by
  

Proof state:
α : Type u_1
l : Ordnode α
x : α
r : Ordnode α
hl : Sized l
hr : Sized r
⊢ Sized (Ordnode.balance' l x r)

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

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

Next tactic:
split_ifs