Theorem: Std.BinomialHeapImp.Heap.WellFormed.merge'
File: Std/Data/BinomialHeap.lean

tactic: unfold merge
state_before: α✝ : Type u_1
le : α✝ → α✝ → Bool
s₁ s₂ : Heap α✝
n : Nat
h₁ : WellFormed le n s₁
h₂ : WellFormed le n s₂
⊢ WellFormed le n (merge le s₁ s₂) ∧ ((Heap.rankGT s₁ n ↔ Heap.rankGT s₂ n) → Heap.rankGT (merge le s₁ s₂) n)

tactic: split
state_before: α✝ : Type u_1
le : α✝ → α✝ → Bool
s₁ s₂ : Heap α✝
n : Nat
h₁ : WellFormed le n s₁
h₂ : WellFormed le n s₂
⊢ WellFormed le n
      (match s₁, s₂ with
      | Heap.nil, h => h
      | h, Heap.nil => h
      | s₁@h:(cons r₁ a₁ n₁ t₁), s₂@h_1:(cons r₂ a₂ n₂ t₂) =>
        if r₁ < r₂ then cons r₁ a₁ n₁ (merge le t₁ s₂)
        else
          if r₂ < r₁ then cons r₂ a₂ n₂ (merge le s₁ t₂)
          else
            match combine le a₁ a₂ n₁ n₂ with
            | (a, n) =>
              let r := r₁ + 1;
              if Heap.rankGT t₁ r then
                if Heap.rankGT t₂ r then cons r a n (merge le t₁ t₂) else merge le (cons r a n t₁) t₂
              else if Heap.rankGT t₂ r then merge le t₁ (cons r a n t₂) else cons r a n (merge le t₁ t₂)) ∧
    ((Heap.rankGT s₁ n ↔ Heap.rankGT s₂ n) →
      Heap.rankGT
        (match s₁, s₂ with
        | Heap.nil, h => h
        | h, Heap.nil => h
        | s₁@h:(cons r₁ a₁ n₁ t₁), s₂@h_1:(cons r₂ a₂ n₂ t₂) =>
          if r₁ < r₂ then cons r₁ a₁ n₁ (merge le t₁ s₂)
          else
            if r₂ < r₁ then cons r₂ a₂ n₂ (merge le s₁ t₂)
            else
              match combine le a₁ a₂ n₁ n₂ with
              | (a, n) =>
                let r := r₁ + 1;
                if Heap.rankGT t₁ r then
                  if Heap.rankGT t₂ r then cons r a n (merge le t₁ t₂) else merge le (cons r a n t₁) t₂
                else if Heap.rankGT t₂ r then merge le t₁ (cons r a n t₂) else cons r a n (merge le t₁ t₂))
        n)

tactic: exact ⟨h₂, fun h => h.1 h₁⟩
state_before: case h_1
α✝ : Type u_1
le : α✝ → α✝ → Bool
s₂ : Heap α✝
n : Nat
h₂ : WellFormed le n s₂
x✝¹ x✝ : Heap α✝
h₁ : WellFormed le n Heap.nil
⊢ WellFormed le n s₂ ∧ ((Heap.rankGT Heap.nil n ↔ Heap.rankGT s₂ n) → Heap.rankGT s₂ n)

tactic: exact ⟨h₁, fun h => h.2 h₂⟩
state_before: case h_2
α✝ : Type u_1
le : α✝ → α✝ → Bool
s₁ : Heap α✝
n : Nat
h₁ : WellFormed le n s₁
x✝² x✝¹ : Heap α✝
x✝ : s₁ = Heap.nil → False
h₂ : WellFormed le n Heap.nil
⊢ WellFormed le n s₁ ∧ ((Heap.rankGT s₁ n ↔ Heap.rankGT Heap.nil n) → Heap.rankGT s₁ n)

tactic: rename_i r₁ a₁ n₁ t₁ r₂ a₂ n₂ t₂
state_before: case h_3
α✝ : Type u_1
le : α✝ → α✝ → Bool
n : Nat
x✝¹ x✝ : Heap α✝
r₁✝ : Nat
a₁✝ : α✝
n₁✝ : HeapNode α✝
t₁✝ : Heap α✝
r₂✝ : Nat
a₂✝ : α✝
n₂✝ : HeapNode α✝
t₂✝ : Heap α✝
h₁ : WellFormed le n (cons r₁✝ a₁✝ n₁✝ t₁✝)
h₂ : WellFormed le n (cons r₂✝ a₂✝ n₂✝ t₂✝)
⊢ WellFormed le n
      (if r₁✝ < r₂✝ then cons r₁✝ a₁✝ n₁✝ (merge le t₁✝ (cons r₂✝ a₂✝ n₂✝ t₂✝))
      else
        if r₂✝ < r₁✝ then cons r₂✝ a₂✝ n₂✝ (merge le (cons r₁✝ a₁✝ n₁✝ t₁✝) t₂✝)
        else
          match combine le a₁✝ a₂✝ n₁✝ n₂✝ with
          | (a, n) =>
            let r := r₁✝ + 1;
            if Heap.rankGT t₁✝ r then
              if Heap.rankGT t₂✝ r then cons r a n (merge le t₁✝ t₂✝) else merge le (cons r a n t₁✝) t₂✝
            else if Heap.rankGT t₂✝ r then merge le t₁✝ (cons r a n t₂✝) else cons r a n (merge le t₁✝ t₂✝)) ∧
    ((Heap.rankGT (cons r₁✝ a₁✝ n₁✝ t₁✝) n ↔ Heap.rankGT (cons r₂✝ a₂✝ n₂✝ t₂✝) n) →
      Heap.rankGT
        (if r₁✝ < r₂✝ then cons r₁✝ a₁✝ n₁✝ (merge le t₁✝ (cons r₂✝ a₂✝ n₂✝ t₂✝))
        else
          if r₂✝ < r₁✝ then cons r₂✝ a₂✝ n₂✝ (merge le (cons r₁✝ a₁✝ n₁✝ t₁✝) t₂✝)
          else
            match combine le a₁✝ a₂✝ n₁✝ n₂✝ with
            | (a, n) =>
              let r := r₁✝ + 1;
              if Heap.rankGT t₁✝ r then
                if Heap.rankGT t₂✝ r then cons r a n (merge le t₁✝ t₂✝) else merge le (cons r a n t₁✝) t₂✝
              else if Heap.rankGT t₂✝ r then merge le t₁✝ (cons r a n t₂✝) else cons r a n (merge le t₁✝ t₂✝))
        n)

