Theorem: project.IsHeap_merge (Project/Merge.lean)

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys h : List (BinTree α)
hxs : IsHeapForest' rx []
hys : IsHeapForest' ry h
⊢ IsHeapForest' (min rx ry) (mergeNodes le [] h)
Tactic:
rw [empty_heap_merge_left]
State after:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys h : List (BinTree α)
hxs : IsHeapForest' rx []
hys : IsHeapForest' ry h
⊢ IsHeapForest' (min rx ry) h

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys h : List (BinTree α)
hxs : IsHeapForest' rx []
hys : IsHeapForest' ry h
⊢ IsHeapForest' (min rx ry) h
Tactic:
apply IsHeapForest'_weaken hys
State after:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys h : List (BinTree α)
hxs : IsHeapForest' rx []
hys : IsHeapForest' ry h
⊢ min rx ry ≤ ry

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys h : List (BinTree α)
hxs : IsHeapForest' rx []
hys : IsHeapForest' ry h
⊢ min rx ry ≤ ry
Tactic:
apply min_le_right
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys h : List (BinTree α)
hxs : IsHeapForest' rx h
hys : IsHeapForest' ry []
⊢ IsHeapForest' (min rx ry) (mergeNodes le h [])
Tactic:
rw[empty_heap_merge_right]
State after:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys h : List (BinTree α)
hxs : IsHeapForest' rx h
hys : IsHeapForest' ry []
⊢ IsHeapForest' (min rx ry) h

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys h : List (BinTree α)
hxs : IsHeapForest' rx h
hys : IsHeapForest' ry []
⊢ IsHeapForest' (min rx ry) h
Tactic:
apply IsHeapForest'_weaken hxs
State after:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys h : List (BinTree α)
hxs : IsHeapForest' rx h
hys : IsHeapForest' ry []
⊢ min rx ry ≤ rx

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys h : List (BinTree α)
hxs : IsHeapForest' rx h
hys : IsHeapForest' ry []
⊢ min rx ry ≤ rx
Tactic:
apply min_le_left
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
⊢ IsHeapForest' (min rx ry) (mergeNodes le (h₁ :: t₁) (h₂ :: t₂))
Tactic:
unfold mergeNodes
State after:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
⊢ IsHeapForest' (min rx ry)
    (if h₁.rank < h₂.rank then h₁ :: mergeNodes le t₁ (h₂ :: t₂)
    else
      if h₂.rank < h₁.rank then h₂ :: mergeNodes le t₂ (h₁ :: t₁)
      else
        let merged := combine le h₁ h₂;
        let r := merged.rank;
        if (r != hRank t₁) = true then
          if (r != hRank t₂) = true then merged :: mergeNodes le t₁ t₂ else mergeNodes le (merged :: t₁) t₂
        else if (r != hRank t₂) = true then mergeNodes le t₁ (merged :: t₂) else merged :: mergeNodes le t₁ t₂)

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
⊢ IsHeapForest' (min rx ry)
    (if h₁.rank < h₂.rank then h₁ :: mergeNodes le t₁ (h₂ :: t₂)
    else
      if h₂.rank < h₁.rank then h₂ :: mergeNodes le t₂ (h₁ :: t₁)
      else
        let merged := combine le h₁ h₂;
        let r := merged.rank;
        if (r != hRank t₁) = true then
          if (r != hRank t₂) = true then merged :: mergeNodes le t₁ t₂ else mergeNodes le (merged :: t₁) t₂
        else if (r != hRank t₂) = true then mergeNodes le t₁ (merged :: t₂) else merged :: mergeNodes le t₁ t₂)
Tactic:
split
State after:
case inl
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝ : h₁.rank < h₂.rank
⊢ IsHeapForest' (min rx ry) (h₁ :: mergeNodes le t₁ (h₂ :: t₂))

case inr
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝ : ¬h₁.rank < h₂.rank
⊢ IsHeapForest' (min rx ry)
    (if h₂.rank < h₁.rank then h₂ :: mergeNodes le t₂ (h₁ :: t₁)
    else
      let merged := combine le h₁ h₂;
      let r := merged.rank;
      if (r != hRank t₁) = true then
        if (r != hRank t₂) = true then merged :: mergeNodes le t₁ t₂ else mergeNodes le (merged :: t₁) t₂
      else if (r != hRank t₂) = true then mergeNodes le t₁ (merged :: t₂) else merged :: mergeNodes le t₁ t₂)

State before:
case inl
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝ : h₁.rank < h₂.rank
⊢ IsHeapForest' (min rx ry) (h₁ :: mergeNodes le t₁ (h₂ :: t₂))

case inr
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝ : ¬h₁.rank < h₂.rank
⊢ IsHeapForest' (min rx ry)
    (if h₂.rank < h₁.rank then h₂ :: mergeNodes le t₂ (h₁ :: t₁)
    else
      let merged := combine le h₁ h₂;
      let r := merged.rank;
      if (r != hRank t₁) = true then
        if (r != hRank t₂) = true then merged :: mergeNodes le t₁ t₂ else mergeNodes le (merged :: t₁) t₂
      else if (r != hRank t₂) = true then mergeNodes le t₁ (merged :: t₂) else merged :: mergeNodes le t₁ t₂)
Tactic:
. constructor
  . cases hxs
    rw[Nat.min_eq]
    split
    . assumption
    . rename_i nle
      simp at nle
      apply Nat.lt_trans nle
      assumption
  . cases hxs
    assumption
  . cases hxs with | cons hlt bt hf =>
      rename_i hlt₂
      have : h₁.rank = min h₁.rank (h₂.rank - 1) := by
        have hle : h₁.rank ≤ (h₂.rank - 1) := by
          apply Nat.le_pred_of_lt hlt₂
        have : min h₁.rank (h₂.rank - 1) = h₁.rank := by
          apply min_eq_left hle
        rw[this]
      rw [this]; clear this
      apply IsHeap_merge
      . assumption
      . apply IsHeapForest'_strengthen_pred
        . assumption
        . cases bt with | mk =>
            have hge : h₁.rank ≥ 0 := by
              cases h₁.rank
              . simp 
              . simp
            have hle : 0 ≤ h₁.rank := by
              apply hge
            have : 0 < h₂.rank := by
              apply lt_of_le_of_lt hle hlt₂
            assumption
State after:
case inr
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝ : ¬h₁.rank < h₂.rank
⊢ IsHeapForest' (min rx ry)
    (if h₂.rank < h₁.rank then h₂ :: mergeNodes le t₂ (h₁ :: t₁)
    else
      let merged := combine le h₁ h₂;
      let r := merged.rank;
      if (r != hRank t₁) = true then
        if (r != hRank t₂) = true then merged :: mergeNodes le t₁ t₂ else mergeNodes le (merged :: t₁) t₂
      else if (r != hRank t₂) = true then mergeNodes le t₁ (merged :: t₂) else merged :: mergeNodes le t₁ t₂)

State before:
case inr
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝ : ¬h₁.rank < h₂.rank
⊢ IsHeapForest' (min rx ry)
    (if h₂.rank < h₁.rank then h₂ :: mergeNodes le t₂ (h₁ :: t₁)
    else
      let merged := combine le h₁ h₂;
      let r := merged.rank;
      if (r != hRank t₁) = true then
        if (r != hRank t₂) = true then merged :: mergeNodes le t₁ t₂ else mergeNodes le (merged :: t₁) t₂
      else if (r != hRank t₂) = true then mergeNodes le t₁ (merged :: t₂) else merged :: mergeNodes le t₁ t₂)
