Module: Mathlib.Data.Ordmap.Invariants

Goal state before:
pp: case nil
α : Type u_1
l : Ordnode α
x : α
⊢ (casesOn (id nil)
        (casesOn (id l) (Ordnode.singleton x) fun ls ll lx lr ↦
          casesOn (id ll)
            (casesOn lr (node 2 l x nil) fun size l lrx r ↦ node 3 (Ordnode.singleton lx) lrx (Ordnode.singleton x))
            fun lls l x_1 r ↦
            casesOn (id lr) (node 3 ll lx (Ordnode.singleton x)) fun lrs lrl lrx lrr ↦
              if lrs < ratio * lls then node (ls + 1) ll lx (node (lrs + 1) lr x nil)
              else node (ls + 1) (node (lls + lrl.size + 1) ll lx lrl) lrx (node (lrr.size + 1) lrr x nil))
        fun rs l_1 x_1 r ↦
        casesOn (id l) (node (rs + 1) nil x nil) fun ls ll lx lr ↦
          if ls > delta * rs then
            casesOn (id ll) nil fun lls l x_2 r ↦
              casesOn (id lr) nil fun lrs lrl lrx lrr ↦
                if lrs < ratio * lls then node (ls + rs + 1) ll lx (node (rs + lrs + 1) lr x nil)
                else node (ls + rs + 1) (node (lls + lrl.size + 1) ll lx lrl) lrx (node (lrr.size + rs + 1) lrr x nil)
          else node (ls + rs + 1) l x nil).dual =
    casesOn (id nil.dual)
      (casesOn (id l.dual) (Ordnode.singleton x) fun rs rl rx rr ↦
        casesOn (id rr)
          (casesOn rl (node 2 nil x l.dual) fun size l rlx r ↦ node 3 (Ordnode.singleton x) rlx (Ordnode.singleton rx))
          fun rrs l x_1 r ↦
          casesOn (id rl) (node 3 (Ordnode.singleton x) rx rr) fun rls rll rlx rlr ↦
            if rls < ratio * rrs then node (rs + 1) (node (rls + 1) nil x rl) rx rr
            else node (rs + 1) (node (rll.size + 1) nil x rll) rlx (node (rlr.size + rrs + 1) rlr rx rr))
      fun ls l_1 x_1 r ↦
      casesOn (id l.dual) (node (ls + 1) nil.dual x nil) fun rs rl rx rr ↦
        if rs > delta * ls then
          casesOn (id rr) nil fun rrs l x_2 r ↦
            casesOn (id rl) nil fun rls rll rlx rlr ↦
              if rls < ratio * rrs then node (ls + rs + 1) (node (ls + rls + 1) nil.dual x rl) rx rr
              else
                node (ls + rs + 1) (node (ls + rll.size + 1) nil.dual x rll) rlx (node (rlr.size + rrs + 1) rlr rx rr)
        else node (ls + rs + 1) nil.dual x l.dual

pp: case node
α : Type u_1
l : Ordnode α
x : α
rs : ℕ
rl : Ordnode α
rx : α
rr : Ordnode α
⊢ (casesOn (id (node rs rl rx rr))
        (casesOn (id l) (Ordnode.singleton x) fun ls ll lx lr ↦
          casesOn (id ll)
            (casesOn lr (node 2 l x nil) fun size l lrx r ↦ node 3 (Ordnode.singleton lx) lrx (Ordnode.singleton x))
            fun lls l x_1 r ↦
            casesOn (id lr) (node 3 ll lx (Ordnode.singleton x)) fun lrs lrl lrx lrr ↦
              if lrs < ratio * lls then node (ls + 1) ll lx (node (lrs + 1) lr x nil)
              else node (ls + 1) (node (lls + lrl.size + 1) ll lx lrl) lrx (node (lrr.size + 1) lrr x nil))
        fun rs_1 l_1 x_1 r ↦
        casesOn (id l) (node (rs_1 + 1) nil x (node rs rl rx rr)) fun ls ll lx lr ↦
          if ls > delta * rs_1 then
            casesOn (id ll) nil fun lls l x_2 r ↦
              casesOn (id lr) nil fun lrs lrl lrx lrr ↦
                if lrs < ratio * lls then node (ls + rs_1 + 1) ll lx (node (rs_1 + lrs + 1) lr x (node rs rl rx rr))
                else
                  node (ls + rs_1 + 1) (node (lls + lrl.size + 1) ll lx lrl) lrx
                    (node (lrr.size + rs_1 + 1) lrr x (node rs rl rx rr))
          else node (ls + rs_1 + 1) l x (node rs rl rx rr)).dual =
    casesOn (id (node rs rl rx rr).dual)
      (casesOn (id l.dual) (Ordnode.singleton x) fun rs rl rx rr ↦
        casesOn (id rr)
          (casesOn rl (node 2 nil x l.dual) fun size l rlx r ↦ node 3 (Ordnode.singleton x) rlx (Ordnode.singleton rx))
          fun rrs l x_1 r ↦
          casesOn (id rl) (node 3 (Ordnode.singleton x) rx rr) fun rls rll rlx rlr ↦
            if rls < ratio * rrs then node (rs + 1) (node (rls + 1) nil x rl) rx rr
            else node (rs + 1) (node (rll.size + 1) nil x rll) rlx (node (rlr.size + rrs + 1) rlr rx rr))
      fun ls l_1 x_1 r ↦
      casesOn (id l.dual) (node (ls + 1) (node rs rl rx rr).dual x nil) fun rs_1 rl_1 rx_1 rr_1 ↦
        if rs_1 > delta * ls then
          casesOn (id rr_1) nil fun rrs l x_2 r ↦
            casesOn (id rl_1) nil fun rls rll rlx rlr ↦
              if rls < ratio * rrs then
                node (ls + rs_1 + 1) (node (ls + rls + 1) (node rs rl rx rr).dual x rl_1) rx_1 rr_1
              else
                node (ls + rs_1 + 1) (node (ls + rll.size + 1) (node rs rl rx rr).dual x rll) rlx
                  (node (rlr.size + rrs + 1) rlr rx_1 rr_1)
        else node (ls + rs_1 + 1) (node rs rl rx rr).dual x l.dual