tactic: let ⟨hr₁, hn₁, ht₁⟩ := h₁
state_before: case h_3
α✝ : Type u_1
le : α✝ → α✝ → Bool
n : Nat
x✝¹ x✝ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
r₂ : Nat
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n (cons r₁ a₁ n₁ t₁)
h₂ : WellFormed le n (cons r₂ a₂ n₂ t₂)
⊢ WellFormed le n
      (if r₁ < r₂ then cons r₁ a₁ n₁ (merge le t₁ (cons r₂ a₂ n₂ t₂))
      else
        if r₂ < r₁ then cons r₂ a₂ n₂ (merge le (cons r₁ a₁ n₁ t₁) t₂)
        else
          match combine le a₁ a₂ n₁ n₂ with
          | (a, n) =>
            let r := r₁ + 1;
            if Heap.rankGT t₁ r then
              if Heap.rankGT t₂ r then cons r a n (merge le t₁ t₂) else merge le (cons r a n t₁) t₂
            else if Heap.rankGT t₂ r then merge le t₁ (cons r a n t₂) else cons r a n (merge le t₁ t₂)) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n ↔ Heap.rankGT (cons r₂ a₂ n₂ t₂) n) →
      Heap.rankGT
        (if r₁ < r₂ then cons r₁ a₁ n₁ (merge le t₁ (cons r₂ a₂ n₂ t₂))
        else
          if r₂ < r₁ then cons r₂ a₂ n₂ (merge le (cons r₁ a₁ n₁ t₁) t₂)
          else
            match combine le a₁ a₂ n₁ n₂ with
            | (a, n) =>
              let r := r₁ + 1;
              if Heap.rankGT t₁ r then
                if Heap.rankGT t₂ r then cons r a n (merge le t₁ t₂) else merge le (cons r a n t₁) t₂
              else if Heap.rankGT t₂ r then merge le t₁ (cons r a n t₂) else cons r a n (merge le t₁ t₂))
        n)

tactic: let ⟨hr₂, hn₂, ht₂⟩ := h₂
state_before: case h_3
α✝ : Type u_1
le : α✝ → α✝ → Bool
n : Nat
x✝¹ x✝ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
r₂ : Nat
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n (cons r₁ a₁ n₁ t₁)
h₂ : WellFormed le n (cons r₂ a₂ n₂ t₂)
hr₁ : n ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
⊢ WellFormed le n
      (if r₁ < r₂ then cons r₁ a₁ n₁ (merge le t₁ (cons r₂ a₂ n₂ t₂))
      else
        if r₂ < r₁ then cons r₂ a₂ n₂ (merge le (cons r₁ a₁ n₁ t₁) t₂)
        else
          match combine le a₁ a₂ n₁ n₂ with
          | (a, n) =>
            let r := r₁ + 1;
            if Heap.rankGT t₁ r then
              if Heap.rankGT t₂ r then cons r a n (merge le t₁ t₂) else merge le (cons r a n t₁) t₂
            else if Heap.rankGT t₂ r then merge le t₁ (cons r a n t₂) else cons r a n (merge le t₁ t₂)) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n ↔ Heap.rankGT (cons r₂ a₂ n₂ t₂) n) →
      Heap.rankGT
        (if r₁ < r₂ then cons r₁ a₁ n₁ (merge le t₁ (cons r₂ a₂ n₂ t₂))
        else
          if r₂ < r₁ then cons r₂ a₂ n₂ (merge le (cons r₁ a₁ n₁ t₁) t₂)
          else
            match combine le a₁ a₂ n₁ n₂ with
            | (a, n) =>
              let r := r₁ + 1;
              if Heap.rankGT t₁ r then
                if Heap.rankGT t₂ r then cons r a n (merge le t₁ t₂) else merge le (cons r a n t₁) t₂
              else if Heap.rankGT t₂ r then merge le t₁ (cons r a n t₂) else cons r a n (merge le t₁ t₂))
        n)

tactic: split <;> rename_i lt₁
state_before: case h_3
α✝ : Type u_1
le : α✝ → α✝ → Bool
n : Nat
x✝¹ x✝ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
r₂ : Nat
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n (cons r₁ a₁ n₁ t₁)
h₂ : WellFormed le n (cons r₂ a₂ n₂ t₂)
hr₁ : n ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
hr₂ : n ≤ r₂
hn₂ : HeapNode.WellFormed le a₂ n₂ r₂
ht₂ : WellFormed le (r₂ + 1) t₂
⊢ WellFormed le n
      (if r₁ < r₂ then cons r₁ a₁ n₁ (merge le t₁ (cons r₂ a₂ n₂ t₂))
      else
        if r₂ < r₁ then cons r₂ a₂ n₂ (merge le (cons r₁ a₁ n₁ t₁) t₂)
        else
          match combine le a₁ a₂ n₁ n₂ with
          | (a, n) =>
            let r := r₁ + 1;
            if Heap.rankGT t₁ r then
              if Heap.rankGT t₂ r then cons r a n (merge le t₁ t₂) else merge le (cons r a n t₁) t₂
            else if Heap.rankGT t₂ r then merge le t₁ (cons r a n t₂) else cons r a n (merge le t₁ t₂)) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n ↔ Heap.rankGT (cons r₂ a₂ n₂ t₂) n) →
      Heap.rankGT
        (if r₁ < r₂ then cons r₁ a₁ n₁ (merge le t₁ (cons r₂ a₂ n₂ t₂))
        else
          if r₂ < r₁ then cons r₂ a₂ n₂ (merge le (cons r₁ a₁ n₁ t₁) t₂)
          else
            match combine le a₁ a₂ n₁ n₂ with
            | (a, n) =>
              let r := r₁ + 1;
              if Heap.rankGT t₁ r then
                if Heap.rankGT t₂ r then cons r a n (merge le t₁ t₂) else merge le (cons r a n t₁) t₂
              else if Heap.rankGT t₂ r then merge le t₁ (cons r a n t₂) else cons r a n (merge le t₁ t₂))
        n)

tactic: split <;> rename_i lt₂
state_before: case h_3.inr
α✝ : Type u_1
le : α✝ → α✝ → Bool
n : Nat
x✝¹ x✝ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
r₂ : Nat
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n (cons r₁ a₁ n₁ t₁)
h₂ : WellFormed le n (cons r₂ a₂ n₂ t₂)
hr₁ : n ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
hr₂ : n ≤ r₂
hn₂ : HeapNode.WellFormed le a₂ n₂ r₂
ht₂ : WellFormed le (r₂ + 1) t₂
lt₁ : ¬r₁ < r₂
⊢ WellFormed le n
      (if r₂ < r₁ then cons r₂ a₂ n₂ (merge le (cons r₁ a₁ n₁ t₁) t₂)
      else
        match combine le a₁ a₂ n₁ n₂ with
        | (a, n) =>
          let r := r₁ + 1;
          if Heap.rankGT t₁ r then if Heap.rankGT t₂ r then cons r a n (merge le t₁ t₂) else merge le (cons r a n t₁) t₂
          else if Heap.rankGT t₂ r then merge le t₁ (cons r a n t₂) else cons r a n (merge le t₁ t₂)) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n ↔ Heap.rankGT (cons r₂ a₂ n₂ t₂) n) →
      Heap.rankGT
        (if r₂ < r₁ then cons r₂ a₂ n₂ (merge le (cons r₁ a₁ n₁ t₁) t₂)
        else
          match combine le a₁ a₂ n₁ n₂ with
          | (a, n) =>
            let r := r₁ + 1;
            if Heap.rankGT t₁ r then
              if Heap.rankGT t₂ r then cons r a n (merge le t₁ t₂) else merge le (cons r a n t₁) t₂
            else if Heap.rankGT t₂ r then merge le t₁ (cons r a n t₂) else cons r a n (merge le t₁ t₂))
        n)