Tactic:
. split
  . constructor
    . rw[Nat.min_eq]
      split
      . cases hys
        apply Nat.lt_of_le_of_lt <;> assumption
      . cases hys
        assumption
    . cases hys
      assumption
    . have heq : min h₂.rank (h₁.rank -1) = h₂.rank := by
        have : h₂.rank ≤ (h₁.rank - 1) := by
          apply Nat.le_pred_of_lt
          assumption
        apply min_eq_left
        assumption
      rw[← heq]
      apply IsHeap_merge 
      . cases hys
        assumption
      . constructor
        . cases hxs
          apply Nat.pred_lt
          simp
          cases rx <;> apply Nat.not_eq_zero_of_lt; repeat assumption
        . cases hxs
          assumption
        . cases hxs
          assumption
  . dsimp
    split
    . split
      . rename_i hneq hneq₂ 
        simp at * 
        have heq : h₁.rank = h₂.rank := by
          apply Nat.le_antisymm <;> assumption
        constructor
        . have : (combine le h₁ h₂).rank = h₁.rank + 1 := by
            apply rank_combine heq
          rw[this]; clear this
          rw[Nat.min_eq]
          split
          . cases hxs
            apply Nat.lt_succ_of_lt 
            assumption
          . cases hys
            rw[heq]
            apply Nat.lt_succ_of_lt
            assumption
        . cases hxs
          cases hys
          apply combine_IsBinTree <;> assumption
        . rw[rank_combine heq] at *
          cases hxs with | cons _ _ ht₁ => 
          cases hys with | cons _ _ ht₂ =>
          have ih := IsHeap_merge ht₁ ht₂
          have min_le : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂) := by 
            rw[← heq] at ht₂
            apply min_hRank_mergeNodes ht₁ ht₂
          by_cases (t₁ = [] ∧ t₂ = [])
          . have (And.intro he₁ he₂) := h
            simp[he₁, he₂]
            constructor
          . apply IsHeapForest'_strengthen
            . apply ih
            . rw[Nat.min_eq] at min_le
              split at min_le
              . match ht₁ with
                | .nil =>
                  rw[empty_heap_merge_left] at *
                  match ht₂ with
                  | .nil => simp at h
                  | .cons (t := bt) hlt _ _ =>
                    rw[hrank_of_cons] at *
                    rw[← heq] at hlt
                    unfold bne at hneq₂
                    rw[Nat.not_beq_eq_true_eq] at hneq₂
                    have n : h₁.rank + 1 ≤ bt.rank := by
                      apply Nat.succ_le_of_lt hlt 
                    apply lt_of_le_of_ne <;> assumption
                | .cons (t := t) (ts := ts) hlt _ _ =>
                  rw[hrank_of_cons] at *
                  have : h₁.rank < hRank (mergeNodes le (t :: ts) t₂) := by
                    apply lt_of_lt_of_le <;> assumption
                  unfold bne at hneq
                  rw[Nat.not_beq_eq_true_eq] at hneq
                  have : h₁.rank + 1 ≤ t.rank := by
                    apply Nat.succ_le_of_lt hlt
                  have : h₁.rank + 1 < t.rank := by
                    apply lt_of_le_of_ne <;> assumption
                  apply lt_of_lt_of_le <;> assumption
              . match ht₂ with
                | .nil => 
                  rw[empty_heap_merge_right] at *
                  match ht₁ with
                  | .nil =>
                    simp at h
                  | .cons (t := t) (ts := ts) lt _ _ => 
                    rw[hrank_of_cons] at *
                    unfold bne at hneq
                    rw[Nat.not_beq_eq_true_eq] at hneq
                    have : h₁.rank + 1 ≤ t.rank := by
                      apply Nat.succ_le_of_lt lt
                    apply lt_of_le_of_ne <;> assumption
                | .cons (t := t) (ts := ts) lt _ _ =>
                  rw[hrank_of_cons] at *
                  rw[← heq] at lt
                  have : h₁.rank + 1 ≤ t.rank := by
                    apply Nat.succ_le_of_lt lt
                  unfold bne at hneq₂
                  rw[Nat.not_beq_eq_true_eq] at hneq₂
                  have : h₁.rank + 1 < t.rank := by
                    apply lt_of_le_of_ne <;> assumption
                  apply lt_of_lt_of_le <;> assumption
      . apply IsHeap_merge
        simp at *
        have heq : h₁.rank = h₂.rank := by
          apply Nat.le_antisymm <;> assumption
        . constructor
          . cases hxs with | cons lt _ _ =>
              rw[rank_combine heq]
              have : h₁.rank < h₁.rank + 1 := by
                apply Nat.lt_succ_self
              apply lt_trans lt this
          . cases hxs 
            cases hys
            apply combine_IsBinTree <;> assumption
          . match hxs with
            | .cons _ _ hf =>
              have : (combine le h₁ h₂).rank = h₁.rank + 1 := by
                apply rank_combine heq
              simp only [this] at *; clear this
              match hf with
              | .nil =>
                constructor
              | .cons (t := t) (ts := ts) lt _ _ =>
                constructor
                . have : h₁.rank + 1 ≤ t.rank := by
                    apply Nat.succ_le_of_lt lt
                  apply lt_of_le_of_ne this
                  rw[hrank_of_cons] at *
                  unfold bne at *
                  rw[Nat.not_beq_eq_true_eq] at *
                  assumption
                . assumption
                . assumption
        . cases hys with | cons lt _ hf =>
            have : ry ≤ h₂.rank := by
                apply le_of_lt lt
            apply IsHeapForest'_weaken hf this
    . split
      . apply IsHeap_merge
        . cases hxs with | cons lt _ hf =>
            have : rx ≤ h₁.rank := by
                apply le_of_lt lt
            apply IsHeapForest'_weaken hf this
        . constructor
          . simp at *
            have heq : h₁.rank = h₂.rank := by
              apply Nat.le_antisymm <;> assumption
            rw[rank_combine heq] at *
            cases hys
            rw[heq]
            apply Nat.lt_succ_of_lt
            assumption
          . cases hxs with | cons =>
              cases hys with | cons =>
                simp at *
                have : h₁.rank = h₂.rank := by
                  apply Nat.le_antisymm <;> assumption
                apply combine_IsBinTree <;> assumption
          . simp at *
            have heq : h₁.rank = h₂.rank := by
              apply Nat.le_antisymm <;> assumption
            rw[rank_combine heq] at *
            cases hys with | cons _ _ hf =>
              match hf with 
              | .nil =>
                constructor
              | .cons (t := t) (ts := ts) lt _ _ =>
                rw[← heq] at lt
                have b : h₁.rank + 1 ≤ t.rank := by
                  apply Nat.succ_le_of_lt lt
                rw[hrank_of_cons] at *
                constructor
                . unfold bne at *
                  rw[Nat.not_beq_eq_true_eq] at *
                  apply lt_of_le_of_ne <;> assumption
                repeat assumption      
      . simp at * 
        have heq : h₁.rank = h₂.rank := by
          apply Nat.le_antisymm <;> assumption
        constructor
        . rw[Nat.min_eq]
          split
          . rw[rank_combine heq] at *
            cases hxs
            apply Nat.lt_succ_of_lt
            assumption
          . rw[rank_combine heq] at *
            cases hys
            rw[heq]
            apply Nat.lt_succ_of_lt
            assumption                
        . cases hxs
          cases hys
          apply combine_IsBinTree <;> assumption
        . rw[rank_combine heq] at *
          cases hxs with | cons _ _ hf =>
          cases hys with | cons _ _ hf₂ =>
          have ih := IsHeap_merge hf hf₂ 
          have hle : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂) := by 
            rw[← heq] at hf₂
            apply min_hRank_mergeNodes hf hf₂
          by_cases (t₁ = [] ∧ t₂ = [])
          . have he₁ := h.left
            have he₂ := h.right
            simp[he₁, he₂]
            constructor
          . apply IsHeapForest'_strengthen
            . apply ih
            . rw[Nat.min_eq] at hle
              split at hle
              . match hf₂ with
                | .nil =>
                  rw[empty_heap_merge_right] at *
                  match hf with
                  | .nil =>
                    contradiction
                  | .cons (t := t) (ts := ts) _ _ _ =>
                    rw[hrank_of_cons] at *
                    unfold bne at *
                    rw[Bool.not_eq_false', beq_iff_eq] at *
                    simp at *
                    contradiction
                | .cons (t := t) (ts := ts) _ _ _ => 
                  match hf with
                  | .nil => 
                    rw[empty_heap_merge_left] at *
                    rw[hrank_of_cons] at *
                    unfold bne at *
                    rw[Bool.not_eq_false', beq_iff_eq] at *
                    simp at *
                    contradiction
                  | .cons (t := t₂) (ts := ts₂) _ _ _ =>
                    repeat rw[hrank_of_cons] at *
                    unfold bne at *
                    rw[Bool.not_eq_false', beq_iff_eq] at *
                    simp at *
                    have ht₁ : IsHeapForest' h₁.rank (t₂ :: ts₂) := by
                      apply IsHeapForest'_of_IsHeapForest' <;> assumption
                    have ht₂ : IsHeapForest' h₁.rank (t :: ts) := by
                      rw[← heq] at *
                      apply IsHeapForest'_of_IsHeapForest' <;> assumption
                    have : t₂.rank + 1 ≤ hRank (mergeNodes le (t₂ :: ts₂) (t :: ts)) := by
                      apply hRank_mergeNodes_cons ht₁ ht₂
                      simp_all
                    rename_i heq₂ _
                    rw[heq₂]
                    apply Nat.lt_of_succ_le this
              . match hf₂ with
                | .nil =>
                  rw[empty_heap_merge_right] at *
                  cases hf
                  . contradiction
                  . rw[hrank_of_cons] at *
                    unfold bne at *
                    rw[Bool.not_eq_false', beq_iff_eq] at *
                    simp at *
                    contradiction
                | .cons (t := t) (ts := ts) _ _ _ =>
                  rw[hrank_of_cons] at *
                  unfold bne at *
                  rw[Bool.not_eq_false', beq_iff_eq] at *
                  simp at *
                  match hf with
                  | .nil =>
                    contradiction
                  | .cons (t := t₂) (ts := ts₂) _ _ _ =>
                    rw[hrank_of_cons] at *
                    simp at *
                    have ht₁ : IsHeapForest' h₁.rank (t₂ :: ts₂) := by
                      apply IsHeapForest'_of_IsHeapForest' <;> assumption
                    have ht₂ : IsHeapForest' h₁.rank (t :: ts) := by
                      rw[← heq] at *
                      apply IsHeapForest'_of_IsHeapForest' <;> assumption
                    have : t₂.rank + 1 ≤ hRank (mergeNodes le (t₂ :: ts₂) (t :: ts)) := by
                      apply hRank_mergeNodes_cons ht₁ ht₂
                      simp_all
                    rename_i heq₂ _
                    rw[heq₂]
                    apply Nat.lt_of_succ_le this
State after:
no goals

State before:
case inl.a.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
⊢ IsHeapForest' h₁.rank (mergeNodes le t₁ (h₂ :: t₂))
Tactic:
rename_i hlt₂
State after:
case inl.a.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
⊢ IsHeapForest' h₁.rank (mergeNodes le t₁ (h₂ :: t₂))

State before:
case inl.a.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
⊢ IsHeapForest' h₁.rank (mergeNodes le t₁ (h₂ :: t₂))
Tactic:
have : h₁.rank = min h₁.rank (h₂.rank - 1) := by
  have hle : h₁.rank ≤ (h₂.rank - 1) := by
    apply Nat.le_pred_of_lt hlt₂
  have : min h₁.rank (h₂.rank - 1) = h₁.rank := by
    apply min_eq_left hle
  rw[this]
State after:
case inl.a.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
this : h₁.rank = min h₁.rank (h₂.rank - 1)
⊢ IsHeapForest' h₁.rank (mergeNodes le t₁ (h₂ :: t₂))

State before:
case inl.a.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
this : h₁.rank = min h₁.rank (h₂.rank - 1)
⊢ IsHeapForest' h₁.rank (mergeNodes le t₁ (h₂ :: t₂))
Tactic:
rw [this]
State after:
case inl.a.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
this : h₁.rank = min h₁.rank (h₂.rank - 1)
⊢ IsHeapForest' (min h₁.rank (h₂.rank - 1)) (mergeNodes le t₁ (h₂ :: t₂))

State before:
case inl.a.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
this : h₁.rank = min h₁.rank (h₂.rank - 1)
⊢ IsHeapForest' (min h₁.rank (h₂.rank - 1)) (mergeNodes le t₁ (h₂ :: t₂))
Tactic:
clear this
State after:
case inl.a.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
⊢ IsHeapForest' (min h₁.rank (h₂.rank - 1)) (mergeNodes le t₁ (h₂ :: t₂))

State before:
case inl.a.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
⊢ IsHeapForest' (min h₁.rank (h₂.rank - 1)) (mergeNodes le t₁ (h₂ :: t₂))
Tactic:
apply IsHeap_merge
State after:
case inl.a.cons.hxs
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
⊢ IsHeapForest' h₁.rank t₁

case inl.a.cons.hys
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
⊢ IsHeapForest' (h₂.rank - 1) (h₂ :: t₂)

State before:
case inl.a.cons.hxs
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
⊢ IsHeapForest' h₁.rank t₁

case inl.a.cons.hys
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
⊢ IsHeapForest' (h₂.rank - 1) (h₂ :: t₂)
Tactic:
. assumption
State after:
case inl.a.cons.hys
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
⊢ IsHeapForest' (h₂.rank - 1) (h₂ :: t₂)

State before:
case inl.a.cons.hys
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
⊢ IsHeapForest' (h₂.rank - 1) (h₂ :: t₂)
Tactic:
. apply IsHeapForest'_strengthen_pred
  . assumption
  . cases bt with | mk =>
      have hge : h₁.rank ≥ 0 := by
        cases h₁.rank
        . simp 
        . simp
      have hle : 0 ≤ h₁.rank := by
        apply hge
      have : 0 < h₂.rank := by
        apply lt_of_le_of_lt hle hlt₂
      assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
⊢ h₁.rank = min h₁.rank (h₂.rank - 1)
Tactic:
have hle : h₁.rank ≤ (h₂.rank - 1) := by
  apply Nat.le_pred_of_lt hlt₂
State after:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
hle : h₁.rank ≤ h₂.rank - 1
⊢ h₁.rank = min h₁.rank (h₂.rank - 1)

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
hle : h₁.rank ≤ h₂.rank - 1
⊢ h₁.rank = min h₁.rank (h₂.rank - 1)
Tactic:
have : min h₁.rank (h₂.rank - 1) = h₁.rank := by
  apply min_eq_left hle
State after:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
hle : h₁.rank ≤ h₂.rank - 1
this : min h₁.rank (h₂.rank - 1) = h₁.rank
⊢ h₁.rank = min h₁.rank (h₂.rank - 1)

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
hle : h₁.rank ≤ h₂.rank - 1
this : min h₁.rank (h₂.rank - 1) = h₁.rank
⊢ h₁.rank = min h₁.rank (h₂.rank - 1)
Tactic:
rw[this]
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
⊢ h₁.rank ≤ h₂.rank - 1
Tactic:
apply Nat.le_pred_of_lt hlt₂
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
bt : IsBinTree h₁
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
hle : h₁.rank ≤ h₂.rank - 1
⊢ min h₁.rank (h₂.rank - 1) = h₁.rank
Tactic:
apply min_eq_left hle
State after:
no goals

State before:
case inl.a.cons.hys.hpos.mk
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝ : IsRankedTree 1 h₁.rank (Heap.nodes h₁.children)
⊢ h₂.rank > 0
Tactic:
have hge : h₁.rank ≥ 0 := by
  cases h₁.rank
  . simp 
  . simp
State after:
case inl.a.cons.hys.hpos.mk
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝ : IsRankedTree 1 h₁.rank (Heap.nodes h₁.children)
hge : h₁.rank ≥ 0
⊢ h₂.rank > 0

State before:
case inl.a.cons.hys.hpos.mk
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝ : IsRankedTree 1 h₁.rank (Heap.nodes h₁.children)
hge : h₁.rank ≥ 0
⊢ h₂.rank > 0
Tactic:
have hle : 0 ≤ h₁.rank := by
  apply hge
State after:
case inl.a.cons.hys.hpos.mk
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝ : IsRankedTree 1 h₁.rank (Heap.nodes h₁.children)
hge : h₁.rank ≥ 0
hle : 0 ≤ h₁.rank
⊢ h₂.rank > 0

State before:
case inl.a.cons.hys.hpos.mk
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝ : IsRankedTree 1 h₁.rank (Heap.nodes h₁.children)
hge : h₁.rank ≥ 0
hle : 0 ≤ h₁.rank
⊢ h₂.rank > 0
Tactic:
have : 0 < h₂.rank := by
  apply lt_of_le_of_lt hle hlt₂
State after:
case inl.a.cons.hys.hpos.mk
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝ : IsRankedTree 1 h₁.rank (Heap.nodes h₁.children)
hge : h₁.rank ≥ 0
hle : 0 ≤ h₁.rank
this : 0 < h₂.rank
⊢ h₂.rank > 0

State before:
case inl.a.cons.hys.hpos.mk
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝ : IsRankedTree 1 h₁.rank (Heap.nodes h₁.children)
hge : h₁.rank ≥ 0
hle : 0 ≤ h₁.rank
this : 0 < h₂.rank
⊢ h₂.rank > 0
Tactic:
assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝ : IsRankedTree 1 h₁.rank (Heap.nodes h₁.children)
⊢ h₁.rank ≥ 0
Tactic:
cases h₁.rank
State after:
case zero
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝ : IsRankedTree 1 h₁.rank (Heap.nodes h₁.children)
⊢ Nat.zero ≥ 0

case succ
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝ : IsRankedTree 1 h₁.rank (Heap.nodes h₁.children)
n✝ : ℕ
⊢ Nat.succ n✝ ≥ 0

State before:
case zero
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝ : IsRankedTree 1 h₁.rank (Heap.nodes h₁.children)
⊢ Nat.zero ≥ 0

case succ
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝ : IsRankedTree 1 h₁.rank (Heap.nodes h₁.children)
n✝ : ℕ
⊢ Nat.succ n✝ ≥ 0
Tactic:
. simp
State after:
case succ
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝ : IsRankedTree 1 h₁.rank (Heap.nodes h₁.children)
n✝ : ℕ
⊢ Nat.succ n✝ ≥ 0

State before:
case succ
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝ : IsRankedTree 1 h₁.rank (Heap.nodes h₁.children)
n✝ : ℕ
⊢ Nat.succ n✝ ≥ 0
Tactic:
. simp
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝ : IsRankedTree 1 h₁.rank (Heap.nodes h₁.children)
hge : h₁.rank ≥ 0
⊢ 0 ≤ h₁.rank
Tactic:
apply hge
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hlt₂ : h₁.rank < h₂.rank
hlt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝ : IsRankedTree 1 h₁.rank (Heap.nodes h₁.children)
hge : h₁.rank ≥ 0
hle : 0 ≤ h₁.rank
⊢ 0 < h₂.rank
Tactic:
apply lt_of_le_of_lt hle hlt₂
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝¹ : ¬h₁.rank < h₂.rank
h✝ : h₂.rank < h₁.rank
⊢ min h₂.rank (h₁.rank - 1) = h₂.rank
Tactic:
have : h₂.rank ≤ (h₁.rank - 1) := by
  apply Nat.le_pred_of_lt
  assumption
State after:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝¹ : ¬h₁.rank < h₂.rank
h✝ : h₂.rank < h₁.rank
this : h₂.rank ≤ h₁.rank - 1
⊢ min h₂.rank (h₁.rank - 1) = h₂.rank

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝¹ : ¬h₁.rank < h₂.rank
h✝ : h₂.rank < h₁.rank
this : h₂.rank ≤ h₁.rank - 1
⊢ min h₂.rank (h₁.rank - 1) = h₂.rank
Tactic:
apply min_eq_left
State after:
case h
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝¹ : ¬h₁.rank < h₂.rank
h✝ : h₂.rank < h₁.rank
this : h₂.rank ≤ h₁.rank - 1
⊢ h₂.rank ≤ h₁.rank - 1

State before:
case h
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝¹ : ¬h₁.rank < h₂.rank
h✝ : h₂.rank < h₁.rank
this : h₂.rank ≤ h₁.rank - 1
⊢ h₂.rank ≤ h₁.rank - 1
Tactic:
assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝¹ : ¬h₁.rank < h₂.rank
h✝ : h₂.rank < h₁.rank
⊢ h₂.rank ≤ h₁.rank - 1
Tactic:
apply Nat.le_pred_of_lt
State after:
case h
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝¹ : ¬h₁.rank < h₂.rank
h✝ : h₂.rank < h₁.rank
⊢ h₂.rank < h₁.rank

State before:
case h
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝¹ : ¬h₁.rank < h₂.rank
h✝ : h₂.rank < h₁.rank
⊢ h₂.rank < h₁.rank
Tactic:
assumption
State after:
no goals

State before:
case inr.inl.a.hys.a.cons.a.succ.h
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝¹ : ¬h₁.rank < h₂.rank
h✝ : h₂.rank < h₁.rank
heq : min h₂.rank (h₁.rank - 1) = h₂.rank
a✝² : IsBinTree h₁
a✝¹ : IsHeapForest' h₁.rank t₁
n✝ : ℕ
a✝ : Nat.succ n✝ < h₁.rank
⊢ ?inr.inl.a.hys.a.cons.a.succ.b < h₁.rank

case inr.inl.a.hys.a.cons.a.succ.b
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝¹ : ¬h₁.rank < h₂.rank
h✝ : h₂.rank < h₁.rank
heq : min h₂.rank (h₁.rank - 1) = h₂.rank
a✝² : IsBinTree h₁
a✝¹ : IsHeapForest' h₁.rank t₁
n✝ : ℕ
a✝ : Nat.succ n✝ < h₁.rank
⊢ ℕ
Tactic:
assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
hneq : ((combine le h₁ h₂).rank != hRank t₁) = true
hneq₂ : ((combine le h₁ h₂).rank != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
⊢ h₁.rank = h₂.rank
Tactic:
apply Nat.le_antisymm <;> assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
hneq : ((combine le h₁ h₂).rank != hRank t₁) = true
hneq₂ : ((combine le h₁ h₂).rank != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
⊢ (combine le h₁ h₂).rank = h₁.rank + 1
Tactic:
apply rank_combine heq
State after:
no goals

State before:
case inr.inr.inl.inl.a.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
hneq : (h₁.rank + 1 != hRank t₁) = true
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝¹ : IsBinTree h₁
a✝ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)
Tactic:
cases hys with | cons _ _ ht₂ =>
have ih := IsHeap_merge ht₁ ht₂
have min_le : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂) := by 
  rw[← heq] at ht₂
  apply min_hRank_mergeNodes ht₁ ht₂
by_cases (t₁ = [] ∧ t₂ = [])
. have (And.intro he₁ he₂) := h
  simp[he₁, he₂]
  constructor
. apply IsHeapForest'_strengthen
  . apply ih
  . rw[Nat.min_eq] at min_le
    split at min_le
    . match ht₁ with
      | .nil =>
        rw[empty_heap_merge_left] at *
        match ht₂ with
        | .nil => simp at h
        | .cons (t := bt) hlt _ _ =>
          rw[hrank_of_cons] at *
          rw[← heq] at hlt
          unfold bne at hneq₂
          rw[Nat.not_beq_eq_true_eq] at hneq₂
          have n : h₁.rank + 1 ≤ bt.rank := by
            apply Nat.succ_le_of_lt hlt 
          apply lt_of_le_of_ne <;> assumption
      | .cons (t := t) (ts := ts) hlt _ _ =>
        rw[hrank_of_cons] at *
        have : h₁.rank < hRank (mergeNodes le (t :: ts) t₂) := by
          apply lt_of_lt_of_le <;> assumption
        unfold bne at hneq
        rw[Nat.not_beq_eq_true_eq] at hneq
        have : h₁.rank + 1 ≤ t.rank := by
          apply Nat.succ_le_of_lt hlt
        have : h₁.rank + 1 < t.rank := by
          apply lt_of_le_of_ne <;> assumption
        apply lt_of_lt_of_le <;> assumption
    . match ht₂ with
      | .nil => 
        rw[empty_heap_merge_right] at *
        match ht₁ with
        | .nil =>
          simp at h
        | .cons (t := t) (ts := ts) lt _ _ => 
          rw[hrank_of_cons] at *
          unfold bne at hneq
          rw[Nat.not_beq_eq_true_eq] at hneq
          have : h₁.rank + 1 ≤ t.rank := by
            apply Nat.succ_le_of_lt lt
          apply lt_of_le_of_ne <;> assumption
      | .cons (t := t) (ts := ts) lt _ _ =>
        rw[hrank_of_cons] at *
        rw[← heq] at lt
        have : h₁.rank + 1 ≤ t.rank := by
          apply Nat.succ_le_of_lt lt
        unfold bne at hneq₂
        rw[Nat.not_beq_eq_true_eq] at hneq₂
        have : h₁.rank + 1 < t.rank := by
          apply lt_of_le_of_ne <;> assumption
        apply lt_of_lt_of_le <;> assumption
State after:
no goals

State before:
case inr.inr.inl.inl.a.cons.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)
Tactic:
have ih := IsHeap_merge ht₁ ht₂
State after:
case inr.inr.inl.inl.a.cons.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)

State before:
case inr.inr.inl.inl.a.cons.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)
Tactic:
have min_le : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂) := by 
  rw[← heq] at ht₂
  apply min_hRank_mergeNodes ht₁ ht₂
State after:
case inr.inr.inl.inl.a.cons.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
min_le : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)