Tactic:
· obtain - | ⟨ls, ll, lx, lr⟩ := l; · rfl
    obtain - | ⟨lls, lll, llx, llr⟩ := ll <;> obtain - | ⟨lrs, lrl, lrx, lrr⟩ := lr <;>
      dsimp only [dual, id] <;> try rfl
    split_ifs with h <;> repeat simp [add_comm]

Goal state after:
case node
α : Type u_1
l : Ordnode α
x : α
rs : ℕ
rl : Ordnode α
rx : α
rr : Ordnode α
⊢ (casesOn (id (node rs rl rx rr))
        (casesOn (id l) (Ordnode.singleton x) fun ls ll lx lr ↦
          casesOn (id ll)
            (casesOn lr (node 2 l x nil) fun size l lrx r ↦ node 3 (Ordnode.singleton lx) lrx (Ordnode.singleton x))
            fun lls l x_1 r ↦
            casesOn (id lr) (node 3 ll lx (Ordnode.singleton x)) fun lrs lrl lrx lrr ↦
              if lrs < ratio * lls then node (ls + 1) ll lx (node (lrs + 1) lr x nil)
              else node (ls + 1) (node (lls + lrl.size + 1) ll lx lrl) lrx (node (lrr.size + 1) lrr x nil))
        fun rs_1 l_1 x_1 r ↦
        casesOn (id l) (node (rs_1 + 1) nil x (node rs rl rx rr)) fun ls ll lx lr ↦
          if ls > delta * rs_1 then
            casesOn (id ll) nil fun lls l x_2 r ↦
              casesOn (id lr) nil fun lrs lrl lrx lrr ↦
                if lrs < ratio * lls then node (ls + rs_1 + 1) ll lx (node (rs_1 + lrs + 1) lr x (node rs rl rx rr))
                else
                  node (ls + rs_1 + 1) (node (lls + lrl.size + 1) ll lx lrl) lrx
                    (node (lrr.size + rs_1 + 1) lrr x (node rs rl rx rr))
          else node (ls + rs_1 + 1) l x (node rs rl rx rr)).dual =
    casesOn (id (node rs rl rx rr).dual)
      (casesOn (id l.dual) (Ordnode.singleton x) fun rs rl rx rr ↦
        casesOn (id rr)
          (casesOn rl (node 2 nil x l.dual) fun size l rlx r ↦ node 3 (Ordnode.singleton x) rlx (Ordnode.singleton rx))
          fun rrs l x_1 r ↦
          casesOn (id rl) (node 3 (Ordnode.singleton x) rx rr) fun rls rll rlx rlr ↦
            if rls < ratio * rrs then node (rs + 1) (node (rls + 1) nil x rl) rx rr
            else node (rs + 1) (node (rll.size + 1) nil x rll) rlx (node (rlr.size + rrs + 1) rlr rx rr))
      fun ls l_1 x_1 r ↦
      casesOn (id l.dual) (node (ls + 1) (node rs rl rx rr).dual x nil) fun rs_1 rl_1 rx_1 rr_1 ↦
        if rs_1 > delta * ls then
          casesOn (id rr_1) nil fun rrs l x_2 r ↦
            casesOn (id rl_1) nil fun rls rll rlx rlr ↦
              if rls < ratio * rrs then
                node (ls + rs_1 + 1) (node (ls + rls + 1) (node rs rl rx rr).dual x rl_1) rx_1 rr_1
              else
                node (ls + rs_1 + 1) (node (ls + rll.size + 1) (node rs rl rx rr).dual x rll) rlx
                  (node (rlr.size + rrs + 1) rlr rx_1 rr_1)
        else node (ls + rs_1 + 1) (node rs rl rx rr).dual x l.dual