tactic: cases Nat.le_antisymm (Nat.ge_of_not_lt lt₂) (Nat.ge_of_not_lt lt₁)
state_before: case h_3.inr.inr
α✝ : Type u_1
le : α✝ → α✝ → Bool
n : Nat
x✝¹ x✝ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
r₂ : Nat
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n (cons r₁ a₁ n₁ t₁)
h₂ : WellFormed le n (cons r₂ a₂ n₂ t₂)
hr₁ : n ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
hr₂ : n ≤ r₂
hn₂ : HeapNode.WellFormed le a₂ n₂ r₂
ht₂ : WellFormed le (r₂ + 1) t₂
lt₁ : ¬r₁ < r₂
lt₂ : ¬r₂ < r₁
⊢ WellFormed le n
      (match combine le a₁ a₂ n₁ n₂ with
      | (a, n) =>
        let r := r₁ + 1;
        if Heap.rankGT t₁ r then if Heap.rankGT t₂ r then cons r a n (merge le t₁ t₂) else merge le (cons r a n t₁) t₂
        else if Heap.rankGT t₂ r then merge le t₁ (cons r a n t₂) else cons r a n (merge le t₁ t₂)) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n ↔ Heap.rankGT (cons r₂ a₂ n₂ t₂) n) →
      Heap.rankGT
        (match combine le a₁ a₂ n₁ n₂ with
        | (a, n) =>
          let r := r₁ + 1;
          if Heap.rankGT t₁ r then if Heap.rankGT t₂ r then cons r a n (merge le t₁ t₂) else merge le (cons r a n t₁) t₂
          else if Heap.rankGT t₂ r then merge le t₁ (cons r a n t₂) else cons r a n (merge le t₁ t₂))
        n)

tactic: split
state_before: case h_3.inr.inr.refl
α✝ : Type u_1
le : α✝ → α✝ → Bool
n : Nat
x✝¹ x✝ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n (cons r₁ a₁ n₁ t₁)
hr₁ : n ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
h₂ : WellFormed le n (cons r₁ a₂ n₂ t₂)
hr₂ : n ≤ r₁
hn₂ : HeapNode.WellFormed le a₂ n₂ r₁
ht₂ : WellFormed le (r₁ + 1) t₂
lt₁ lt₂ : ¬r₁ < r₁
⊢ WellFormed le n
      (match combine le a₁ a₂ n₁ n₂ with
      | (a, n) =>
        let r := r₁ + 1;
        if Heap.rankGT t₁ r then if Heap.rankGT t₂ r then cons r a n (merge le t₁ t₂) else merge le (cons r a n t₁) t₂
        else if Heap.rankGT t₂ r then merge le t₁ (cons r a n t₂) else cons r a n (merge le t₁ t₂)) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n ↔ Heap.rankGT (cons r₁ a₂ n₂ t₂) n) →
      Heap.rankGT
        (match combine le a₁ a₂ n₁ n₂ with
        | (a, n) =>
          let r := r₁ + 1;
          if Heap.rankGT t₁ r then if Heap.rankGT t₂ r then cons r a n (merge le t₁ t₂) else merge le (cons r a n t₁) t₂
          else if Heap.rankGT t₂ r then merge le t₁ (cons r a n t₂) else cons r a n (merge le t₁ t₂))
        n)

tactic: rename_i a n eq
state_before: case h_3.inr.inr.refl
α✝ : Type u_1
le : α✝ → α✝ → Bool
n : Nat
x✝² x✝¹ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n (cons r₁ a₁ n₁ t₁)
hr₁ : n ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
h₂ : WellFormed le n (cons r₁ a₂ n₂ t₂)
hr₂ : n ≤ r₁
hn₂ : HeapNode.WellFormed le a₂ n₂ r₁
ht₂ : WellFormed le (r₁ + 1) t₂
lt₁ lt₂ : ¬r₁ < r₁
x✝ : α✝ × HeapNode α✝
a✝ : α✝
n✝ : HeapNode α✝
heq✝ : combine le a₁ a₂ n₁ n₂ = (a✝, n✝)
⊢ WellFormed le n
      (let r := r₁ + 1;
      if Heap.rankGT t₁ r then if Heap.rankGT t₂ r then cons r a✝ n✝ (merge le t₁ t₂) else merge le (cons r a✝ n✝ t₁) t₂
      else if Heap.rankGT t₂ r then merge le t₁ (cons r a✝ n✝ t₂) else cons r a✝ n✝ (merge le t₁ t₂)) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n ↔ Heap.rankGT (cons r₁ a₂ n₂ t₂) n) →
      Heap.rankGT
        (let r := r₁ + 1;
        if Heap.rankGT t₁ r then
          if Heap.rankGT t₂ r then cons r a✝ n✝ (merge le t₁ t₂) else merge le (cons r a✝ n✝ t₁) t₂
        else if Heap.rankGT t₂ r then merge le t₁ (cons r a✝ n✝ t₂) else cons r a✝ n✝ (merge le t₁ t₂))
        n)

tactic: simp only
state_before: case h_3.inr.inr.refl
α✝ : Type u_1
le : α✝ → α✝ → Bool
n✝ : Nat
x✝² x✝¹ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n✝ (cons r₁ a₁ n₁ t₁)
hr₁ : n✝ ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
h₂ : WellFormed le n✝ (cons r₁ a₂ n₂ t₂)
hr₂ : n✝ ≤ r₁
hn₂ : HeapNode.WellFormed le a₂ n₂ r₁
ht₂ : WellFormed le (r₁ + 1) t₂
lt₁ lt₂ : ¬r₁ < r₁
x✝ : α✝ × HeapNode α✝
a : α✝
n : HeapNode α✝
eq : combine le a₁ a₂ n₁ n₂ = (a, n)
this : HeapNode.WellFormed le a n (r₁ + 1)
⊢ WellFormed le n✝
      (let r := r₁ + 1;
      if Heap.rankGT t₁ r then if Heap.rankGT t₂ r then cons r a n (merge le t₁ t₂) else merge le (cons r a n t₁) t₂
      else if Heap.rankGT t₂ r then merge le t₁ (cons r a n t₂) else cons r a n (merge le t₁ t₂)) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n✝ ↔ Heap.rankGT (cons r₁ a₂ n₂ t₂) n✝) →
      Heap.rankGT
        (let r := r₁ + 1;
        if Heap.rankGT t₁ r then if Heap.rankGT t₂ r then cons r a n (merge le t₁ t₂) else merge le (cons r a n t₁) t₂
        else if Heap.rankGT t₂ r then merge le t₁ (cons r a n t₂) else cons r a n (merge le t₁ t₂))
        n✝)