State before:
case inr.inr.inl.inl.a.cons.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
min_le : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)
Tactic:
by_cases (t₁ = [] ∧ t₂ = [])
State after:
case pos
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
min_le : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
h : t₁ = [] ∧ t₂ = []
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)

case neg
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
min_le : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
h : ¬(t₁ = [] ∧ t₂ = [])
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)

State before:
case pos
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
min_le : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
h : t₁ = [] ∧ t₂ = []
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)

case neg
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
min_le : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
h : ¬(t₁ = [] ∧ t₂ = [])
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)
Tactic:
. have (And.intro he₁ he₂) := h
  simp[he₁, he₂]
  constructor
State after:
case neg
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
min_le : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
h : ¬(t₁ = [] ∧ t₂ = [])
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)

State before:
case neg
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
min_le : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
h : ¬(t₁ = [] ∧ t₂ = [])
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)
Tactic:
. apply IsHeapForest'_strengthen
  . apply ih
  . rw[Nat.min_eq] at min_le
    split at min_le
    . match ht₁ with
      | .nil =>
        rw[empty_heap_merge_left] at *
        match ht₂ with
        | .nil => simp at h
        | .cons (t := bt) hlt _ _ =>
          rw[hrank_of_cons] at *
          rw[← heq] at hlt
          unfold bne at hneq₂
          rw[Nat.not_beq_eq_true_eq] at hneq₂
          have n : h₁.rank + 1 ≤ bt.rank := by
            apply Nat.succ_le_of_lt hlt 
          apply lt_of_le_of_ne <;> assumption
      | .cons (t := t) (ts := ts) hlt _ _ =>
        rw[hrank_of_cons] at *
        have : h₁.rank < hRank (mergeNodes le (t :: ts) t₂) := by
          apply lt_of_lt_of_le <;> assumption
        unfold bne at hneq
        rw[Nat.not_beq_eq_true_eq] at hneq
        have : h₁.rank + 1 ≤ t.rank := by
          apply Nat.succ_le_of_lt hlt
        have : h₁.rank + 1 < t.rank := by
          apply lt_of_le_of_ne <;> assumption
        apply lt_of_lt_of_le <;> assumption
    . match ht₂ with
      | .nil => 
        rw[empty_heap_merge_right] at *
        match ht₁ with
        | .nil =>
          simp at h
        | .cons (t := t) (ts := ts) lt _ _ => 
          rw[hrank_of_cons] at *
          unfold bne at hneq
          rw[Nat.not_beq_eq_true_eq] at hneq
          have : h₁.rank + 1 ≤ t.rank := by
            apply Nat.succ_le_of_lt lt
          apply lt_of_le_of_ne <;> assumption
      | .cons (t := t) (ts := ts) lt _ _ =>
        rw[hrank_of_cons] at *
        rw[← heq] at lt
        have : h₁.rank + 1 ≤ t.rank := by
          apply Nat.succ_le_of_lt lt
        unfold bne at hneq₂
        rw[Nat.not_beq_eq_true_eq] at hneq₂
        have : h₁.rank + 1 < t.rank := by
          apply lt_of_le_of_ne <;> assumption
        apply lt_of_lt_of_le <;> assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
⊢ min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
Tactic:
rw[← heq] at ht₂
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₁.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
⊢ min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝¹ : h₂.rank ≤ h₁.rank
h✝ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₁.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
⊢ min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
Tactic:
apply min_hRank_mergeNodes ht₁ ht₂
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq : (h₁.rank + 1 != hRank []) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le [] t₂)
h : ¬([] = [] ∧ t₂ = [])
h✝ : hRank [] ≤ hRank t₂
min_le : hRank [] ≤ hRank (mergeNodes le [] t₂)
⊢ h₁.rank + 1 < hRank (mergeNodes le [] t₂)
Tactic:
rw[empty_heap_merge_left] at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq : (h₁.rank + 1 != hRank []) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) t₂
h : ¬([] = [] ∧ t₂ = [])
h✝ min_le : hRank [] ≤ hRank t₂
⊢ h₁.rank + 1 < hRank t₂

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq : (h₁.rank + 1 != hRank []) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) t₂
h : ¬([] = [] ∧ t₂ = [])
h✝ min_le : hRank [] ≤ hRank t₂
⊢ h₁.rank + 1 < hRank t₂
Tactic:
match ht₂ with
| .nil => simp at h
| .cons (t := bt) hlt _ _ =>
  rw[hrank_of_cons] at *
  rw[← heq] at hlt
  unfold bne at hneq₂
  rw[Nat.not_beq_eq_true_eq] at hneq₂
  have n : h₁.rank + 1 ≤ bt.rank := by
    apply Nat.succ_le_of_lt hlt 
  apply lt_of_le_of_ne <;> assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq hneq₂ : (h₁.rank + 1 != hRank []) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) []