tactic: split <;> split <;> rename_i hl₁ hl₂
state_before: case h_3.inr.inr.refl
α✝ : Type u_1
le : α✝ → α✝ → Bool
n✝ : Nat
x✝² x✝¹ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n✝ (cons r₁ a₁ n₁ t₁)
hr₁ : n✝ ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
h₂ : WellFormed le n✝ (cons r₁ a₂ n₂ t₂)
hr₂ : n✝ ≤ r₁
hn₂ : HeapNode.WellFormed le a₂ n₂ r₁
ht₂ : WellFormed le (r₁ + 1) t₂
lt₁ lt₂ : ¬r₁ < r₁
x✝ : α✝ × HeapNode α✝
a : α✝
n : HeapNode α✝
eq : combine le a₁ a₂ n₁ n₂ = (a, n)
this : HeapNode.WellFormed le a n (r₁ + 1)
⊢ WellFormed le n✝
      (if Heap.rankGT t₁ (r₁ + 1) then
        if Heap.rankGT t₂ (r₁ + 1) then cons (r₁ + 1) a n (merge le t₁ t₂) else merge le (cons (r₁ + 1) a n t₁) t₂
      else if Heap.rankGT t₂ (r₁ + 1) then merge le t₁ (cons (r₁ + 1) a n t₂) else cons (r₁ + 1) a n (merge le t₁ t₂)) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n✝ ↔ Heap.rankGT (cons r₁ a₂ n₂ t₂) n✝) →
      Heap.rankGT
        (if Heap.rankGT t₁ (r₁ + 1) then
          if Heap.rankGT t₂ (r₁ + 1) then cons (r₁ + 1) a n (merge le t₁ t₂) else merge le (cons (r₁ + 1) a n t₁) t₂
        else if Heap.rankGT t₂ (r₁ + 1) then merge le t₁ (cons (r₁ + 1) a n t₂) else cons (r₁ + 1) a n (merge le t₁ t₂))
        n✝)

tactic: refine ⟨⟨hr₁, hn₁, And.left (merge' ht₁ ⟨lt₁, hn₂, ht₂⟩)⟩, fun h => ?_⟩
state_before: case h_3.inl
α✝ : Type u_1
le : α✝ → α✝ → Bool
n : Nat
x✝¹ x✝ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
r₂ : Nat
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n (cons r₁ a₁ n₁ t₁)
h₂ : WellFormed le n (cons r₂ a₂ n₂ t₂)
hr₁ : n ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
hr₂ : n ≤ r₂
hn₂ : HeapNode.WellFormed le a₂ n₂ r₂
ht₂ : WellFormed le (r₂ + 1) t₂
lt₁ : r₁ < r₂
⊢ WellFormed le n (cons r₁ a₁ n₁ (merge le t₁ (cons r₂ a₂ n₂ t₂))) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n ↔ Heap.rankGT (cons r₂ a₂ n₂ t₂) n) →
      Heap.rankGT (cons r₁ a₁ n₁ (merge le t₁ (cons r₂ a₂ n₂ t₂))) n)

tactic: exact h.2 <| Nat.lt_of_le_of_lt hr₁ lt₁
state_before: case h_3.inl
α✝ : Type u_1
le : α✝ → α✝ → Bool
n : Nat
x✝¹ x✝ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
r₂ : Nat
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n (cons r₁ a₁ n₁ t₁)
h₂ : WellFormed le n (cons r₂ a₂ n₂ t₂)
hr₁ : n ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
hr₂ : n ≤ r₂
hn₂ : HeapNode.WellFormed le a₂ n₂ r₂
ht₂ : WellFormed le (r₂ + 1) t₂
lt₁ : r₁ < r₂
h : Heap.rankGT (cons r₁ a₁ n₁ t₁) n ↔ Heap.rankGT (cons r₂ a₂ n₂ t₂) n
⊢ Heap.rankGT (cons r₁ a₁ n₁ (merge le t₁ (cons r₂ a₂ n₂ t₂))) n

tactic: refine ⟨⟨hr₂, hn₂, And.left (merge' ⟨lt₂, hn₁, ht₁⟩ ht₂)⟩, fun h => ?_⟩
state_before: case h_3.inr.inl
α✝ : Type u_1
le : α✝ → α✝ → Bool
n : Nat
x✝¹ x✝ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
r₂ : Nat
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n (cons r₁ a₁ n₁ t₁)
h₂ : WellFormed le n (cons r₂ a₂ n₂ t₂)
hr₁ : n ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
hr₂ : n ≤ r₂
hn₂ : HeapNode.WellFormed le a₂ n₂ r₂
ht₂ : WellFormed le (r₂ + 1) t₂
lt₁ : ¬r₁ < r₂
lt₂ : r₂ < r₁
⊢ WellFormed le n (cons r₂ a₂ n₂ (merge le (cons r₁ a₁ n₁ t₁) t₂)) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n ↔ Heap.rankGT (cons r₂ a₂ n₂ t₂) n) →
      Heap.rankGT (cons r₂ a₂ n₂ (merge le (cons r₁ a₁ n₁ t₁) t₂)) n)

tactic: exact h.1 <| Nat.lt_of_le_of_lt hr₂ lt₂
state_before: case h_3.inr.inl
α✝ : Type u_1
le : α✝ → α✝ → Bool
n : Nat
x✝¹ x✝ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
r₂ : Nat
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n (cons r₁ a₁ n₁ t₁)
h₂ : WellFormed le n (cons r₂ a₂ n₂ t₂)
hr₁ : n ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
hr₂ : n ≤ r₂
hn₂ : HeapNode.WellFormed le a₂ n₂ r₂
ht₂ : WellFormed le (r₂ + 1) t₂
lt₁ : ¬r₁ < r₂
lt₂ : r₂ < r₁
h : Heap.rankGT (cons r₁ a₁ n₁ t₁) n ↔ Heap.rankGT (cons r₂ a₂ n₂ t₂) n
⊢ Heap.rankGT (cons r₂ a₂ n₂ (merge le (cons r₁ a₁ n₁ t₁) t₂)) n

tactic: unfold combine at eq
state_before: α✝ : Type u_1
le : α✝ → α✝ → Bool
n✝ : Nat
x✝² x✝¹ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n✝ (cons r₁ a₁ n₁ t₁)
hr₁ : n✝ ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
h₂ : WellFormed le n✝ (cons r₁ a₂ n₂ t₂)
hr₂ : n✝ ≤ r₁
hn₂ : HeapNode.WellFormed le a₂ n₂ r₁
ht₂ : WellFormed le (r₁ + 1) t₂
lt₁ lt₂ : ¬r₁ < r₁
x✝ : α✝ × HeapNode α✝
a : α✝
n : HeapNode α✝
eq : combine le a₁ a₂ n₁ n₂ = (a, n)
⊢ HeapNode.WellFormed le a n (r₁ + 1)

tactic: split at eq <;> cases eq <;> rename_i h
state_before: α✝ : Type u_1
le : α✝ → α✝ → Bool
n✝ : Nat
x✝² x✝¹ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n✝ (cons r₁ a₁ n₁ t₁)
hr₁ : n✝ ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
h₂ : WellFormed le n✝ (cons r₁ a₂ n₂ t₂)
hr₂ : n✝ ≤ r₁
hn₂ : HeapNode.WellFormed le a₂ n₂ r₁
ht₂ : WellFormed le (r₁ + 1) t₂
lt₁ lt₂ : ¬r₁ < r₁
x✝ : α✝ × HeapNode α✝
a : α✝
n : HeapNode α✝
eq : (if le a₁ a₂ = true then (a₁, HeapNode.node a₂ n₂ n₁) else (a₂, HeapNode.node a₁ n₁ n₂)) = (a, n)
⊢ HeapNode.WellFormed le a n (r₁ + 1)