h : ¬([] = [] ∧ [] = [])
h✝ min_le : hRank [] ≤ hRank []
⊢ h₁.rank + 1 < hRank []
Tactic:
simp at h
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq : (h₁.rank + 1 != hRank []) = true
bt : BinTree α
ts✝ : List (BinTree α)
hlt : h₂.rank < bt.rank
a✝¹ : IsBinTree bt
a✝ : IsHeapForest' bt.rank ts✝
hneq₂ : (h₁.rank + 1 != hRank (bt :: ts✝)) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (bt :: ts✝)
h : ¬([] = [] ∧ bt :: ts✝ = [])
h✝ min_le : hRank [] ≤ hRank (bt :: ts✝)
⊢ h₁.rank + 1 < hRank (bt :: ts✝)
Tactic:
rw[hrank_of_cons] at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq : (h₁.rank + 1 != hRank []) = true
bt : BinTree α
ts✝ : List (BinTree α)
hlt : h₂.rank < bt.rank
a✝¹ : IsBinTree bt
a✝ : IsHeapForest' bt.rank ts✝
hneq₂ : (h₁.rank + 1 != bt.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (bt :: ts✝)
h : ¬([] = [] ∧ bt :: ts✝ = [])
h✝ min_le : hRank [] ≤ bt.rank
⊢ h₁.rank + 1 < bt.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq : (h₁.rank + 1 != hRank []) = true
bt : BinTree α
ts✝ : List (BinTree α)
hlt : h₂.rank < bt.rank
a✝¹ : IsBinTree bt
a✝ : IsHeapForest' bt.rank ts✝
hneq₂ : (h₁.rank + 1 != bt.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (bt :: ts✝)
h : ¬([] = [] ∧ bt :: ts✝ = [])
h✝ min_le : hRank [] ≤ bt.rank
⊢ h₁.rank + 1 < bt.rank
Tactic:
rw[← heq] at hlt
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq : (h₁.rank + 1 != hRank []) = true
bt : BinTree α
ts✝ : List (BinTree α)
hlt : h₁.rank < bt.rank
a✝¹ : IsBinTree bt
a✝ : IsHeapForest' bt.rank ts✝
hneq₂ : (h₁.rank + 1 != bt.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (bt :: ts✝)
h : ¬([] = [] ∧ bt :: ts✝ = [])
h✝ min_le : hRank [] ≤ bt.rank
⊢ h₁.rank + 1 < bt.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq : (h₁.rank + 1 != hRank []) = true
bt : BinTree α
ts✝ : List (BinTree α)
hlt : h₁.rank < bt.rank
a✝¹ : IsBinTree bt
a✝ : IsHeapForest' bt.rank ts✝
hneq₂ : (h₁.rank + 1 != bt.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (bt :: ts✝)
h : ¬([] = [] ∧ bt :: ts✝ = [])
h✝ min_le : hRank [] ≤ bt.rank
⊢ h₁.rank + 1 < bt.rank
Tactic:
unfold bne at hneq₂
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq : (h₁.rank + 1 != hRank []) = true
bt : BinTree α
ts✝ : List (BinTree α)
hlt : h₁.rank < bt.rank
a✝¹ : IsBinTree bt
a✝ : IsHeapForest' bt.rank ts✝
hneq₂ : (!h₁.rank + 1 == bt.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (bt :: ts✝)
h : ¬([] = [] ∧ bt :: ts✝ = [])
h✝ min_le : hRank [] ≤ bt.rank
⊢ h₁.rank + 1 < bt.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq : (h₁.rank + 1 != hRank []) = true
bt : BinTree α
ts✝ : List (BinTree α)
hlt : h₁.rank < bt.rank
a✝¹ : IsBinTree bt
a✝ : IsHeapForest' bt.rank ts✝
hneq₂ : (!h₁.rank + 1 == bt.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (bt :: ts✝)
h : ¬([] = [] ∧ bt :: ts✝ = [])
h✝ min_le : hRank [] ≤ bt.rank
⊢ h₁.rank + 1 < bt.rank
Tactic:
rw[Nat.not_beq_eq_true_eq] at hneq₂
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq : (h₁.rank + 1 != hRank []) = true
bt : BinTree α
ts✝ : List (BinTree α)
hlt : h₁.rank < bt.rank
a✝¹ : IsBinTree bt
a✝ : IsHeapForest' bt.rank ts✝
hneq₂ : ¬h₁.rank + 1 = bt.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (bt :: ts✝)
h : ¬([] = [] ∧ bt :: ts✝ = [])
h✝ min_le : hRank [] ≤ bt.rank
⊢ h₁.rank + 1 < bt.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq : (h₁.rank + 1 != hRank []) = true
bt : BinTree α
ts✝ : List (BinTree α)
hlt : h₁.rank < bt.rank
a✝¹ : IsBinTree bt
a✝ : IsHeapForest' bt.rank ts✝
hneq₂ : ¬h₁.rank + 1 = bt.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (bt :: ts✝)
h : ¬([] = [] ∧ bt :: ts✝ = [])
h✝ min_le : hRank [] ≤ bt.rank
⊢ h₁.rank + 1 < bt.rank
Tactic:
have n : h₁.rank + 1 ≤ bt.rank := by
  apply Nat.succ_le_of_lt hlt
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq : (h₁.rank + 1 != hRank []) = true
bt : BinTree α
ts✝ : List (BinTree α)
hlt : h₁.rank < bt.rank
a✝¹ : IsBinTree bt
a✝ : IsHeapForest' bt.rank ts✝
hneq₂ : ¬h₁.rank + 1 = bt.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (bt :: ts✝)
h : ¬([] = [] ∧ bt :: ts✝ = [])
h✝ min_le : hRank [] ≤ bt.rank
n : h₁.rank + 1 ≤ bt.rank
⊢ h₁.rank + 1 < bt.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq : (h₁.rank + 1 != hRank []) = true
bt : BinTree α
ts✝ : List (BinTree α)
hlt : h₁.rank < bt.rank
a✝¹ : IsBinTree bt
a✝ : IsHeapForest' bt.rank ts✝
hneq₂ : ¬h₁.rank + 1 = bt.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (bt :: ts✝)
h : ¬([] = [] ∧ bt :: ts✝ = [])
h✝ min_le : hRank [] ≤ bt.rank
n : h₁.rank + 1 ≤ bt.rank
⊢ h₁.rank + 1 < bt.rank
Tactic:
apply lt_of_le_of_ne <;> assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq : (h₁.rank + 1 != hRank []) = true
bt : BinTree α
ts✝ : List (BinTree α)
hlt : h₁.rank < bt.rank
a✝¹ : IsBinTree bt
a✝ : IsHeapForest' bt.rank ts✝
hneq₂ : ¬h₁.rank + 1 = bt.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (bt :: ts✝)
h : ¬([] = [] ∧ bt :: ts✝ = [])
h✝ min_le : hRank [] ≤ bt.rank
⊢ h₁.rank + 1 ≤ bt.rank
Tactic:
apply Nat.succ_le_of_lt hlt
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
hlt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : (h₁.rank + 1 != hRank (t :: ts)) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t :: ts) t₂)
h : ¬(t :: ts = [] ∧ t₂ = [])
h✝ : hRank (t :: ts) ≤ hRank t₂
min_le : hRank (t :: ts) ≤ hRank (mergeNodes le (t :: ts) t₂)
⊢ h₁.rank + 1 < hRank (mergeNodes le (t :: ts) t₂)
Tactic:
rw[hrank_of_cons] at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
hlt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : (h₁.rank + 1 != t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t :: ts) t₂)
h : ¬(t :: ts = [] ∧ t₂ = [])
h✝ : t.rank ≤ hRank t₂
min_le : t.rank ≤ hRank (mergeNodes le (t :: ts) t₂)
⊢ h₁.rank + 1 < hRank (mergeNodes le (t :: ts) t₂)

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
hlt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : (h₁.rank + 1 != t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t :: ts) t₂)
h : ¬(t :: ts = [] ∧ t₂ = [])
h✝ : t.rank ≤ hRank t₂
min_le : t.rank ≤ hRank (mergeNodes le (t :: ts) t₂)
⊢ h₁.rank + 1 < hRank (mergeNodes le (t :: ts) t₂)
Tactic:
have : h₁.rank < hRank (mergeNodes le (t :: ts) t₂) := by
  apply lt_of_lt_of_le <;> assumption
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
hlt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : (h₁.rank + 1 != t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t :: ts) t₂)
h : ¬(t :: ts = [] ∧ t₂ = [])
h✝ : t.rank ≤ hRank t₂
min_le : t.rank ≤ hRank (mergeNodes le (t :: ts) t₂)
this : h₁.rank < hRank (mergeNodes le (t :: ts) t₂)
⊢ h₁.rank + 1 < hRank (mergeNodes le (t :: ts) t₂)

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
hlt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : (h₁.rank + 1 != t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t :: ts) t₂)
h : ¬(t :: ts = [] ∧ t₂ = [])
h✝ : t.rank ≤ hRank t₂
min_le : t.rank ≤ hRank (mergeNodes le (t :: ts) t₂)
this : h₁.rank < hRank (mergeNodes le (t :: ts) t₂)
⊢ h₁.rank + 1 < hRank (mergeNodes le (t :: ts) t₂)
Tactic:
unfold bne at hneq
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
hlt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : (!h₁.rank + 1 == t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t :: ts) t₂)
h : ¬(t :: ts = [] ∧ t₂ = [])
h✝ : t.rank ≤ hRank t₂
min_le : t.rank ≤ hRank (mergeNodes le (t :: ts) t₂)
this : h₁.rank < hRank (mergeNodes le (t :: ts) t₂)
⊢ h₁.rank + 1 < hRank (mergeNodes le (t :: ts) t₂)

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
hlt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : (!h₁.rank + 1 == t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t :: ts) t₂)
h : ¬(t :: ts = [] ∧ t₂ = [])
h✝ : t.rank ≤ hRank t₂
min_le : t.rank ≤ hRank (mergeNodes le (t :: ts) t₂)
this : h₁.rank < hRank (mergeNodes le (t :: ts) t₂)
⊢ h₁.rank + 1 < hRank (mergeNodes le (t :: ts) t₂)
Tactic:
rw[Nat.not_beq_eq_true_eq] at hneq
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
hlt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t :: ts) t₂)
h : ¬(t :: ts = [] ∧ t₂ = [])
h✝ : t.rank ≤ hRank t₂
min_le : t.rank ≤ hRank (mergeNodes le (t :: ts) t₂)
this : h₁.rank < hRank (mergeNodes le (t :: ts) t₂)
⊢ h₁.rank + 1 < hRank (mergeNodes le (t :: ts) t₂)

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
hlt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t :: ts) t₂)
h : ¬(t :: ts = [] ∧ t₂ = [])
h✝ : t.rank ≤ hRank t₂
min_le : t.rank ≤ hRank (mergeNodes le (t :: ts) t₂)
this : h₁.rank < hRank (mergeNodes le (t :: ts) t₂)
⊢ h₁.rank + 1 < hRank (mergeNodes le (t :: ts) t₂)
Tactic:
have : h₁.rank + 1 ≤ t.rank := by
  apply Nat.succ_le_of_lt hlt
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
hlt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t :: ts) t₂)
h : ¬(t :: ts = [] ∧ t₂ = [])
h✝ : t.rank ≤ hRank t₂
min_le : t.rank ≤ hRank (mergeNodes le (t :: ts) t₂)
this✝ : h₁.rank < hRank (mergeNodes le (t :: ts) t₂)
this : h₁.rank + 1 ≤ t.rank
⊢ h₁.rank + 1 < hRank (mergeNodes le (t :: ts) t₂)

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
hlt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t :: ts) t₂)
h : ¬(t :: ts = [] ∧ t₂ = [])
h✝ : t.rank ≤ hRank t₂
min_le : t.rank ≤ hRank (mergeNodes le (t :: ts) t₂)
this✝ : h₁.rank < hRank (mergeNodes le (t :: ts) t₂)
this : h₁.rank + 1 ≤ t.rank
⊢ h₁.rank + 1 < hRank (mergeNodes le (t :: ts) t₂)
Tactic:
have : h₁.rank + 1 < t.rank := by
  apply lt_of_le_of_ne <;> assumption
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
hlt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t :: ts) t₂)
h : ¬(t :: ts = [] ∧ t₂ = [])
h✝ : t.rank ≤ hRank t₂
min_le : t.rank ≤ hRank (mergeNodes le (t :: ts) t₂)
this✝¹ : h₁.rank < hRank (mergeNodes le (t :: ts) t₂)
this✝ : h₁.rank + 1 ≤ t.rank
this : h₁.rank + 1 < t.rank
⊢ h₁.rank + 1 < hRank (mergeNodes le (t :: ts) t₂)

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
hlt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t :: ts) t₂)
h : ¬(t :: ts = [] ∧ t₂ = [])
h✝ : t.rank ≤ hRank t₂
min_le : t.rank ≤ hRank (mergeNodes le (t :: ts) t₂)
this✝¹ : h₁.rank < hRank (mergeNodes le (t :: ts) t₂)
this✝ : h₁.rank + 1 ≤ t.rank
this : h₁.rank + 1 < t.rank
⊢ h₁.rank + 1 < hRank (mergeNodes le (t :: ts) t₂)
Tactic:
apply lt_of_lt_of_le <;> assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
hlt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : (h₁.rank + 1 != t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t :: ts) t₂)
h : ¬(t :: ts = [] ∧ t₂ = [])
h✝ : t.rank ≤ hRank t₂
min_le : t.rank ≤ hRank (mergeNodes le (t :: ts) t₂)
⊢ h₁.rank < hRank (mergeNodes le (t :: ts) t₂)
Tactic:
apply lt_of_lt_of_le <;> assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
hlt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t :: ts) t₂)
h : ¬(t :: ts = [] ∧ t₂ = [])
h✝ : t.rank ≤ hRank t₂
min_le : t.rank ≤ hRank (mergeNodes le (t :: ts) t₂)
this : h₁.rank < hRank (mergeNodes le (t :: ts) t₂)
⊢ h₁.rank + 1 ≤ t.rank
Tactic:
apply Nat.succ_le_of_lt hlt
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq₂ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
hlt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t :: ts) t₂)
h : ¬(t :: ts = [] ∧ t₂ = [])
h✝ : t.rank ≤ hRank t₂
min_le : t.rank ≤ hRank (mergeNodes le (t :: ts) t₂)
this✝ : h₁.rank < hRank (mergeNodes le (t :: ts) t₂)
this : h₁.rank + 1 ≤ t.rank
⊢ h₁.rank + 1 < t.rank
Tactic:
apply lt_of_le_of_ne <;> assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq₂ : (h₁.rank + 1 != hRank []) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ [])
h : ¬(t₁ = [] ∧ [] = [])
h✝ : ¬hRank t₁ ≤ hRank []
min_le : hRank [] ≤ hRank (mergeNodes le t₁ [])
⊢ h₁.rank + 1 < hRank (mergeNodes le t₁ [])
Tactic:
rw[empty_heap_merge_right] at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq₂ : (h₁.rank + 1 != hRank []) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) t₁
h : ¬(t₁ = [] ∧ [] = [])
h✝ : ¬hRank t₁ ≤ hRank []
min_le : hRank [] ≤ hRank t₁
⊢ h₁.rank + 1 < hRank t₁

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq₂ : (h₁.rank + 1 != hRank []) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) t₁
h : ¬(t₁ = [] ∧ [] = [])
h✝ : ¬hRank t₁ ≤ hRank []
min_le : hRank [] ≤ hRank t₁
⊢ h₁.rank + 1 < hRank t₁
Tactic:
match ht₁ with
| .nil =>
  simp at h
| .cons (t := t) (ts := ts) lt _ _ => 
  rw[hrank_of_cons] at *
  unfold bne at hneq
  rw[Nat.not_beq_eq_true_eq] at hneq
  have : h₁.rank + 1 ≤ t.rank := by
    apply Nat.succ_le_of_lt lt
  apply lt_of_le_of_ne <;> assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq₂ hneq : (h₁.rank + 1 != hRank []) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) []
h : ¬([] = [] ∧ [] = [])
h✝ : ¬hRank [] ≤ hRank []
min_le : hRank [] ≤ hRank []
⊢ h₁.rank + 1 < hRank []
Tactic:
simp at h
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq₂ : (h₁.rank + 1 != hRank []) = true
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : (h₁.rank + 1 != hRank (t :: ts)) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : ¬hRank (t :: ts) ≤ hRank []
min_le : hRank [] ≤ hRank (t :: ts)
⊢ h₁.rank + 1 < hRank (t :: ts)
Tactic:
rw[hrank_of_cons] at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq₂ : (h₁.rank + 1 != hRank []) = true
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : (h₁.rank + 1 != t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : ¬t.rank ≤ hRank []
min_le : hRank [] ≤ t.rank
⊢ h₁.rank + 1 < t.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq₂ : (h₁.rank + 1 != hRank []) = true
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : (h₁.rank + 1 != t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : ¬t.rank ≤ hRank []
min_le : hRank [] ≤ t.rank
⊢ h₁.rank + 1 < t.rank
Tactic:
unfold bne at hneq
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq₂ : (h₁.rank + 1 != hRank []) = true
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : (!h₁.rank + 1 == t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : ¬t.rank ≤ hRank []
min_le : hRank [] ≤ t.rank
⊢ h₁.rank + 1 < t.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq₂ : (h₁.rank + 1 != hRank []) = true
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : (!h₁.rank + 1 == t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : ¬t.rank ≤ hRank []
min_le : hRank [] ≤ t.rank
⊢ h₁.rank + 1 < t.rank
Tactic:
rw[Nat.not_beq_eq_true_eq] at hneq
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq₂ : (h₁.rank + 1 != hRank []) = true
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : ¬t.rank ≤ hRank []
min_le : hRank [] ≤ t.rank
⊢ h₁.rank + 1 < t.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq₂ : (h₁.rank + 1 != hRank []) = true
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : ¬t.rank ≤ hRank []
min_le : hRank [] ≤ t.rank
⊢ h₁.rank + 1 < t.rank
Tactic:
have : h₁.rank + 1 ≤ t.rank := by
  apply Nat.succ_le_of_lt lt
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq₂ : (h₁.rank + 1 != hRank []) = true
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : ¬t.rank ≤ hRank []
min_le : hRank [] ≤ t.rank
this : h₁.rank + 1 ≤ t.rank
⊢ h₁.rank + 1 < t.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq₂ : (h₁.rank + 1 != hRank []) = true
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : ¬t.rank ≤ hRank []
min_le : hRank [] ≤ t.rank
this : h₁.rank + 1 ≤ t.rank
⊢ h₁.rank + 1 < t.rank
Tactic:
apply lt_of_le_of_ne <;> assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
hneq₂ : (h₁.rank + 1 != hRank []) = true
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : ¬t.rank ≤ hRank []
min_le : hRank [] ≤ t.rank
⊢ h₁.rank + 1 ≤ t.rank
Tactic:
apply Nat.succ_le_of_lt lt
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₂.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq₂ : (h₁.rank + 1 != hRank (t :: ts)) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ (t :: ts))
h : ¬(t₁ = [] ∧ t :: ts = [])
h✝ : ¬hRank t₁ ≤ hRank (t :: ts)
min_le : hRank (t :: ts) ≤ hRank (mergeNodes le t₁ (t :: ts))
⊢ h₁.rank + 1 < hRank (mergeNodes le t₁ (t :: ts))
Tactic:
rw[hrank_of_cons] at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₂.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq₂ : (h₁.rank + 1 != t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ (t :: ts))
h : ¬(t₁ = [] ∧ t :: ts = [])
h✝ : ¬hRank t₁ ≤ t.rank
min_le : t.rank ≤ hRank (mergeNodes le t₁ (t :: ts))
⊢ h₁.rank + 1 < hRank (mergeNodes le t₁ (t :: ts))

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₂.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq₂ : (h₁.rank + 1 != t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ (t :: ts))
h : ¬(t₁ = [] ∧ t :: ts = [])
h✝ : ¬hRank t₁ ≤ t.rank
min_le : t.rank ≤ hRank (mergeNodes le t₁ (t :: ts))
⊢ h₁.rank + 1 < hRank (mergeNodes le t₁ (t :: ts))
Tactic:
rw[← heq] at lt
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq₂ : (h₁.rank + 1 != t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ (t :: ts))
h : ¬(t₁ = [] ∧ t :: ts = [])
h✝ : ¬hRank t₁ ≤ t.rank
min_le : t.rank ≤ hRank (mergeNodes le t₁ (t :: ts))
⊢ h₁.rank + 1 < hRank (mergeNodes le t₁ (t :: ts))

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq₂ : (h₁.rank + 1 != t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ (t :: ts))
h : ¬(t₁ = [] ∧ t :: ts = [])
h✝ : ¬hRank t₁ ≤ t.rank
min_le : t.rank ≤ hRank (mergeNodes le t₁ (t :: ts))
⊢ h₁.rank + 1 < hRank (mergeNodes le t₁ (t :: ts))
Tactic:
have : h₁.rank + 1 ≤ t.rank := by
  apply Nat.succ_le_of_lt lt
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq₂ : (h₁.rank + 1 != t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ (t :: ts))
h : ¬(t₁ = [] ∧ t :: ts = [])
h✝ : ¬hRank t₁ ≤ t.rank
min_le : t.rank ≤ hRank (mergeNodes le t₁ (t :: ts))
this : h₁.rank + 1 ≤ t.rank
⊢ h₁.rank + 1 < hRank (mergeNodes le t₁ (t :: ts))

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq₂ : (h₁.rank + 1 != t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ (t :: ts))
h : ¬(t₁ = [] ∧ t :: ts = [])
h✝ : ¬hRank t₁ ≤ t.rank
min_le : t.rank ≤ hRank (mergeNodes le t₁ (t :: ts))
this : h₁.rank + 1 ≤ t.rank
⊢ h₁.rank + 1 < hRank (mergeNodes le t₁ (t :: ts))
Tactic:
unfold bne at hneq₂
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq₂ : (!h₁.rank + 1 == t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ (t :: ts))
h : ¬(t₁ = [] ∧ t :: ts = [])
h✝ : ¬hRank t₁ ≤ t.rank
min_le : t.rank ≤ hRank (mergeNodes le t₁ (t :: ts))
this : h₁.rank + 1 ≤ t.rank
⊢ h₁.rank + 1 < hRank (mergeNodes le t₁ (t :: ts))

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq₂ : (!h₁.rank + 1 == t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ (t :: ts))
h : ¬(t₁ = [] ∧ t :: ts = [])
h✝ : ¬hRank t₁ ≤ t.rank
min_le : t.rank ≤ hRank (mergeNodes le t₁ (t :: ts))
this : h₁.rank + 1 ≤ t.rank
⊢ h₁.rank + 1 < hRank (mergeNodes le t₁ (t :: ts))
Tactic:
rw[Nat.not_beq_eq_true_eq] at hneq₂
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq₂ : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ (t :: ts))
h : ¬(t₁ = [] ∧ t :: ts = [])
h✝ : ¬hRank t₁ ≤ t.rank
min_le : t.rank ≤ hRank (mergeNodes le t₁ (t :: ts))
this : h₁.rank + 1 ≤ t.rank
⊢ h₁.rank + 1 < hRank (mergeNodes le t₁ (t :: ts))

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq₂ : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ (t :: ts))
h : ¬(t₁ = [] ∧ t :: ts = [])
h✝ : ¬hRank t₁ ≤ t.rank
min_le : t.rank ≤ hRank (mergeNodes le t₁ (t :: ts))
this : h₁.rank + 1 ≤ t.rank
⊢ h₁.rank + 1 < hRank (mergeNodes le t₁ (t :: ts))
Tactic:
have : h₁.rank + 1 < t.rank := by
  apply lt_of_le_of_ne <;> assumption
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq₂ : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ (t :: ts))
h : ¬(t₁ = [] ∧ t :: ts = [])
h✝ : ¬hRank t₁ ≤ t.rank
min_le : t.rank ≤ hRank (mergeNodes le t₁ (t :: ts))
this✝ : h₁.rank + 1 ≤ t.rank
this : h₁.rank + 1 < t.rank
⊢ h₁.rank + 1 < hRank (mergeNodes le t₁ (t :: ts))

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq₂ : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ (t :: ts))
h : ¬(t₁ = [] ∧ t :: ts = [])
h✝ : ¬hRank t₁ ≤ t.rank
min_le : t.rank ≤ hRank (mergeNodes le t₁ (t :: ts))
this✝ : h₁.rank + 1 ≤ t.rank
this : h₁.rank + 1 < t.rank
⊢ h₁.rank + 1 < hRank (mergeNodes le t₁ (t :: ts))
Tactic:
apply lt_of_lt_of_le <;> assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq₂ : (h₁.rank + 1 != t.rank) = true
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ (t :: ts))
h : ¬(t₁ = [] ∧ t :: ts = [])
h✝ : ¬hRank t₁ ≤ t.rank
min_le : t.rank ≤ hRank (mergeNodes le t₁ (t :: ts))
⊢ h₁.rank + 1 ≤ t.rank
Tactic:
apply Nat.succ_le_of_lt lt
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hneq : (h₁.rank + 1 != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
ht₁ : IsHeapForest' h₁.rank t₁
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
ht₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hneq₂ : ¬h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ (t :: ts))
h : ¬(t₁ = [] ∧ t :: ts = [])
h✝ : ¬hRank t₁ ≤ t.rank
min_le : t.rank ≤ hRank (mergeNodes le t₁ (t :: ts))
this : h₁.rank + 1 ≤ t.rank
⊢ h₁.rank + 1 < t.rank
Tactic:
apply lt_of_le_of_ne <;> assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ((combine le h₁ h₂).rank != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = false
⊢ h₁.rank = h₂.rank
Tactic:
apply Nat.le_antisymm <;> assumption
State after:
no goals

State before:
case inr.inr.inl.inr.hxs.a.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ((combine le h₁ h₂).rank != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝¹ : IsBinTree h₁
lt : rx < h₁.rank
a✝ : IsHeapForest' h₁.rank t₁
⊢ rx < (combine le h₁ h₂).rank
Tactic:
rw[rank_combine heq]
State after:
case inr.inr.inl.inr.hxs.a.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ((combine le h₁ h₂).rank != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝¹ : IsBinTree h₁
lt : rx < h₁.rank
a✝ : IsHeapForest' h₁.rank t₁
⊢ rx < h₁.rank + 1

State before:
case inr.inr.inl.inr.hxs.a.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ((combine le h₁ h₂).rank != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝¹ : IsBinTree h₁
lt : rx < h₁.rank
a✝ : IsHeapForest' h₁.rank t₁
⊢ rx < h₁.rank + 1
Tactic:
have : h₁.rank < h₁.rank + 1 := by
  apply Nat.lt_succ_self
State after:
case inr.inr.inl.inr.hxs.a.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ((combine le h₁ h₂).rank != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝¹ : IsBinTree h₁
lt : rx < h₁.rank
a✝ : IsHeapForest' h₁.rank t₁
this : h₁.rank < h₁.rank + 1
⊢ rx < h₁.rank + 1

State before:
case inr.inr.inl.inr.hxs.a.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ((combine le h₁ h₂).rank != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝¹ : IsBinTree h₁
lt : rx < h₁.rank
a✝ : IsHeapForest' h₁.rank t₁
this : h₁.rank < h₁.rank + 1
⊢ rx < h₁.rank + 1
Tactic:
apply lt_trans lt this
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ((combine le h₁ h₂).rank != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝¹ : IsBinTree h₁
lt : rx < h₁.rank
a✝ : IsHeapForest' h₁.rank t₁
⊢ h₁.rank < h₁.rank + 1
Tactic:
apply Nat.lt_succ_self
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ((combine le h₁ h₂).rank != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝¹ : rx < h₁.rank
a✝ : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
⊢ IsHeapForest' (combine le h₁ h₂).rank t₁
Tactic:
have : (combine le h₁ h₂).rank = h₁.rank + 1 := by
  apply rank_combine heq
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ((combine le h₁ h₂).rank != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝¹ : rx < h₁.rank
a✝ : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
this : (combine le h₁ h₂).rank = h₁.rank + 1
⊢ IsHeapForest' (combine le h₁ h₂).rank t₁

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ((combine le h₁ h₂).rank != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝¹ : rx < h₁.rank
a✝ : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
this : (combine le h₁ h₂).rank = h₁.rank + 1
⊢ IsHeapForest' (combine le h₁ h₂).rank t₁
Tactic:
simp only [this] at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝¹ : rx < h₁.rank
a✝ : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₁) = true
h✝ : (h₁.rank + 1 != hRank t₂) = false
this : True
⊢ IsHeapForest' (h₁.rank + 1) t₁

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝¹ : rx < h₁.rank
a✝ : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₁) = true
h✝ : (h₁.rank + 1 != hRank t₂) = false
this : True
⊢ IsHeapForest' (h₁.rank + 1) t₁
Tactic:
clear this
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝¹ : rx < h₁.rank
a✝ : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₁) = true
h✝ : (h₁.rank + 1 != hRank t₂) = false
⊢ IsHeapForest' (h₁.rank + 1) t₁

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝¹ : rx < h₁.rank
a✝ : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₁) = true
h✝ : (h₁.rank + 1 != hRank t₂) = false
⊢ IsHeapForest' (h₁.rank + 1) t₁
Tactic:
match hf with
| .nil =>
  constructor
| .cons (t := t) (ts := ts) lt _ _ =>
  constructor
  . have : h₁.rank + 1 ≤ t.rank := by
      apply Nat.succ_le_of_lt lt
    apply lt_of_le_of_ne this
    rw[hrank_of_cons] at *
    unfold bne at *
    rw[Nat.not_beq_eq_true_eq] at *
    assumption
  . assumption
  . assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ((combine le h₁ h₂).rank != hRank t₁) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝¹ : rx < h₁.rank
a✝ : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
⊢ (combine le h₁ h₂).rank = h₁.rank + 1
Tactic:
apply rank_combine heq
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝¹ : rx < h₁.rank
a✝ : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₂) = false
hxs : IsHeapForest' rx [h₁]
h✝ : (h₁.rank + 1 != hRank []) = true
⊢ IsHeapForest' (h₁.rank + 1) []
Tactic:
constructor
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : rx < h₁.rank
a✝² : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₂) = false
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hxs : IsHeapForest' rx (h₁ :: t :: ts)
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ IsHeapForest' (h₁.rank + 1) (t :: ts)
Tactic:
constructor
State after:
case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : rx < h₁.rank
a✝² : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₂) = false
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hxs : IsHeapForest' rx (h₁ :: t :: ts)
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ h₁.rank + 1 < t.rank

case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : rx < h₁.rank
a✝² : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₂) = false
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hxs : IsHeapForest' rx (h₁ :: t :: ts)
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ IsBinTree t

case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : rx < h₁.rank
a✝² : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₂) = false
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hxs : IsHeapForest' rx (h₁ :: t :: ts)
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ IsHeapForest' t.rank ts

State before:
case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : rx < h₁.rank
a✝² : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₂) = false
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hxs : IsHeapForest' rx (h₁ :: t :: ts)
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ h₁.rank + 1 < t.rank

case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : rx < h₁.rank
a✝² : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₂) = false
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hxs : IsHeapForest' rx (h₁ :: t :: ts)
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ IsBinTree t