tactic: exact ⟨r₁, rfl, h, hn₂, hn₁⟩
state_before: case inl.refl
α✝ : Type u_1
le : α✝ → α✝ → Bool
n : Nat
x✝² x✝¹ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n (cons r₁ a₁ n₁ t₁)
hr₁ : n ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
h₂ : WellFormed le n (cons r₁ a₂ n₂ t₂)
hr₂ : n ≤ r₁
hn₂ : HeapNode.WellFormed le a₂ n₂ r₁
ht₂ : WellFormed le (r₁ + 1) t₂
lt₁ lt₂ : ¬r₁ < r₁
x✝ : α✝ × HeapNode α✝
h : le a₁ a₂ = true
⊢ HeapNode.WellFormed le a₁ (HeapNode.node a₂ n₂ n₁) (r₁ + 1)

tactic: exact ⟨r₁, rfl, TotalBLE.total.resolve_left h, hn₁, hn₂⟩
state_before: case inr.refl
α✝ : Type u_1
le : α✝ → α✝ → Bool
n : Nat
x✝² x✝¹ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n (cons r₁ a₁ n₁ t₁)
hr₁ : n ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
h₂ : WellFormed le n (cons r₁ a₂ n₂ t₂)
hr₂ : n ≤ r₁
hn₂ : HeapNode.WellFormed le a₂ n₂ r₁
ht₂ : WellFormed le (r₁ + 1) t₂
lt₁ lt₂ : ¬r₁ < r₁
x✝ : α✝ × HeapNode α✝
h : ¬le a₁ a₂ = true
⊢ HeapNode.WellFormed le a₂ (HeapNode.node a₁ n₁ n₂) (r₁ + 1)

tactic: exact ⟨⟨Nat.le_succ_of_le hr₁, this,
  (merge' (ht₁.of_rankGT hl₁) (ht₂.of_rankGT hl₂)).1⟩,
  fun _ => Nat.lt_succ_of_le hr₁⟩
state_before: case h_3.inr.inr.refl.inl.inl
α✝ : Type u_1
le : α✝ → α✝ → Bool
n✝ : Nat
x✝² x✝¹ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n✝ (cons r₁ a₁ n₁ t₁)
hr₁ : n✝ ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
h₂ : WellFormed le n✝ (cons r₁ a₂ n₂ t₂)
hr₂ : n✝ ≤ r₁
hn₂ : HeapNode.WellFormed le a₂ n₂ r₁
ht₂ : WellFormed le (r₁ + 1) t₂
lt₁ lt₂ : ¬r₁ < r₁
x✝ : α✝ × HeapNode α✝
a : α✝
n : HeapNode α✝
eq : combine le a₁ a₂ n₁ n₂ = (a, n)
this : HeapNode.WellFormed le a n (r₁ + 1)
hl₁ : Heap.rankGT t₁ (r₁ + 1)
hl₂ : Heap.rankGT t₂ (r₁ + 1)
⊢ WellFormed le n✝ (cons (r₁ + 1) a n (merge le t₁ t₂)) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n✝ ↔ Heap.rankGT (cons r₁ a₂ n₂ t₂) n✝) →
      Heap.rankGT (cons (r₁ + 1) a n (merge le t₁ t₂)) n✝)

tactic: let ⟨ih₁, ih₂⟩ := merge' (s₁ := .cons ..)
  ⟨Nat.le_succ_of_le hr₁, this, ht₁.of_rankGT hl₁⟩
  (ht₂.of_le (Nat.le_succ_of_le hr₁))
state_before: case h_3.inr.inr.refl.inl.inr
α✝ : Type u_1
le : α✝ → α✝ → Bool
n✝ : Nat
x✝² x✝¹ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n✝ (cons r₁ a₁ n₁ t₁)
hr₁ : n✝ ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
h₂ : WellFormed le n✝ (cons r₁ a₂ n₂ t₂)
hr₂ : n✝ ≤ r₁
hn₂ : HeapNode.WellFormed le a₂ n₂ r₁
ht₂ : WellFormed le (r₁ + 1) t₂
lt₁ lt₂ : ¬r₁ < r₁
x✝ : α✝ × HeapNode α✝
a : α✝
n : HeapNode α✝
eq : combine le a₁ a₂ n₁ n₂ = (a, n)
this : HeapNode.WellFormed le a n (r₁ + 1)
hl₁ : Heap.rankGT t₁ (r₁ + 1)
hl₂ : ¬Heap.rankGT t₂ (r₁ + 1)
⊢ WellFormed le n✝ (merge le (cons (r₁ + 1) a n t₁) t₂) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n✝ ↔ Heap.rankGT (cons r₁ a₂ n₂ t₂) n✝) →
      Heap.rankGT (merge le (cons (r₁ + 1) a n t₁) t₂) n✝)

tactic: exact ⟨ih₁, fun _ => ih₂ ⟨fun _ => ht₂.rankGT.le_trans hr₁, fun h => Nat.lt_succ_of_le hr₁⟩⟩
state_before: case h_3.inr.inr.refl.inl.inr
α✝ : Type u_1
le : α✝ → α✝ → Bool
n✝ : Nat
x✝² x✝¹ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n✝ (cons r₁ a₁ n₁ t₁)
hr₁ : n✝ ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
h₂ : WellFormed le n✝ (cons r₁ a₂ n₂ t₂)
hr₂ : n✝ ≤ r₁
hn₂ : HeapNode.WellFormed le a₂ n₂ r₁
ht₂ : WellFormed le (r₁ + 1) t₂
lt₁ lt₂ : ¬r₁ < r₁
x✝ : α✝ × HeapNode α✝
a : α✝
n : HeapNode α✝
eq : combine le a₁ a₂ n₁ n₂ = (a, n)
this : HeapNode.WellFormed le a n (r₁ + 1)
hl₁ : Heap.rankGT t₁ (r₁ + 1)
hl₂ : ¬Heap.rankGT t₂ (r₁ + 1)
ih₁ : WellFormed le n✝ (merge le (cons (Nat.succ r₁) a n t₁) t₂)
ih₂ :
  (Heap.rankGT (cons (Nat.succ r₁) a n t₁) n✝ ↔ Heap.rankGT t₂ n✝) →
    Heap.rankGT (merge le (cons (Nat.succ r₁) a n t₁) t₂) n✝
⊢ WellFormed le n✝ (merge le (cons (r₁ + 1) a n t₁) t₂) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n✝ ↔ Heap.rankGT (cons r₁ a₂ n₂ t₂) n✝) →
      Heap.rankGT (merge le (cons (r₁ + 1) a n t₁) t₂) n✝)

tactic: let ⟨ih₁, ih₂⟩ := merge' (s₂ := .cons ..) (ht₁.of_le (Nat.le_succ_of_le hr₁))
  ⟨Nat.le_succ_of_le hr₁, this, ht₂.of_rankGT hl₂⟩
state_before: case h_3.inr.inr.refl.inr.inl
α✝ : Type u_1
le : α✝ → α✝ → Bool
n✝ : Nat
x✝² x✝¹ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n✝ (cons r₁ a₁ n₁ t₁)
hr₁ : n✝ ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
h₂ : WellFormed le n✝ (cons r₁ a₂ n₂ t₂)
hr₂ : n✝ ≤ r₁
hn₂ : HeapNode.WellFormed le a₂ n₂ r₁
ht₂ : WellFormed le (r₁ + 1) t₂
lt₁ lt₂ : ¬r₁ < r₁
x✝ : α✝ × HeapNode α✝
a : α✝
n : HeapNode α✝
eq : combine le a₁ a₂ n₁ n₂ = (a, n)
this : HeapNode.WellFormed le a n (r₁ + 1)
hl₁ : ¬Heap.rankGT t₁ (r₁ + 1)
hl₂ : Heap.rankGT t₂ (r₁ + 1)
⊢ WellFormed le n✝ (merge le t₁ (cons (r₁ + 1) a n t₂)) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n✝ ↔ Heap.rankGT (cons r₁ a₂ n₂ t₂) n✝) →
      Heap.rankGT (merge le t₁ (cons (r₁ + 1) a n t₂)) n✝)