case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : rx < h₁.rank
a✝² : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₂) = false
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hxs : IsHeapForest' rx (h₁ :: t :: ts)
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ IsHeapForest' t.rank ts
Tactic:
. have : h₁.rank + 1 ≤ t.rank := by
    apply Nat.succ_le_of_lt lt
  apply lt_of_le_of_ne this
  rw[hrank_of_cons] at *
  unfold bne at *
  rw[Nat.not_beq_eq_true_eq] at *
  assumption
State after:
case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : rx < h₁.rank
a✝² : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₂) = false
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hxs : IsHeapForest' rx (h₁ :: t :: ts)
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ IsBinTree t

case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : rx < h₁.rank
a✝² : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₂) = false
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hxs : IsHeapForest' rx (h₁ :: t :: ts)
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ IsHeapForest' t.rank ts

State before:
case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : rx < h₁.rank
a✝² : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₂) = false
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hxs : IsHeapForest' rx (h₁ :: t :: ts)
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ IsBinTree t

case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : rx < h₁.rank
a✝² : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₂) = false
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hxs : IsHeapForest' rx (h₁ :: t :: ts)
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ IsHeapForest' t.rank ts
Tactic:
. assumption
State after:
case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : rx < h₁.rank
a✝² : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₂) = false
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hxs : IsHeapForest' rx (h₁ :: t :: ts)
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ IsHeapForest' t.rank ts

State before:
case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : rx < h₁.rank
a✝² : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₂) = false
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hxs : IsHeapForest' rx (h₁ :: t :: ts)
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ IsHeapForest' t.rank ts
Tactic:
. assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : rx < h₁.rank
a✝² : IsBinTree h₁
hf : IsHeapForest' h₁.rank t₁
h✝¹ : (h₁.rank + 1 != hRank t₂) = false
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
hxs : IsHeapForest' rx (h₁ :: t :: ts)
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ h₁.rank + 1 ≤ t.rank
Tactic:
apply Nat.succ_le_of_lt lt
State after:
no goals

State before:
case inr.inr.inl.inr.hys.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
h✝³ : ¬h₁.rank < h₂.rank
h✝² : ¬h₂.rank < h₁.rank
h✝¹ : ((combine le h₁ h₂).rank != hRank t₁) = true
h✝ : ¬((combine le h₁ h₂).rank != hRank t₂) = true
a✝ : IsBinTree h₂
lt : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
⊢ IsHeapForest' ry t₂
Tactic:
have : ry ≤ h₂.rank := by
    apply le_of_lt lt
State after:
case inr.inr.inl.inr.hys.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
h✝³ : ¬h₁.rank < h₂.rank
h✝² : ¬h₂.rank < h₁.rank
h✝¹ : ((combine le h₁ h₂).rank != hRank t₁) = true
h✝ : ¬((combine le h₁ h₂).rank != hRank t₂) = true
a✝ : IsBinTree h₂
lt : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
this : ry ≤ h₂.rank
⊢ IsHeapForest' ry t₂

State before:
case inr.inr.inl.inr.hys.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
h✝³ : ¬h₁.rank < h₂.rank
h✝² : ¬h₂.rank < h₁.rank
h✝¹ : ((combine le h₁ h₂).rank != hRank t₁) = true
h✝ : ¬((combine le h₁ h₂).rank != hRank t₂) = true
a✝ : IsBinTree h₂
lt : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
this : ry ≤ h₂.rank
⊢ IsHeapForest' ry t₂
Tactic:
apply IsHeapForest'_weaken hf this
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
h✝³ : ¬h₁.rank < h₂.rank
h✝² : ¬h₂.rank < h₁.rank
h✝¹ : ((combine le h₁ h₂).rank != hRank t₁) = true
h✝ : ¬((combine le h₁ h₂).rank != hRank t₂) = true
a✝ : IsBinTree h₂
lt : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
⊢ ry ≤ h₂.rank
Tactic:
apply le_of_lt lt
State after:
no goals

State before:
case inr.inr.inr.inl.hxs.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ¬h₁.rank < h₂.rank
h✝² : ¬h₂.rank < h₁.rank
h✝¹ : ¬((combine le h₁ h₂).rank != hRank t₁) = true
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = true
a✝ : IsBinTree h₁
lt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
⊢ IsHeapForest' rx t₁
Tactic:
have : rx ≤ h₁.rank := by
    apply le_of_lt lt
State after:
case inr.inr.inr.inl.hxs.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ¬h₁.rank < h₂.rank
h✝² : ¬h₂.rank < h₁.rank
h✝¹ : ¬((combine le h₁ h₂).rank != hRank t₁) = true
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = true
a✝ : IsBinTree h₁
lt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
this : rx ≤ h₁.rank
⊢ IsHeapForest' rx t₁

State before:
case inr.inr.inr.inl.hxs.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ¬h₁.rank < h₂.rank
h✝² : ¬h₂.rank < h₁.rank
h✝¹ : ¬((combine le h₁ h₂).rank != hRank t₁) = true
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = true
a✝ : IsBinTree h₁
lt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
this : rx ≤ h₁.rank
⊢ IsHeapForest' rx t₁
Tactic:
apply IsHeapForest'_weaken hf this
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ¬h₁.rank < h₂.rank
h✝² : ¬h₂.rank < h₁.rank
h✝¹ : ¬((combine le h₁ h₂).rank != hRank t₁) = true
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = true
a✝ : IsBinTree h₁
lt : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
⊢ rx ≤ h₁.rank
Tactic:
apply le_of_lt lt
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ((combine le h₁ h₂).rank != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₁) = false
⊢ h₁.rank = h₂.rank
Tactic:
apply Nat.le_antisymm <;> assumption
State after:
no goals

State before:
case inr.inr.inr.inl.hys.a.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
h✝³ : ¬h₁.rank < h₂.rank
h✝² : ¬h₂.rank < h₁.rank
h✝¹ : ¬((combine le h₁ h₂).rank != hRank t₁) = true
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = true
a✝² : IsBinTree h₁
a✝¹ : rx < h₁.rank
a✝ : IsHeapForest' h₁.rank t₁
⊢ IsBinTree (combine le h₁ h₂)
Tactic:
cases hys with | cons =>
  simp at *
  have : h₁.rank = h₂.rank := by
    apply Nat.le_antisymm <;> assumption
  apply combine_IsBinTree <;> assumption
State after:
no goals

State before:
case inr.inr.inr.inl.hys.a.cons.cons
α : Type u_1
le : α → α → Bool
not_le_le : ∀ (x y : α), ¬le x y = true → le y x = true
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
h✝³ : ¬h₁.rank < h₂.rank
h✝² : ¬h₂.rank < h₁.rank
h✝¹ : ¬((combine le h₁ h₂).rank != hRank t₁) = true
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = true
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
a✝³ : IsHeapForest' h₁.rank t₁
a✝² : IsBinTree h₂
a✝¹ : ry < h₂.rank
a✝ : IsHeapForest' h₂.rank t₂
⊢ IsBinTree (combine le h₁ h₂)
Tactic:
simp at *
State after:
case inr.inr.inr.inl.hys.a.cons.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
h✝³ : ((combine le h₁ h₂).rank != hRank t₂) = true
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
a✝³ : IsHeapForest' h₁.rank t₁
a✝² : IsBinTree h₂
a✝¹ : ry < h₂.rank
a✝ : IsHeapForest' h₂.rank t₂
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₁) = false
⊢ IsBinTree (combine le h₁ h₂)

State before:
case inr.inr.inr.inl.hys.a.cons.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
h✝³ : ((combine le h₁ h₂).rank != hRank t₂) = true
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
a✝³ : IsHeapForest' h₁.rank t₁
a✝² : IsBinTree h₂
a✝¹ : ry < h₂.rank
a✝ : IsHeapForest' h₂.rank t₂
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₁) = false
⊢ IsBinTree (combine le h₁ h₂)
Tactic:
have : h₁.rank = h₂.rank := by
  apply Nat.le_antisymm <;> assumption
State after:
case inr.inr.inr.inl.hys.a.cons.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
h✝³ : ((combine le h₁ h₂).rank != hRank t₂) = true
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
a✝³ : IsHeapForest' h₁.rank t₁
a✝² : IsBinTree h₂
a✝¹ : ry < h₂.rank
a✝ : IsHeapForest' h₂.rank t₂
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₁) = false
this : h₁.rank = h₂.rank
⊢ IsBinTree (combine le h₁ h₂)

State before:
case inr.inr.inr.inl.hys.a.cons.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
h✝³ : ((combine le h₁ h₂).rank != hRank t₂) = true
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
a✝³ : IsHeapForest' h₁.rank t₁
a✝² : IsBinTree h₂
a✝¹ : ry < h₂.rank
a✝ : IsHeapForest' h₂.rank t₂
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₁) = false
this : h₁.rank = h₂.rank
⊢ IsBinTree (combine le h₁ h₂)
Tactic:
apply combine_IsBinTree <;> assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
h✝³ : ((combine le h₁ h₂).rank != hRank t₂) = true
a✝⁵ : IsBinTree h₁
a✝⁴ : rx < h₁.rank
a✝³ : IsHeapForest' h₁.rank t₁
a✝² : IsBinTree h₂
a✝¹ : ry < h₂.rank
a✝ : IsHeapForest' h₂.rank t₂
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : ((combine le h₁ h₂).rank != hRank t₁) = false
⊢ h₁.rank = h₂.rank
Tactic:
apply Nat.le_antisymm <;> assumption
State after:
no goals

State before:
case inr.inr.inr.inl.hys.a.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
h✝³ : (h₁.rank + 1 != hRank t₂) = true
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝² : h₂.rank ≤ h₁.rank
h✝¹ : h₁.rank ≤ h₂.rank
h✝ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
⊢ IsHeapForest' (h₁.rank + 1) t₂
Tactic:
match hf with 
| .nil =>
  constructor
| .cons (t := t) (ts := ts) lt _ _ =>
  rw[← heq] at lt
  have b : h₁.rank + 1 ≤ t.rank := by
    apply Nat.succ_le_of_lt lt
  rw[hrank_of_cons] at *
  constructor
  . unfold bne at *
    rw[Nat.not_beq_eq_true_eq] at *
    apply lt_of_le_of_ne <;> assumption
  repeat assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
h✝ : (h₁.rank + 1 != hRank []) = true
⊢ IsHeapForest' (h₁.rank + 1) []
Tactic:
constructor
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₂.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ IsHeapForest' (h₁.rank + 1) (t :: ts)
Tactic:
rw[← heq] at lt
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ IsHeapForest' (h₁.rank + 1) (t :: ts)

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ IsHeapForest' (h₁.rank + 1) (t :: ts)
Tactic:
have b : h₁.rank + 1 ≤ t.rank := by
  apply Nat.succ_le_of_lt lt
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
b : h₁.rank + 1 ≤ t.rank
⊢ IsHeapForest' (h₁.rank + 1) (t :: ts)

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
b : h₁.rank + 1 ≤ t.rank
⊢ IsHeapForest' (h₁.rank + 1) (t :: ts)
Tactic:
rw[hrank_of_cons] at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != t.rank) = true
b : h₁.rank + 1 ≤ t.rank
⊢ IsHeapForest' (h₁.rank + 1) (t :: ts)

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != t.rank) = true
b : h₁.rank + 1 ≤ t.rank
⊢ IsHeapForest' (h₁.rank + 1) (t :: ts)
Tactic:
constructor
State after:
case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != t.rank) = true
b : h₁.rank + 1 ≤ t.rank
⊢ h₁.rank + 1 < t.rank

case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != t.rank) = true
b : h₁.rank + 1 ≤ t.rank
⊢ IsBinTree t

case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != t.rank) = true
b : h₁.rank + 1 ≤ t.rank
⊢ IsHeapForest' t.rank ts

State before:
case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != t.rank) = true
b : h₁.rank + 1 ≤ t.rank
⊢ h₁.rank + 1 < t.rank

case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != t.rank) = true
b : h₁.rank + 1 ≤ t.rank
⊢ IsBinTree t

case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != t.rank) = true
b : h₁.rank + 1 ≤ t.rank
⊢ IsHeapForest' t.rank ts
Tactic:
. unfold bne at *
  rw[Nat.not_beq_eq_true_eq] at *
  apply lt_of_le_of_ne <;> assumption
State after:
case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != t.rank) = true
b : h₁.rank + 1 ≤ t.rank
⊢ IsBinTree t

case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != t.rank) = true
b : h₁.rank + 1 ≤ t.rank
⊢ IsHeapForest' t.rank ts

State before:
case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != t.rank) = true
b : h₁.rank + 1 ≤ t.rank
⊢ IsBinTree t

case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != t.rank) = true
b : h₁.rank + 1 ≤ t.rank
⊢ IsHeapForest' t.rank ts
Tactic:
repeat assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != hRank (t :: ts)) = true
⊢ h₁.rank + 1 ≤ t.rank
Tactic:
apply Nat.succ_le_of_lt lt
State after:
no goals

State before:
case a
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₂
a✝² : ry < h₂.rank
hf : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
lt : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝ : (h₁.rank + 1 != t.rank) = true
b : h₁.rank + 1 ≤ t.rank
⊢ IsHeapForest' t.rank ts
Tactic:
assumption
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hxs : IsHeapForest' rx (h₁ :: t₁)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : ((combine le h₁ h₂).rank != hRank t₁) = false
h✝ : ((combine le h₁ h₂).rank != hRank t₂) = false
⊢ h₁.rank = h₂.rank
Tactic:
apply Nat.le_antisymm <;> assumption
State after:
no goals

State before:
case inr.inr.inr.inr.a.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
hys : IsHeapForest' ry (h₂ :: t₂)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
h✝ : (h₁.rank + 1 != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝¹ : IsBinTree h₁
a✝ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)
Tactic:
cases hys with | cons _ _ hf₂ =>
have ih := IsHeap_merge hf hf₂ 
have hle : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂) := by 
  rw[← heq] at hf₂
  apply min_hRank_mergeNodes hf hf₂
by_cases (t₁ = [] ∧ t₂ = [])
. have he₁ := h.left
  have he₂ := h.right
  simp[he₁, he₂]
  constructor