tactic: exact ⟨ih₁, fun _ => ih₂ ⟨fun h => Nat.lt_succ_of_le hr₁, fun _ => ht₁.rankGT.le_trans hr₁⟩⟩
state_before: case h_3.inr.inr.refl.inr.inl
α✝ : Type u_1
le : α✝ → α✝ → Bool
n✝ : Nat
x✝² x✝¹ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n✝ (cons r₁ a₁ n₁ t₁)
hr₁ : n✝ ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
h₂ : WellFormed le n✝ (cons r₁ a₂ n₂ t₂)
hr₂ : n✝ ≤ r₁
hn₂ : HeapNode.WellFormed le a₂ n₂ r₁
ht₂ : WellFormed le (r₁ + 1) t₂
lt₁ lt₂ : ¬r₁ < r₁
x✝ : α✝ × HeapNode α✝
a : α✝
n : HeapNode α✝
eq : combine le a₁ a₂ n₁ n₂ = (a, n)
this : HeapNode.WellFormed le a n (r₁ + 1)
hl₁ : ¬Heap.rankGT t₁ (r₁ + 1)
hl₂ : Heap.rankGT t₂ (r₁ + 1)
ih₁ : WellFormed le n✝ (merge le t₁ (cons (Nat.succ r₁) a n t₂))
ih₂ :
  (Heap.rankGT t₁ n✝ ↔ Heap.rankGT (cons (Nat.succ r₁) a n t₂) n✝) →
    Heap.rankGT (merge le t₁ (cons (Nat.succ r₁) a n t₂)) n✝
⊢ WellFormed le n✝ (merge le t₁ (cons (r₁ + 1) a n t₂)) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n✝ ↔ Heap.rankGT (cons r₁ a₂ n₂ t₂) n✝) →
      Heap.rankGT (merge le t₁ (cons (r₁ + 1) a n t₂)) n✝)

tactic: let ⟨ih₁, ih₂⟩ := merge' ht₁ ht₂
state_before: case h_3.inr.inr.refl.inr.inr
α✝ : Type u_1
le : α✝ → α✝ → Bool
n✝ : Nat
x✝² x✝¹ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n✝ (cons r₁ a₁ n₁ t₁)
hr₁ : n✝ ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
h₂ : WellFormed le n✝ (cons r₁ a₂ n₂ t₂)
hr₂ : n✝ ≤ r₁
hn₂ : HeapNode.WellFormed le a₂ n₂ r₁
ht₂ : WellFormed le (r₁ + 1) t₂
lt₁ lt₂ : ¬r₁ < r₁
x✝ : α✝ × HeapNode α✝
a : α✝
n : HeapNode α✝
eq : combine le a₁ a₂ n₁ n₂ = (a, n)
this : HeapNode.WellFormed le a n (r₁ + 1)
hl₁ : ¬Heap.rankGT t₁ (r₁ + 1)
hl₂ : ¬Heap.rankGT t₂ (r₁ + 1)
⊢ WellFormed le n✝ (cons (r₁ + 1) a n (merge le t₁ t₂)) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n✝ ↔ Heap.rankGT (cons r₁ a₂ n₂ t₂) n✝) →
      Heap.rankGT (cons (r₁ + 1) a n (merge le t₁ t₂)) n✝)

tactic: exact ⟨⟨Nat.le_succ_of_le hr₁, this, ih₁.of_rankGT (ih₂ (iff_of_false hl₁ hl₂))⟩,
  fun _ => Nat.lt_succ_of_le hr₁⟩
state_before: case h_3.inr.inr.refl.inr.inr
α✝ : Type u_1
le : α✝ → α✝ → Bool
n✝ : Nat
x✝² x✝¹ : Heap α✝
r₁ : Nat
a₁ : α✝
n₁ : HeapNode α✝
t₁ : Heap α✝
a₂ : α✝
n₂ : HeapNode α✝
t₂ : Heap α✝
h₁ : WellFormed le n✝ (cons r₁ a₁ n₁ t₁)
hr₁ : n✝ ≤ r₁
hn₁ : HeapNode.WellFormed le a₁ n₁ r₁
ht₁ : WellFormed le (r₁ + 1) t₁
h₂ : WellFormed le n✝ (cons r₁ a₂ n₂ t₂)
hr₂ : n✝ ≤ r₁
hn₂ : HeapNode.WellFormed le a₂ n₂ r₁
ht₂ : WellFormed le (r₁ + 1) t₂
lt₁ lt₂ : ¬r₁ < r₁
x✝ : α✝ × HeapNode α✝
a : α✝
n : HeapNode α✝
eq : combine le a₁ a₂ n₁ n₂ = (a, n)
this : HeapNode.WellFormed le a n (r₁ + 1)
hl₁ : ¬Heap.rankGT t₁ (r₁ + 1)
hl₂ : ¬Heap.rankGT t₂ (r₁ + 1)
ih₁ : WellFormed le (r₁ + 1) (merge le t₁ t₂)
ih₂ : (Heap.rankGT t₁ (r₁ + 1) ↔ Heap.rankGT t₂ (r₁ + 1)) → Heap.rankGT (merge le t₁ t₂) (r₁ + 1)
⊢ WellFormed le n✝ (cons (r₁ + 1) a n (merge le t₁ t₂)) ∧
    ((Heap.rankGT (cons r₁ a₁ n₁ t₁) n✝ ↔ Heap.rankGT (cons r₁ a₂ n₂ t₂) n✝) →
      Heap.rankGT (cons (r₁ + 1) a n (merge le t₁ t₂)) n✝)

tactic: simp_wf
state_before: α✝ : Type u_1
le : α✝ → α✝ → Bool
_x✝ : (s₁ : Heap α✝) ×' (s₂ : Heap α✝) ×' (n : Nat) ×' (_ : WellFormed le n s₁) ×' WellFormed le n s₂
a✝⁵ :
  ∀ (y : (s₁ : Heap α✝) ×' (s₂ : Heap α✝) ×' (n : Nat) ×' (_ : WellFormed le n s₁) ×' WellFormed le n s₂),
    (invImage
            (fun a =>
              PSigma.casesOn a fun s₁ snd =>
                PSigma.casesOn snd fun s₂ snd =>
                  PSigma.casesOn snd fun n snd => PSigma.casesOn snd fun h₁ snd => length s₁ + length s₂)
            instWellFoundedRelation).1
        y _x✝ →
      WellFormed le y.2.2.1 (merge le y.1 y.2.1) ∧
        ((Heap.rankGT y.1 y.2.2.1 ↔ Heap.rankGT y.2.1 y.2.2.1) → Heap.rankGT (merge le y.1 y.2.1) y.2.2.1)