. apply IsHeapForest'_strengthen
  . apply ih
  . rw[Nat.min_eq] at hle
    split at hle
    . match hf₂ with
      | .nil =>
        rw[empty_heap_merge_right] at *
        match hf with
        | .nil =>
          contradiction
        | .cons (t := t) (ts := ts) _ _ _ =>
          rw[hrank_of_cons] at *
          unfold bne at *
          rw[Bool.not_eq_false', beq_iff_eq] at *
          simp at *
          contradiction
      | .cons (t := t) (ts := ts) _ _ _ => 
        match hf with
        | .nil => 
          rw[empty_heap_merge_left] at *
          rw[hrank_of_cons] at *
          unfold bne at *
          rw[Bool.not_eq_false', beq_iff_eq] at *
          simp at *
          contradiction
        | .cons (t := t₂) (ts := ts₂) _ _ _ =>
          repeat rw[hrank_of_cons] at *
          unfold bne at *
          rw[Bool.not_eq_false', beq_iff_eq] at *
          simp at *
          have ht₁ : IsHeapForest' h₁.rank (t₂ :: ts₂) := by
            apply IsHeapForest'_of_IsHeapForest' <;> assumption
          have ht₂ : IsHeapForest' h₁.rank (t :: ts) := by
            rw[← heq] at *
            apply IsHeapForest'_of_IsHeapForest' <;> assumption
          have : t₂.rank + 1 ≤ hRank (mergeNodes le (t₂ :: ts₂) (t :: ts)) := by
            apply hRank_mergeNodes_cons ht₁ ht₂
            simp_all
          rename_i heq₂ _
          rw[heq₂]
          apply Nat.lt_of_succ_le this
    . match hf₂ with
      | .nil =>
        rw[empty_heap_merge_right] at *
        cases hf
        . contradiction
        . rw[hrank_of_cons] at *
          unfold bne at *
          rw[Bool.not_eq_false', beq_iff_eq] at *
          simp at *
          contradiction
      | .cons (t := t) (ts := ts) _ _ _ =>
        rw[hrank_of_cons] at *
        unfold bne at *
        rw[Bool.not_eq_false', beq_iff_eq] at *
        simp at *
        match hf with
        | .nil =>
          contradiction
        | .cons (t := t₂) (ts := ts₂) _ _ _ =>
          rw[hrank_of_cons] at *
          simp at *
          have ht₁ : IsHeapForest' h₁.rank (t₂ :: ts₂) := by
            apply IsHeapForest'_of_IsHeapForest' <;> assumption
          have ht₂ : IsHeapForest' h₁.rank (t :: ts) := by
            rw[← heq] at *
            apply IsHeapForest'_of_IsHeapForest' <;> assumption
          have : t₂.rank + 1 ≤ hRank (mergeNodes le (t₂ :: ts₂) (t :: ts)) := by
            apply hRank_mergeNodes_cons ht₁ ht₂
            simp_all
          rename_i heq₂ _
          rw[heq₂]
          apply Nat.lt_of_succ_le this
State after:
no goals

State before:
case inr.inr.inr.inr.a.cons.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
h✝ : (h₁.rank + 1 != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)
Tactic:
have ih := IsHeap_merge hf hf₂
State after:
case inr.inr.inr.inr.a.cons.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
h✝ : (h₁.rank + 1 != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)

State before:
case inr.inr.inr.inr.a.cons.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
h✝ : (h₁.rank + 1 != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)
Tactic:
have hle : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂) := by 
  rw[← heq] at hf₂
  apply min_hRank_mergeNodes hf hf₂
State after:
case inr.inr.inr.inr.a.cons.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
h✝ : (h₁.rank + 1 != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
hle : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)

State before:
case inr.inr.inr.inr.a.cons.cons
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
h✝ : (h₁.rank + 1 != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
hle : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)
Tactic:
by_cases (t₁ = [] ∧ t₂ = [])
State after:
case pos
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
h✝ : (h₁.rank + 1 != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
hle : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
h : t₁ = [] ∧ t₂ = []
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)

case neg
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
h✝ : (h₁.rank + 1 != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
hle : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
h : ¬(t₁ = [] ∧ t₂ = [])
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)

State before:
case pos
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
h✝ : (h₁.rank + 1 != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
hle : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
h : t₁ = [] ∧ t₂ = []
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)

case neg
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
h✝ : (h₁.rank + 1 != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
hle : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
h : ¬(t₁ = [] ∧ t₂ = [])
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)
Tactic:
. have he₁ := h.left
  have he₂ := h.right
  simp[he₁, he₂]
  constructor
State after:
case neg
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
h✝ : (h₁.rank + 1 != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
hle : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
h : ¬(t₁ = [] ∧ t₂ = [])
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)

State before:
case neg
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
h✝ : (h₁.rank + 1 != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
hle : min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
h : ¬(t₁ = [] ∧ t₂ = [])
⊢ IsHeapForest' (h₁.rank + 1) (mergeNodes le t₁ t₂)
Tactic:
. apply IsHeapForest'_strengthen
  . apply ih
  . rw[Nat.min_eq] at hle
    split at hle
    . match hf₂ with
      | .nil =>
        rw[empty_heap_merge_right] at *
        match hf with
        | .nil =>
          contradiction
        | .cons (t := t) (ts := ts) _ _ _ =>
          rw[hrank_of_cons] at *
          unfold bne at *
          rw[Bool.not_eq_false', beq_iff_eq] at *
          simp at *
          contradiction
      | .cons (t := t) (ts := ts) _ _ _ => 
        match hf with
        | .nil => 
          rw[empty_heap_merge_left] at *
          rw[hrank_of_cons] at *
          unfold bne at *
          rw[Bool.not_eq_false', beq_iff_eq] at *
          simp at *
          contradiction
        | .cons (t := t₂) (ts := ts₂) _ _ _ =>
          repeat rw[hrank_of_cons] at *
          unfold bne at *
          rw[Bool.not_eq_false', beq_iff_eq] at *
          simp at *
          have ht₁ : IsHeapForest' h₁.rank (t₂ :: ts₂) := by
            apply IsHeapForest'_of_IsHeapForest' <;> assumption
          have ht₂ : IsHeapForest' h₁.rank (t :: ts) := by
            rw[← heq] at *
            apply IsHeapForest'_of_IsHeapForest' <;> assumption
          have : t₂.rank + 1 ≤ hRank (mergeNodes le (t₂ :: ts₂) (t :: ts)) := by
            apply hRank_mergeNodes_cons ht₁ ht₂
            simp_all
          rename_i heq₂ _
          rw[heq₂]
          apply Nat.lt_of_succ_le this
    . match hf₂ with
      | .nil =>
        rw[empty_heap_merge_right] at *
        cases hf
        . contradiction
        . rw[hrank_of_cons] at *
          unfold bne at *
          rw[Bool.not_eq_false', beq_iff_eq] at *
          simp at *
          contradiction
      | .cons (t := t) (ts := ts) _ _ _ =>
        rw[hrank_of_cons] at *
        unfold bne at *
        rw[Bool.not_eq_false', beq_iff_eq] at *
        simp at *
        match hf with
        | .nil =>
          contradiction
        | .cons (t := t₂) (ts := ts₂) _ _ _ =>
          rw[hrank_of_cons] at *
          simp at *
          have ht₁ : IsHeapForest' h₁.rank (t₂ :: ts₂) := by
            apply IsHeapForest'_of_IsHeapForest' <;> assumption
          have ht₂ : IsHeapForest' h₁.rank (t :: ts) := by
            rw[← heq] at *
            apply IsHeapForest'_of_IsHeapForest' <;> assumption
          have : t₂.rank + 1 ≤ hRank (mergeNodes le (t₂ :: ts₂) (t :: ts)) := by
            apply hRank_mergeNodes_cons ht₁ ht₂
            simp_all
          rename_i heq₂ _
          rw[heq₂]
          apply Nat.lt_of_succ_le this
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
h✝ : (h₁.rank + 1 != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
⊢ min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
Tactic:
rw[← heq] at hf₂
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
h✝ : (h₁.rank + 1 != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₁.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
⊢ min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝³ : h₂.rank ≤ h₁.rank
h✝² : h₁.rank ≤ h₂.rank
h✝¹ : (h₁.rank + 1 != hRank t₁) = false
h✝ : (h₁.rank + 1 != hRank t₂) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₁.rank t₂
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ t₂)
⊢ min (hRank t₁) (hRank t₂) ≤ hRank (mergeNodes le t₁ t₂)
Tactic:
apply min_hRank_mergeNodes hf hf₂
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
h✝² : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
h✝¹ : (h₁.rank + 1 != hRank []) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ [])
h : ¬(t₁ = [] ∧ [] = [])
h✝ : hRank t₁ ≤ hRank []
hle : hRank t₁ ≤ hRank (mergeNodes le t₁ [])
⊢ h₁.rank + 1 < hRank (mergeNodes le t₁ [])
Tactic:
rw[empty_heap_merge_right] at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
h✝² : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
h✝¹ : (h₁.rank + 1 != hRank []) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) t₁
h : ¬(t₁ = [] ∧ [] = [])
h✝ : hRank t₁ ≤ hRank []
hle : hRank t₁ ≤ hRank t₁
⊢ h₁.rank + 1 < hRank t₁

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
h✝² : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
h✝¹ : (h₁.rank + 1 != hRank []) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) t₁
h : ¬(t₁ = [] ∧ [] = [])
h✝ : hRank t₁ ≤ hRank []
hle : hRank t₁ ≤ hRank t₁
⊢ h₁.rank + 1 < hRank t₁
Tactic:
match hf with
| .nil =>
  contradiction
| .cons (t := t) (ts := ts) _ _ _ =>
  rw[hrank_of_cons] at *
  unfold bne at *
  rw[Bool.not_eq_false', beq_iff_eq] at *
  simp at *
  contradiction
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝³ : IsBinTree h₁
a✝² : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝¹ : IsBinTree h₂
a✝ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
h✝² h✝¹ : (h₁.rank + 1 != hRank []) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) []
h : ¬([] = [] ∧ [] = [])
h✝ hle : hRank [] ≤ hRank []
⊢ h₁.rank + 1 < hRank []
Tactic:
contradiction
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
h✝² : (h₁.rank + 1 != hRank []) = false
t : BinTree α
ts : List (BinTree α)
a✝² : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝¹ : (h₁.rank + 1 != hRank (t :: ts)) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : hRank (t :: ts) ≤ hRank []
hle : hRank (t :: ts) ≤ hRank (t :: ts)
⊢ h₁.rank + 1 < hRank (t :: ts)
Tactic:
rw[hrank_of_cons] at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
h✝² : (h₁.rank + 1 != hRank []) = false
t : BinTree α
ts : List (BinTree α)
a✝² : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝¹ : (h₁.rank + 1 != t.rank) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : t.rank ≤ hRank []
hle : t.rank ≤ t.rank
⊢ h₁.rank + 1 < t.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
h✝² : (h₁.rank + 1 != hRank []) = false
t : BinTree α
ts : List (BinTree α)
a✝² : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝¹ : (h₁.rank + 1 != t.rank) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : t.rank ≤ hRank []
hle : t.rank ≤ t.rank
⊢ h₁.rank + 1 < t.rank
Tactic:
unfold bne at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
h✝² : (!h₁.rank + 1 == hRank []) = false
t : BinTree α
ts : List (BinTree α)
a✝² : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝¹ : (!h₁.rank + 1 == t.rank) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : t.rank ≤ hRank []
hle : t.rank ≤ t.rank
⊢ h₁.rank + 1 < t.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
h✝² : (!h₁.rank + 1 == hRank []) = false
t : BinTree α
ts : List (BinTree α)
a✝² : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝¹ : (!h₁.rank + 1 == t.rank) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : t.rank ≤ hRank []
hle : t.rank ≤ t.rank
⊢ h₁.rank + 1 < t.rank
Tactic:
rw[Bool.not_eq_false', beq_iff_eq] at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
h✝² : h₁.rank + 1 = hRank []
t : BinTree α
ts : List (BinTree α)
a✝² : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝¹ : h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : t.rank ≤ hRank []
hle : t.rank ≤ t.rank
⊢ h₁.rank + 1 < t.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
h✝² : h₁.rank + 1 = hRank []
t : BinTree α
ts : List (BinTree α)
a✝² : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝¹ : h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬(t :: ts = [] ∧ [] = [])
h✝ : t.rank ≤ hRank []
hle : t.rank ≤ t.rank
⊢ h₁.rank + 1 < t.rank
Tactic:
simp at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
h✝² : h₁.rank + 1 = hRank []
t : BinTree α
ts : List (BinTree α)
a✝² : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝¹ : h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h✝ : t.rank ≤ hRank []
h hle : True
⊢ h₁.rank + 1 < t.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
h✝² : h₁.rank + 1 = hRank []
t : BinTree α
ts : List (BinTree α)
a✝² : h₁.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝¹ : h₁.rank + 1 = t.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h✝ : t.rank ≤ hRank []
h hle : True
⊢ h₁.rank + 1 < t.rank
Tactic:
contradiction
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
h✝² : (h₁.rank + 1 != hRank t₁) = false
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
a✝² : h₂.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝¹ : (h₁.rank + 1 != hRank (t :: ts)) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le t₁ (t :: ts))
h : ¬(t₁ = [] ∧ t :: ts = [])
h✝ : hRank t₁ ≤ hRank (t :: ts)
hle : hRank t₁ ≤ hRank (mergeNodes le t₁ (t :: ts))
⊢ h₁.rank + 1 < hRank (mergeNodes le t₁ (t :: ts))
Tactic:
match hf with
| .nil => 
  rw[empty_heap_merge_left] at *
  rw[hrank_of_cons] at *
  unfold bne at *
  rw[Bool.not_eq_false', beq_iff_eq] at *
  simp at *
  contradiction
| .cons (t := t₂) (ts := ts₂) _ _ _ =>
  repeat rw[hrank_of_cons] at *
  unfold bne at *
  rw[Bool.not_eq_false', beq_iff_eq] at *
  simp at *
  have ht₁ : IsHeapForest' h₁.rank (t₂ :: ts₂) := by
    apply IsHeapForest'_of_IsHeapForest' <;> assumption
  have ht₂ : IsHeapForest' h₁.rank (t :: ts) := by
    rw[← heq] at *
    apply IsHeapForest'_of_IsHeapForest' <;> assumption
  have : t₂.rank + 1 ≤ hRank (mergeNodes le (t₂ :: ts₂) (t :: ts)) := by
    apply hRank_mergeNodes_cons ht₁ ht₂
    simp_all
  rename_i heq₂ _
  rw[heq₂]
  apply Nat.lt_of_succ_le this
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
a✝² : h₂.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝² : (h₁.rank + 1 != hRank (t :: ts)) = false
h✝¹ : (h₁.rank + 1 != hRank []) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le [] (t :: ts))
h : ¬([] = [] ∧ t :: ts = [])
h✝ : hRank [] ≤ hRank (t :: ts)
hle : hRank [] ≤ hRank (mergeNodes le [] (t :: ts))
⊢ h₁.rank + 1 < hRank (mergeNodes le [] (t :: ts))
Tactic:
rw[empty_heap_merge_left] at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
a✝² : h₂.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝² : (h₁.rank + 1 != hRank (t :: ts)) = false
h✝¹ : (h₁.rank + 1 != hRank []) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬([] = [] ∧ t :: ts = [])
h✝ hle : hRank [] ≤ hRank (t :: ts)
⊢ h₁.rank + 1 < hRank (t :: ts)

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
a✝² : h₂.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝² : (h₁.rank + 1 != hRank (t :: ts)) = false
h✝¹ : (h₁.rank + 1 != hRank []) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬([] = [] ∧ t :: ts = [])
h✝ hle : hRank [] ≤ hRank (t :: ts)
⊢ h₁.rank + 1 < hRank (t :: ts)
Tactic:
rw[hrank_of_cons] at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
a✝² : h₂.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝² : (h₁.rank + 1 != t.rank) = false
h✝¹ : (h₁.rank + 1 != hRank []) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬([] = [] ∧ t :: ts = [])
h✝ hle : hRank [] ≤ t.rank
⊢ h₁.rank + 1 < t.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
a✝² : h₂.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝² : (h₁.rank + 1 != t.rank) = false
h✝¹ : (h₁.rank + 1 != hRank []) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬([] = [] ∧ t :: ts = [])
h✝ hle : hRank [] ≤ t.rank
⊢ h₁.rank + 1 < t.rank
Tactic:
unfold bne at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
a✝² : h₂.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝² : (!h₁.rank + 1 == t.rank) = false
h✝¹ : (!h₁.rank + 1 == hRank []) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬([] = [] ∧ t :: ts = [])
h✝ hle : hRank [] ≤ t.rank
⊢ h₁.rank + 1 < t.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
a✝² : h₂.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝² : (!h₁.rank + 1 == t.rank) = false
h✝¹ : (!h₁.rank + 1 == hRank []) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬([] = [] ∧ t :: ts = [])
h✝ hle : hRank [] ≤ t.rank
⊢ h₁.rank + 1 < t.rank
Tactic:
rw[Bool.not_eq_false', beq_iff_eq] at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
a✝² : h₂.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝² : h₁.rank + 1 = t.rank
h✝¹ : h₁.rank + 1 = hRank []
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬([] = [] ∧ t :: ts = [])
h✝ hle : hRank [] ≤ t.rank
⊢ h₁.rank + 1 < t.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
a✝² : h₂.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝² : h₁.rank + 1 = t.rank
h✝¹ : h₁.rank + 1 = hRank []
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h : ¬([] = [] ∧ t :: ts = [])
h✝ hle : hRank [] ≤ t.rank
⊢ h₁.rank + 1 < t.rank
Tactic:
simp at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
a✝² : h₂.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝² : h₁.rank + 1 = t.rank
h✝¹ : h₁.rank + 1 = hRank []
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h✝ hle : hRank [] ≤ t.rank
h : True
⊢ h₁.rank + 1 < t.rank

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁶ : IsBinTree h₁
a✝⁵ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁴ : IsBinTree h₂
a✝³ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂
t : BinTree α
ts : List (BinTree α)
a✝² : h₂.rank < t.rank
a✝¹ : IsBinTree t
a✝ : IsHeapForest' t.rank ts
h✝² : h₁.rank + 1 = t.rank
h✝¹ : h₁.rank + 1 = hRank []
ih : IsHeapForest' (min h₁.rank h₂.rank) (t :: ts)
h✝ hle : hRank [] ≤ t.rank
h : True
⊢ h₁.rank + 1 < t.rank
Tactic:
contradiction
State after:
no goals

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂✝ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁹ : IsBinTree h₁
a✝⁸ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁷ : IsBinTree h₂
a✝⁶ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂✝
t : BinTree α
ts : List (BinTree α)
a✝⁵ : h₂.rank < t.rank
a✝⁴ : IsBinTree t
a✝³ : IsHeapForest' t.rank ts
h✝² : (h₁.rank + 1 != hRank (t :: ts)) = false
t₂ : BinTree α
ts₂ : List (BinTree α)
a✝² : h₁.rank < t₂.rank
a✝¹ : IsBinTree t₂
a✝ : IsHeapForest' t₂.rank ts₂
h✝¹ : (h₁.rank + 1 != hRank (t₂ :: ts₂)) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t₂ :: ts₂) (t :: ts))
h : ¬(t₂ :: ts₂ = [] ∧ t :: ts = [])
h✝ : hRank (t₂ :: ts₂) ≤ hRank (t :: ts)
hle : hRank (t₂ :: ts₂) ≤ hRank (mergeNodes le (t₂ :: ts₂) (t :: ts))
⊢ h₁.rank + 1 < hRank (mergeNodes le (t₂ :: ts₂) (t :: ts))
Tactic:
repeat rw[hrank_of_cons] at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂✝ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁹ : IsBinTree h₁
a✝⁸ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁷ : IsBinTree h₂
a✝⁶ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂✝
t : BinTree α
ts : List (BinTree α)
a✝⁵ : h₂.rank < t.rank
a✝⁴ : IsBinTree t
a✝³ : IsHeapForest' t.rank ts
h✝² : (h₁.rank + 1 != t.rank) = false
t₂ : BinTree α
ts₂ : List (BinTree α)
a✝² : h₁.rank < t₂.rank
a✝¹ : IsBinTree t₂
a✝ : IsHeapForest' t₂.rank ts₂
h✝¹ : (h₁.rank + 1 != t₂.rank) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t₂ :: ts₂) (t :: ts))
h : ¬(t₂ :: ts₂ = [] ∧ t :: ts = [])
h✝ : t₂.rank ≤ t.rank
hle : t₂.rank ≤ hRank (mergeNodes le (t₂ :: ts₂) (t :: ts))
⊢ h₁.rank + 1 < hRank (mergeNodes le (t₂ :: ts₂) (t :: ts))

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂✝ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁹ : IsBinTree h₁
a✝⁸ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁷ : IsBinTree h₂
a✝⁶ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂✝
t : BinTree α
ts : List (BinTree α)
a✝⁵ : h₂.rank < t.rank
a✝⁴ : IsBinTree t
a✝³ : IsHeapForest' t.rank ts
h✝² : (h₁.rank + 1 != t.rank) = false
t₂ : BinTree α
ts₂ : List (BinTree α)
a✝² : h₁.rank < t₂.rank
a✝¹ : IsBinTree t₂
a✝ : IsHeapForest' t₂.rank ts₂
h✝¹ : (h₁.rank + 1 != t₂.rank) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t₂ :: ts₂) (t :: ts))
h : ¬(t₂ :: ts₂ = [] ∧ t :: ts = [])
h✝ : t₂.rank ≤ t.rank
hle : t₂.rank ≤ hRank (mergeNodes le (t₂ :: ts₂) (t :: ts))
⊢ h₁.rank + 1 < hRank (mergeNodes le (t₂ :: ts₂) (t :: ts))
Tactic:
unfold bne at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂✝ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁹ : IsBinTree h₁
a✝⁸ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁷ : IsBinTree h₂
a✝⁶ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂✝
t : BinTree α
ts : List (BinTree α)
a✝⁵ : h₂.rank < t.rank
a✝⁴ : IsBinTree t
a✝³ : IsHeapForest' t.rank ts
h✝² : (!h₁.rank + 1 == t.rank) = false
t₂ : BinTree α
ts₂ : List (BinTree α)
a✝² : h₁.rank < t₂.rank
a✝¹ : IsBinTree t₂
a✝ : IsHeapForest' t₂.rank ts₂
h✝¹ : (!h₁.rank + 1 == t₂.rank) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t₂ :: ts₂) (t :: ts))
h : ¬(t₂ :: ts₂ = [] ∧ t :: ts = [])
h✝ : t₂.rank ≤ t.rank
hle : t₂.rank ≤ hRank (mergeNodes le (t₂ :: ts₂) (t :: ts))
⊢ h₁.rank + 1 < hRank (mergeNodes le (t₂ :: ts₂) (t :: ts))

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂✝ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁹ : IsBinTree h₁
a✝⁸ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁷ : IsBinTree h₂
a✝⁶ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂✝
t : BinTree α
ts : List (BinTree α)
a✝⁵ : h₂.rank < t.rank
a✝⁴ : IsBinTree t
a✝³ : IsHeapForest' t.rank ts
h✝² : (!h₁.rank + 1 == t.rank) = false
t₂ : BinTree α
ts₂ : List (BinTree α)
a✝² : h₁.rank < t₂.rank
a✝¹ : IsBinTree t₂
a✝ : IsHeapForest' t₂.rank ts₂
h✝¹ : (!h₁.rank + 1 == t₂.rank) = false
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t₂ :: ts₂) (t :: ts))
h : ¬(t₂ :: ts₂ = [] ∧ t :: ts = [])
h✝ : t₂.rank ≤ t.rank
hle : t₂.rank ≤ hRank (mergeNodes le (t₂ :: ts₂) (t :: ts))
⊢ h₁.rank + 1 < hRank (mergeNodes le (t₂ :: ts₂) (t :: ts))
Tactic:
rw[Bool.not_eq_false', beq_iff_eq] at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂✝ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁹ : IsBinTree h₁
a✝⁸ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁷ : IsBinTree h₂
a✝⁶ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂✝
t : BinTree α
ts : List (BinTree α)
a✝⁵ : h₂.rank < t.rank
a✝⁴ : IsBinTree t
a✝³ : IsHeapForest' t.rank ts
h✝² : h₁.rank + 1 = t.rank
t₂ : BinTree α
ts₂ : List (BinTree α)
a✝² : h₁.rank < t₂.rank
a✝¹ : IsBinTree t₂
a✝ : IsHeapForest' t₂.rank ts₂
h✝¹ : h₁.rank + 1 = t₂.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t₂ :: ts₂) (t :: ts))
h : ¬(t₂ :: ts₂ = [] ∧ t :: ts = [])
h✝ : t₂.rank ≤ t.rank
hle : t₂.rank ≤ hRank (mergeNodes le (t₂ :: ts₂) (t :: ts))
⊢ h₁.rank + 1 < hRank (mergeNodes le (t₂ :: ts₂) (t :: ts))