s₁ : Heap α✝
s₂✝ : (s₂ : Heap α✝) ×' (n : Nat) ×' (_ : WellFormed le n s₁) ×' WellFormed le n s₂
a✝⁴ :
  ∀ (y : (s₁ : Heap α✝) ×' (s₂ : Heap α✝) ×' (n : Nat) ×' (_ : WellFormed le n s₁) ×' WellFormed le n s₂),
    (invImage
            (fun a =>
              PSigma.casesOn a fun s₁ snd =>
                PSigma.casesOn snd fun s₂ snd =>
                  PSigma.casesOn snd fun n snd => PSigma.casesOn snd fun h₁ snd => length s₁ + length s₂)
            instWellFoundedRelation).1
        y { fst := s₁, snd := s₂✝ } →
      WellFormed le y.2.2.1 (merge le y.1 y.2.1) ∧
        ((Heap.rankGT y.1 y.2.2.1 ↔ Heap.rankGT y.2.1 y.2.2.1) → Heap.rankGT (merge le y.1 y.2.1) y.2.2.1)
s₂ : Heap α✝
n✝¹ : (n : Nat) ×' (_ : WellFormed le n s₁) ×' WellFormed le n s₂
a✝³ :
  ∀ (y : (s₁ : Heap α✝) ×' (s₂ : Heap α✝) ×' (n : Nat) ×' (_ : WellFormed le n s₁) ×' WellFormed le n s₂),
    (invImage
            (fun a =>
              PSigma.casesOn a fun s₁ snd =>
                PSigma.casesOn snd fun s₂ snd =>
                  PSigma.casesOn snd fun n snd => PSigma.casesOn snd fun h₁ snd => length s₁ + length s₂)
            instWellFoundedRelation).1
        y { fst := s₁, snd := { fst := s₂, snd := n✝¹ } } →
      WellFormed le y.2.2.1 (merge le y.1 y.2.1) ∧
        ((Heap.rankGT y.1 y.2.2.1 ↔ Heap.rankGT y.2.1 y.2.2.1) → Heap.rankGT (merge le y.1 y.2.1) y.2.2.1)
n : Nat
h₁✝¹ : (_ : WellFormed le n s₁) ×' WellFormed le n s₂
a✝² :
  ∀ (y : (s₁ : Heap α✝) ×' (s₂ : Heap α✝) ×' (n : Nat) ×' (_ : WellFormed le n s₁) ×' WellFormed le n s₂),
    (invImage
            (fun a =>
              PSigma.casesOn a fun s₁ snd =>
                PSigma.casesOn snd fun s₂ snd =>
                  PSigma.casesOn snd fun n snd => PSigma.casesOn snd fun h₁ snd => length s₁ + length s₂)
            instWellFoundedRelation).1
        y { fst := s₁, snd := { fst := s₂, snd := { fst := n, snd := h₁✝¹ } } } →
      WellFormed le y.2.2.1 (merge le y.1 y.2.1) ∧
        ((Heap.rankGT y.1 y.2.2.1 ↔ Heap.rankGT y.2.1 y.2.2.1) → Heap.rankGT (merge le y.1 y.2.1) y.2.2.1)
h₁✝ : WellFormed le n s₁
h₂✝¹ : WellFormed le n s₂
a✝¹ :
  ∀ (y : (s₁ : Heap α✝) ×' (s₂ : Heap α✝) ×' (n : Nat) ×' (_ : WellFormed le n s₁) ×' WellFormed le n s₂),
    (invImage
            (fun a =>
              PSigma.casesOn a fun s₁ snd =>
                PSigma.casesOn snd fun s₂ snd =>
                  PSigma.casesOn snd fun n snd => PSigma.casesOn snd fun h₁ snd => length s₁ + length s₂)
            instWellFoundedRelation).1
        y { fst := s₁, snd := { fst := s₂, snd := { fst := n, snd := { fst := h₁✝, snd := h₂✝¹ } } } } →
      WellFormed le y.2.2.1 (merge le y.1 y.2.1) ∧
        ((Heap.rankGT y.1 y.2.2.1 ↔ Heap.rankGT y.2.1 y.2.2.1) → Heap.rankGT (merge le y.1 y.2.1) y.2.2.1)
r₁✝ : Nat
a₁✝ : α✝
n₁✝ : HeapNode α✝
t₁✝ : Heap α✝
r₂✝ : Nat
a₂✝ : α✝
n₂✝ : HeapNode α✝
t₂✝ : Heap α✝
h✝⁸ : s₁ = cons r₁✝ a₁✝ n₁✝ t₁✝
h₁ : WellFormed le n (cons r₁✝ a₁✝ n₁✝ t₁✝)
h✝⁷ : s₂ = cons r₂✝ a₂✝ n₂✝ t₂✝
h₂✝ : WellFormed le n (cons r₂✝ a₂✝ n₂✝ t₂✝)
hr₁ : n ≤ r₁✝
hn₁ : HeapNode.WellFormed le a₁✝ n₁✝ r₁✝
ht₁ : WellFormed le (r₁✝ + 1) t₁✝
hr₂✝ : n ≤ r₂✝
hn₂✝ : HeapNode.WellFormed le a₂✝ n₂✝ r₂✝
ht₂✝ : WellFormed le (r₂✝ + 1) t₂✝
h✝⁶ : ¬r₁✝ < r₂✝
h✝⁵ : ¬r₂✝ < r₁✝
h✝⁴ : r₂✝ = r₁✝
h₂ : WellFormed le n (cons r₁✝ a₂✝ n₂✝ t₂✝)
hr₂ : n ≤ r₁✝
hn₂ : HeapNode.WellFormed le a₂✝ n₂✝ r₁✝
ht₂ : WellFormed le (r₁✝ + 1) t₂✝
lt₁ lt₂ : ¬r₁✝ < r₁✝
x✝ : r₁✝ = r₁✝
h✝³ : HEq x✝ (_ : r₁✝ = r₁✝)
a✝ : α✝
n✝ : HeapNode α✝
h✝² heq✝ : combine le a₁✝ a₂✝ n₁✝ n₂✝ = (a✝, n✝)
this : HeapNode.WellFormed le a✝ n✝ (r₁✝ + 1)
h✝¹ : ¬Heap.rankGT t₁✝ (r₁✝ + 1)
h✝ : ¬Heap.rankGT t₂✝ (r₁✝ + 1)
⊢ (invImage
        (fun a =>
          PSigma.casesOn a fun s₁ snd =>
            PSigma.casesOn snd fun s₂ snd =>
              PSigma.casesOn snd fun n snd => PSigma.casesOn snd fun h₁ snd => length s₁ + length s₂)
        instWellFoundedRelation).1
    { fst := t₁✝, snd := { fst := t₂✝, snd := { fst := r₁✝ + 1, snd := { fst := ht₁, snd := ht₂ } } } }
    { fst := s₁, snd := { fst := s₂, snd := { fst := n, snd := { fst := h₁✝, snd := h₂✝¹ } } } }

tactic: simp_arith [*]
state_before: α✝ : Type u_1
le : α✝ → α✝ → Bool
_x✝ : (s₁ : Heap α✝) ×' (s₂ : Heap α✝) ×' (n : Nat) ×' (_ : WellFormed le n s₁) ×' WellFormed le n s₂
a✝⁵ :
  ∀ (y : (s₁ : Heap α✝) ×' (s₂ : Heap α✝) ×' (n : Nat) ×' (_ : WellFormed le n s₁) ×' WellFormed le n s₂),
    (invImage
            (fun a =>
              PSigma.casesOn a fun s₁ snd =>
                PSigma.casesOn snd fun s₂ snd =>
                  PSigma.casesOn snd fun n snd => PSigma.casesOn snd fun h₁ snd => length s₁ + length s₂)
            instWellFoundedRelation).1
        y _x✝ →
      WellFormed le y.2.2.1 (merge le y.1 y.2.1) ∧
        ((Heap.rankGT y.1 y.2.2.1 ↔ Heap.rankGT y.2.1 y.2.2.1) → Heap.rankGT (merge le y.1 y.2.1) y.2.2.1)
s₁ : Heap α✝
s₂✝ : (s₂ : Heap α✝) ×' (n : Nat) ×' (_ : WellFormed le n s₁) ×' WellFormed le n s₂
a✝⁴ :
  ∀ (y : (s₁ : Heap α✝) ×' (s₂ : Heap α✝) ×' (n : Nat) ×' (_ : WellFormed le n s₁) ×' WellFormed le n s₂),
    (invImage
            (fun a =>
              PSigma.casesOn a fun s₁ snd =>
                PSigma.casesOn snd fun s₂ snd =>
                  PSigma.casesOn snd fun n snd => PSigma.casesOn snd fun h₁ snd => length s₁ + length s₂)
            instWellFoundedRelation).1
        y { fst := s₁, snd := s₂✝ } →
      WellFormed le y.2.2.1 (merge le y.1 y.2.1) ∧
        ((Heap.rankGT y.1 y.2.2.1 ↔ Heap.rankGT y.2.1 y.2.2.1) → Heap.rankGT (merge le y.1 y.2.1) y.2.2.1)
s₂ : Heap α✝
n✝¹ : (n : Nat) ×' (_ : WellFormed le n s₁) ×' WellFormed le n s₂
a✝³ :
  ∀ (y : (s₁ : Heap α✝) ×' (s₂ : Heap α✝) ×' (n : Nat) ×' (_ : WellFormed le n s₁) ×' WellFormed le n s₂),
    (invImage
            (fun a =>
              PSigma.casesOn a fun s₁ snd =>
                PSigma.casesOn snd fun s₂ snd =>
                  PSigma.casesOn snd fun n snd => PSigma.casesOn snd fun h₁ snd => length s₁ + length s₂)
            instWellFoundedRelation).1
        y { fst := s₁, snd := { fst := s₂, snd := n✝¹ } } →
      WellFormed le y.2.2.1 (merge le y.1 y.2.1) ∧
        ((Heap.rankGT y.1 y.2.2.1 ↔ Heap.rankGT y.2.1 y.2.2.1) → Heap.rankGT (merge le y.1 y.2.1) y.2.2.1)
n : Nat
h₁✝¹ : (_ : WellFormed le n s₁) ×' WellFormed le n s₂
a✝² :
  ∀ (y : (s₁ : Heap α✝) ×' (s₂ : Heap α✝) ×' (n : Nat) ×' (_ : WellFormed le n s₁) ×' WellFormed le n s₂),
    (invImage
            (fun a =>
              PSigma.casesOn a fun s₁ snd =>
                PSigma.casesOn snd fun s₂ snd =>
                  PSigma.casesOn snd fun n snd => PSigma.casesOn snd fun h₁ snd => length s₁ + length s₂)
            instWellFoundedRelation).1
        y { fst := s₁, snd := { fst := s₂, snd := { fst := n, snd := h₁✝¹ } } } →
      WellFormed le y.2.2.1 (merge le y.1 y.2.1) ∧
        ((Heap.rankGT y.1 y.2.2.1 ↔ Heap.rankGT y.2.1 y.2.2.1) → Heap.rankGT (merge le y.1 y.2.1) y.2.2.1)
h₁✝ : WellFormed le n s₁
h₂✝¹ : WellFormed le n s₂
a✝¹ :
  ∀ (y : (s₁ : Heap α✝) ×' (s₂ : Heap α✝) ×' (n : Nat) ×' (_ : WellFormed le n s₁) ×' WellFormed le n s₂),
    (invImage
            (fun a =>
              PSigma.casesOn a fun s₁ snd =>
                PSigma.casesOn snd fun s₂ snd =>
                  PSigma.casesOn snd fun n snd => PSigma.casesOn snd fun h₁ snd => length s₁ + length s₂)
            instWellFoundedRelation).1
        y { fst := s₁, snd := { fst := s₂, snd := { fst := n, snd := { fst := h₁✝, snd := h₂✝¹ } } } } →
      WellFormed le y.2.2.1 (merge le y.1 y.2.1) ∧
        ((Heap.rankGT y.1 y.2.2.1 ↔ Heap.rankGT y.2.1 y.2.2.1) → Heap.rankGT (merge le y.1 y.2.1) y.2.2.1)
r₁✝ : Nat
a₁✝ : α✝
n₁✝ : HeapNode α✝
t₁✝ : Heap α✝
r₂✝ : Nat
a₂✝ : α✝
n₂✝ : HeapNode α✝
t₂✝ : Heap α✝
h✝⁸ : s₁ = cons r₁✝ a₁✝ n₁✝ t₁✝
h₁ : WellFormed le n (cons r₁✝ a₁✝ n₁✝ t₁✝)
h✝⁷ : s₂ = cons r₂✝ a₂✝ n₂✝ t₂✝
h₂✝ : WellFormed le n (cons r₂✝ a₂✝ n₂✝ t₂✝)
hr₁ : n ≤ r₁✝
hn₁ : HeapNode.WellFormed le a₁✝ n₁✝ r₁✝
ht₁ : WellFormed le (r₁✝ + 1) t₁✝
hr₂✝ : n ≤ r₂✝
hn₂✝ : HeapNode.WellFormed le a₂✝ n₂✝ r₂✝
ht₂✝ : WellFormed le (r₂✝ + 1) t₂✝
h✝⁶ : ¬r₁✝ < r₂✝
h✝⁵ : ¬r₂✝ < r₁✝
h✝⁴ : r₂✝ = r₁✝
h₂ : WellFormed le n (cons r₁✝ a₂✝ n₂✝ t₂✝)
hr₂ : n ≤ r₁✝
hn₂ : HeapNode.WellFormed le a₂✝ n₂✝ r₁✝
ht₂ : WellFormed le (r₁✝ + 1) t₂✝
lt₁ lt₂ : ¬r₁✝ < r₁✝
x✝ : r₁✝ = r₁✝
h✝³ : HEq x✝ (_ : r₁✝ = r₁✝)
a✝ : α✝
n✝ : HeapNode α✝
h✝² heq✝ : combine le a₁✝ a₂✝ n₁✝ n₂✝ = (a✝, n✝)
this : HeapNode.WellFormed le a✝ n✝ (r₁✝ + 1)
h✝¹ : ¬Heap.rankGT t₁✝ (r₁✝ + 1)
h✝ : ¬Heap.rankGT t₂✝ (r₁✝ + 1)
⊢ length t₁✝ + length t₂✝ < length s₁ + length s₂