State before:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂✝ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁹ : IsBinTree h₁
a✝⁸ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁷ : IsBinTree h₂
a✝⁶ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂✝
t : BinTree α
ts : List (BinTree α)
a✝⁵ : h₂.rank < t.rank
a✝⁴ : IsBinTree t
a✝³ : IsHeapForest' t.rank ts
h✝² : h₁.rank + 1 = t.rank
t₂ : BinTree α
ts₂ : List (BinTree α)
a✝² : h₁.rank < t₂.rank
a✝¹ : IsBinTree t₂
a✝ : IsHeapForest' t₂.rank ts₂
h✝¹ : h₁.rank + 1 = t₂.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t₂ :: ts₂) (t :: ts))
h : ¬(t₂ :: ts₂ = [] ∧ t :: ts = [])
h✝ : t₂.rank ≤ t.rank
hle : t₂.rank ≤ hRank (mergeNodes le (t₂ :: ts₂) (t :: ts))
⊢ h₁.rank + 1 < hRank (mergeNodes le (t₂ :: ts₂) (t :: ts))
Tactic:
simp at *
State after:
α : Type u_1
le : α → α → Bool
rx : ℕ
xs : List (BinTree α)
ry : ℕ
ys : List (BinTree α)
h₁ : BinTree α
t₁ : List (BinTree α)
h₂ : BinTree α
t₂✝ : List (BinTree α)
not_le_le : ∀ (x y : α), le x y = false → le y x = true
h✝⁴ : h₂.rank ≤ h₁.rank
h✝³ : h₁.rank ≤ h₂.rank
heq : h₁.rank = h₂.rank
a✝⁹ : IsBinTree h₁
a✝⁸ : rx < h₁.rank
hf : IsHeapForest' h₁.rank t₁
a✝⁷ : IsBinTree h₂
a✝⁶ : ry < h₂.rank
hf₂ : IsHeapForest' h₂.rank t₂✝
t : BinTree α
ts : List (BinTree α)
a✝⁵ : h₂.rank < t.rank
a✝⁴ : IsBinTree t
a✝³ : IsHeapForest' t.rank ts
h✝² : h₁.rank + 1 = t.rank
t₂ : BinTree α
ts₂ : List (BinTree α)
a✝² : h₁.rank < t₂.rank
a✝¹ : IsBinTree t₂
a✝ : IsHeapForest' t₂.rank ts₂
h✝¹ : h₁.rank + 1 = t₂.rank
ih : IsHeapForest' (min h₁.rank h₂.rank) (mergeNodes le (t₂ :: ts₂) (t :: ts))
h✝ : t₂.rank ≤ t.rank
hle : t₂.rank ≤ hRank (mergeNodes le (t₂ :: ts₂) (t :: ts))
h : True
⊢ h₁.rank + 1 < hRank (mergeNodes le (t₂ :: ts₂) (t :: ts))