Theorem: Nat.Linear.Poly.of_denote_eq_cancelAux
File: src/lean/Init/Data/Nat/Linear.lean

tactic: assumption
state_before: case zero
ctx : Context
m₁ m₂ r₁ r₂ : Poly
h : denote_eq ctx (cancelAux zero m₁ m₂ r₁ r₂)
⊢ denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)

tactic: simp at h
state_before: case succ
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
m₁ m₂ r₁ r₂ : Poly
h : denote_eq ctx (cancelAux (succ fuel) m₁ m₂ r₁ r₂)
⊢ denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)

tactic: split at h <;> simp <;> try assumption
state_before: case succ
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
m₁ m₂ r₁ r₂ : Poly
h :
  denote_eq ctx
    (match m₁, m₂ with
    | m₁, [] => (List.reverse r₁ ++ m₁, List.reverse r₂)
    | [], m₂ => (List.reverse r₁, List.reverse r₂ ++ m₂)
    | (k₁, v₁) :: m₁, (k₂, v₂) :: m₂ =>
      bif blt v₁ v₂ then cancelAux fuel m₁ ((k₂, v₂) :: m₂) ((k₁, v₁) :: r₁) r₂
      else
        bif blt v₂ v₁ then cancelAux fuel ((k₁, v₁) :: m₁) m₂ r₁ ((k₂, v₂) :: r₂)
        else
          bif blt k₁ k₂ then cancelAux fuel m₁ m₂ r₁ ((k₂ - k₁, v₁) :: r₂)
          else bif blt k₂ k₁ then cancelAux fuel m₁ m₂ ((k₁ - k₂, v₁) :: r₁) r₂ else cancelAux fuel m₁ m₂ r₁ r₂)
⊢ denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)

tactic: rename_i k₁ v₁ m₁ k₂ v₂ m₂
state_before: case succ.h_3
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝¹ m₂✝¹ : Poly
k₁✝ : Nat
v₁✝ : Var
m₁✝ : List (Nat × Var)
k₂✝ : Nat
v₂✝ : Var
m₂✝ : List (Nat × Var)
h :
  denote_eq ctx
    (bif blt v₁✝ v₂✝ then cancelAux fuel m₁✝ ((k₂✝, v₂✝) :: m₂✝) ((k₁✝, v₁✝) :: r₁) r₂
    else
      bif blt v₂✝ v₁✝ then cancelAux fuel ((k₁✝, v₁✝) :: m₁✝) m₂✝ r₁ ((k₂✝, v₂✝) :: r₂)
      else
        bif blt k₁✝ k₂✝ then cancelAux fuel m₁✝ m₂✝ r₁ ((k₂✝ - k₁✝, v₁✝) :: r₂)
        else bif blt k₂✝ k₁✝ then cancelAux fuel m₁✝ m₂✝ ((k₁✝ - k₂✝, v₁✝) :: r₁) r₂ else cancelAux fuel m₁✝ m₂✝ r₁ r₂)
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁✝, v₁✝) :: m₁✝, List.reverse r₂ ++ (k₂✝, v₂✝) :: m₂✝)

tactic: by_cases hltv : Nat.blt v₁ v₂ <;> simp [hltv] at h
state_before: case succ.h_3
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
v₂ : Var
m₂ : List (Nat × Var)
h :
  denote_eq ctx
    (bif blt v₁ v₂ then cancelAux fuel m₁ ((k₂, v₂) :: m₂) ((k₁, v₁) :: r₁) r₂
    else
      bif blt v₂ v₁ then cancelAux fuel ((k₁, v₁) :: m₁) m₂ r₁ ((k₂, v₂) :: r₂)
      else
        bif blt k₁ k₂ then cancelAux fuel m₁ m₂ r₁ ((k₂ - k₁, v₁) :: r₂)
        else bif blt k₂ k₁ then cancelAux fuel m₁ m₂ ((k₁ - k₂, v₁) :: r₁) r₂ else cancelAux fuel m₁ m₂ r₁ r₂)
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₂, v₂) :: m₂)

tactic: assumption
state_before: case succ.h_3
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝¹ m₂✝¹ : Poly
k₁✝ : Nat
v₁✝ : Var
m₁✝ : List (Nat × Var)
k₂✝ : Nat
v₂✝ : Var
m₂✝ : List (Nat × Var)
h :
  denote_eq ctx
    (bif blt v₁✝ v₂✝ then cancelAux fuel m₁✝ ((k₂✝, v₂✝) :: m₂✝) ((k₁✝, v₁✝) :: r₁) r₂
    else
      bif blt v₂✝ v₁✝ then cancelAux fuel ((k₁✝, v₁✝) :: m₁✝) m₂✝ r₁ ((k₂✝, v₂✝) :: r₂)
      else
        bif blt k₁✝ k₂✝ then cancelAux fuel m₁✝ m₂✝ r₁ ((k₂✝ - k₁✝, v₁✝) :: r₂)
        else bif blt k₂✝ k₁✝ then cancelAux fuel m₁✝ m₂✝ ((k₁✝ - k₂✝, v₁✝) :: r₁) r₂ else cancelAux fuel m₁✝ m₂✝ r₁ r₂)
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁✝, v₁✝) :: m₁✝, List.reverse r₂ ++ (k₂✝, v₂✝) :: m₂✝)

tactic: have ih := ih (h := h)
state_before: case succ.h_3.inl
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
v₂ : Var
m₂ : List (Nat × Var)
hltv : blt v₁ v₂ = true
h : denote_eq ctx (cancelAux fuel m₁ ((k₂, v₂) :: m₂) ((k₁, v₁) :: r₁) r₂)
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₂, v₂) :: m₂)

tactic: simp [denote_eq] at ih ⊢
state_before: case succ.h_3.inl
ctx : Context
fuel : Nat
ih✝ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
v₂ : Var
m₂ : List (Nat × Var)
hltv : blt v₁ v₂ = true
h : denote_eq ctx (cancelAux fuel m₁ ((k₂, v₂) :: m₂) ((k₁, v₁) :: r₁) r₂)
ih : denote_eq ctx (List.reverse ((k₁, v₁) :: r₁) ++ m₁, List.reverse r₂ ++ (k₂, v₂) :: m₂)
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₂, v₂) :: m₂)

tactic: assumption
state_before: case succ.h_3.inl
ctx : Context
fuel : Nat
ih✝ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
v₂ : Var
m₂ : List (Nat × Var)
hltv : blt v₁ v₂ = true
h : denote_eq ctx (cancelAux fuel m₁ ((k₂, v₂) :: m₂) ((k₁, v₁) :: r₁) r₂)
ih : denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁) = denote ctx r₂ + (denote ctx m₂ + k₂ * Var.denote ctx v₂)
⊢ denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁) = denote ctx r₂ + (denote ctx m₂ + k₂ * Var.denote ctx v₂)

tactic: by_cases hgtv : Nat.blt v₂ v₁ <;> simp [hgtv] at h
state_before: case succ.h_3.inr
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
v₂ : Var
m₂ : List (Nat × Var)
hltv : ¬blt v₁ v₂ = true
h :
  denote_eq ctx
    (bif blt v₂ v₁ then cancelAux fuel ((k₁, v₁) :: m₁) m₂ r₁ ((k₂, v₂) :: r₂)
    else
      bif blt k₁ k₂ then cancelAux fuel m₁ m₂ r₁ ((k₂ - k₁, v₁) :: r₂)
      else bif blt k₂ k₁ then cancelAux fuel m₁ m₂ ((k₁ - k₂, v₁) :: r₁) r₂ else cancelAux fuel m₁ m₂ r₁ r₂)
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₂, v₂) :: m₂)

tactic: have ih := ih (h := h)
state_before: case succ.h_3.inr.inl
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
v₂ : Var
m₂ : List (Nat × Var)
hltv : ¬blt v₁ v₂ = true
hgtv : blt v₂ v₁ = true
h : denote_eq ctx (cancelAux fuel ((k₁, v₁) :: m₁) m₂ r₁ ((k₂, v₂) :: r₂))
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₂, v₂) :: m₂)

tactic: simp [denote_eq] at ih ⊢
state_before: case succ.h_3.inr.inl
ctx : Context
fuel : Nat
ih✝ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
v₂ : Var
m₂ : List (Nat × Var)
hltv : ¬blt v₁ v₂ = true
hgtv : blt v₂ v₁ = true
h : denote_eq ctx (cancelAux fuel ((k₁, v₁) :: m₁) m₂ r₁ ((k₂, v₂) :: r₂))
ih : denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse ((k₂, v₂) :: r₂) ++ m₂)
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₂, v₂) :: m₂)

tactic: assumption
state_before: case succ.h_3.inr.inl
ctx : Context
fuel : Nat
ih✝ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
v₂ : Var
m₂ : List (Nat × Var)
hltv : ¬blt v₁ v₂ = true
hgtv : blt v₂ v₁ = true
h : denote_eq ctx (cancelAux fuel ((k₁, v₁) :: m₁) m₂ r₁ ((k₂, v₂) :: r₂))
ih : denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁) = denote ctx r₂ + (denote ctx m₂ + k₂ * Var.denote ctx v₂)
⊢ denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁) = denote ctx r₂ + (denote ctx m₂ + k₂ * Var.denote ctx v₂)

tactic: have heqv : v₁ = v₂ := eq_of_not_blt_eq_true hltv hgtv
state_before: case succ.h_3.inr.inr
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
v₂ : Var
m₂ : List (Nat × Var)
hltv : ¬blt v₁ v₂ = true
hgtv : ¬blt v₂ v₁ = true
h :
  denote_eq ctx
    (bif blt k₁ k₂ then cancelAux fuel m₁ m₂ r₁ ((k₂ - k₁, v₁) :: r₂)
    else bif blt k₂ k₁ then cancelAux fuel m₁ m₂ ((k₁ - k₂, v₁) :: r₁) r₂ else cancelAux fuel m₁ m₂ r₁ r₂)
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₂, v₂) :: m₂)

tactic: subst heqv
state_before: case succ.h_3.inr.inr
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
v₂ : Var
m₂ : List (Nat × Var)
hltv : ¬blt v₁ v₂ = true
hgtv : ¬blt v₂ v₁ = true
h :
  denote_eq ctx
    (bif blt k₁ k₂ then cancelAux fuel m₁ m₂ r₁ ((k₂ - k₁, v₁) :: r₂)
    else bif blt k₂ k₁ then cancelAux fuel m₁ m₂ ((k₁ - k₂, v₁) :: r₁) r₂ else cancelAux fuel m₁ m₂ r₁ r₂)
heqv : v₁ = v₂
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₂, v₂) :: m₂)

tactic: by_cases hltk : Nat.blt k₁ k₂ <;> simp [hltk] at h
state_before: case succ.h_3.inr.inr
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
h :
  denote_eq ctx
    (bif blt k₁ k₂ then cancelAux fuel m₁ m₂ r₁ ((k₂ - k₁, v₁) :: r₂)
    else bif blt k₂ k₁ then cancelAux fuel m₁ m₂ ((k₁ - k₂, v₁) :: r₁) r₂ else cancelAux fuel m₁ m₂ r₁ r₂)
hltv hgtv : ¬blt v₁ v₁ = true
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₂, v₁) :: m₂)

tactic: have ih := ih (h := h)
state_before: case succ.h_3.inr.inr.inl
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : blt k₁ k₂ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ r₁ ((k₂ - k₁, v₁) :: r₂))
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₂, v₁) :: m₂)

tactic: simp [denote_eq] at ih ⊢
state_before: case succ.h_3.inr.inr.inl
ctx : Context
fuel : Nat
ih✝ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : blt k₁ k₂ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ r₁ ((k₂ - k₁, v₁) :: r₂))
ih : denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse ((k₂ - k₁, v₁) :: r₂) ++ m₂)
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₂, v₁) :: m₂)

tactic: have haux : k₁ * Var.denote ctx v₁ ≤ k₂ * Var.denote ctx v₁ := Nat.mul_le_mul_right _ (Nat.le_of_lt (Nat.blt_eq.mp hltk))
state_before: case succ.h_3.inr.inr.inl
ctx : Context
fuel : Nat
ih✝ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : blt k₁ k₂ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ r₁ ((k₂ - k₁, v₁) :: r₂))
ih : denote ctx r₁ + denote ctx m₁ = denote ctx r₂ + (denote ctx m₂ + (k₂ - k₁) * Var.denote ctx v₁)
⊢ denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁) = denote ctx r₂ + (denote ctx m₂ + k₂ * Var.denote ctx v₁)

tactic: rw [Nat.mul_sub_right_distrib, ← Nat.add_assoc, ← Nat.add_sub_assoc haux] at ih
state_before: case succ.h_3.inr.inr.inl
ctx : Context
fuel : Nat
ih✝ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : blt k₁ k₂ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ r₁ ((k₂ - k₁, v₁) :: r₂))
ih : denote ctx r₁ + denote ctx m₁ = denote ctx r₂ + (denote ctx m₂ + (k₂ - k₁) * Var.denote ctx v₁)
haux : k₁ * Var.denote ctx v₁ ≤ k₂ * Var.denote ctx v₁
⊢ denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁) = denote ctx r₂ + (denote ctx m₂ + k₂ * Var.denote ctx v₁)

tactic: have ih := Nat.eq_add_of_sub_eq (Nat.le_trans haux (Nat.le_add_left ..)) ih.symm
state_before: case succ.h_3.inr.inr.inl
ctx : Context
fuel : Nat
ih✝ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : blt k₁ k₂ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ r₁ ((k₂ - k₁, v₁) :: r₂))
ih : denote ctx r₁ + denote ctx m₁ = denote ctx r₂ + denote ctx m₂ + k₂ * Var.denote ctx v₁ - k₁ * Var.denote ctx v₁
haux : k₁ * Var.denote ctx v₁ ≤ k₂ * Var.denote ctx v₁
⊢ denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁) = denote ctx r₂ + (denote ctx m₂ + k₂ * Var.denote ctx v₁)

tactic: simp at ih
state_before: case succ.h_3.inr.inr.inl
ctx : Context
fuel : Nat
ih✝¹ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : blt k₁ k₂ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ r₁ ((k₂ - k₁, v₁) :: r₂))
ih✝ : denote ctx r₁ + denote ctx m₁ = denote ctx r₂ + denote ctx m₂ + k₂ * Var.denote ctx v₁ - k₁ * Var.denote ctx v₁
haux : k₁ * Var.denote ctx v₁ ≤ k₂ * Var.denote ctx v₁
ih : denote ctx r₂ + denote ctx m₂ + k₂ * Var.denote ctx v₁ = denote ctx r₁ + denote ctx m₁ + k₁ * Var.denote ctx v₁
⊢ denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁) = denote ctx r₂ + (denote ctx m₂ + k₂ * Var.denote ctx v₁)

tactic: rw [ih]
state_before: case succ.h_3.inr.inr.inl
ctx : Context
fuel : Nat
ih✝¹ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : blt k₁ k₂ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ r₁ ((k₂ - k₁, v₁) :: r₂))
ih✝ : denote ctx r₁ + denote ctx m₁ = denote ctx r₂ + denote ctx m₂ + k₂ * Var.denote ctx v₁ - k₁ * Var.denote ctx v₁
haux : k₁ * Var.denote ctx v₁ ≤ k₂ * Var.denote ctx v₁
ih : denote ctx r₂ + (denote ctx m₂ + k₂ * Var.denote ctx v₁) = denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁)
⊢ denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁) = denote ctx r₂ + (denote ctx m₂ + k₂ * Var.denote ctx v₁)

tactic: by_cases hgtk : Nat.blt k₂ k₁ <;> simp [hgtk] at h
state_before: case succ.h_3.inr.inr.inr
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : ¬blt k₁ k₂ = true
h : denote_eq ctx (bif blt k₂ k₁ then cancelAux fuel m₁ m₂ ((k₁ - k₂, v₁) :: r₁) r₂ else cancelAux fuel m₁ m₂ r₁ r₂)
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₂, v₁) :: m₂)

tactic: have ih := ih (h := h)
state_before: case succ.h_3.inr.inr.inr.inl
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : ¬blt k₁ k₂ = true
hgtk : blt k₂ k₁ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ ((k₁ - k₂, v₁) :: r₁) r₂)
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₂, v₁) :: m₂)

tactic: simp [denote_eq] at ih ⊢
state_before: case succ.h_3.inr.inr.inr.inl
ctx : Context
fuel : Nat
ih✝ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : ¬blt k₁ k₂ = true
hgtk : blt k₂ k₁ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ ((k₁ - k₂, v₁) :: r₁) r₂)
ih : denote_eq ctx (List.reverse ((k₁ - k₂, v₁) :: r₁) ++ m₁, List.reverse r₂ ++ m₂)
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₂, v₁) :: m₂)

tactic: have haux : k₂ * Var.denote ctx v₁ ≤ k₁ * Var.denote ctx v₁ := Nat.mul_le_mul_right _ (Nat.le_of_lt (Nat.blt_eq.mp hgtk))
state_before: case succ.h_3.inr.inr.inr.inl
ctx : Context
fuel : Nat
ih✝ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : ¬blt k₁ k₂ = true
hgtk : blt k₂ k₁ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ ((k₁ - k₂, v₁) :: r₁) r₂)
ih : denote ctx r₁ + (denote ctx m₁ + (k₁ - k₂) * Var.denote ctx v₁) = denote ctx r₂ + denote ctx m₂
⊢ denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁) = denote ctx r₂ + (denote ctx m₂ + k₂ * Var.denote ctx v₁)

tactic: rw [Nat.mul_sub_right_distrib, ← Nat.add_assoc, ← Nat.add_sub_assoc haux] at ih
state_before: case succ.h_3.inr.inr.inr.inl
ctx : Context
fuel : Nat
ih✝ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : ¬blt k₁ k₂ = true
hgtk : blt k₂ k₁ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ ((k₁ - k₂, v₁) :: r₁) r₂)
ih : denote ctx r₁ + (denote ctx m₁ + (k₁ - k₂) * Var.denote ctx v₁) = denote ctx r₂ + denote ctx m₂
haux : k₂ * Var.denote ctx v₁ ≤ k₁ * Var.denote ctx v₁
⊢ denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁) = denote ctx r₂ + (denote ctx m₂ + k₂ * Var.denote ctx v₁)

tactic: have ih := Nat.eq_add_of_sub_eq (Nat.le_trans haux (Nat.le_add_left ..)) ih
state_before: case succ.h_3.inr.inr.inr.inl
ctx : Context
fuel : Nat
ih✝ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : ¬blt k₁ k₂ = true
hgtk : blt k₂ k₁ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ ((k₁ - k₂, v₁) :: r₁) r₂)
ih : denote ctx r₁ + denote ctx m₁ + k₁ * Var.denote ctx v₁ - k₂ * Var.denote ctx v₁ = denote ctx r₂ + denote ctx m₂
haux : k₂ * Var.denote ctx v₁ ≤ k₁ * Var.denote ctx v₁
⊢ denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁) = denote ctx r₂ + (denote ctx m₂ + k₂ * Var.denote ctx v₁)

tactic: simp at ih
state_before: case succ.h_3.inr.inr.inr.inl
ctx : Context
fuel : Nat
ih✝¹ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : ¬blt k₁ k₂ = true
hgtk : blt k₂ k₁ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ ((k₁ - k₂, v₁) :: r₁) r₂)
ih✝ : denote ctx r₁ + denote ctx m₁ + k₁ * Var.denote ctx v₁ - k₂ * Var.denote ctx v₁ = denote ctx r₂ + denote ctx m₂
haux : k₂ * Var.denote ctx v₁ ≤ k₁ * Var.denote ctx v₁
ih : denote ctx r₁ + denote ctx m₁ + k₁ * Var.denote ctx v₁ = denote ctx r₂ + denote ctx m₂ + k₂ * Var.denote ctx v₁
⊢ denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁) = denote ctx r₂ + (denote ctx m₂ + k₂ * Var.denote ctx v₁)

tactic: rw [ih]
state_before: case succ.h_3.inr.inr.inr.inl
ctx : Context
fuel : Nat
ih✝¹ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : ¬blt k₁ k₂ = true
hgtk : blt k₂ k₁ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ ((k₁ - k₂, v₁) :: r₁) r₂)
ih✝ : denote ctx r₁ + denote ctx m₁ + k₁ * Var.denote ctx v₁ - k₂ * Var.denote ctx v₁ = denote ctx r₂ + denote ctx m₂
haux : k₂ * Var.denote ctx v₁ ≤ k₁ * Var.denote ctx v₁
ih : denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁) = denote ctx r₂ + (denote ctx m₂ + k₂ * Var.denote ctx v₁)
⊢ denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁) = denote ctx r₂ + (denote ctx m₂ + k₂ * Var.denote ctx v₁)

tactic: have heqk : k₁ = k₂ := eq_of_not_blt_eq_true hltk hgtk
state_before: case succ.h_3.inr.inr.inr.inr
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : ¬blt k₁ k₂ = true
hgtk : ¬blt k₂ k₁ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂)
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₂, v₁) :: m₂)

tactic: subst heqk
state_before: case succ.h_3.inr.inr.inr.inr
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ : List (Nat × Var)
k₂ : Nat
m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
hltk : ¬blt k₁ k₂ = true
hgtk : ¬blt k₂ k₁ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂)
heqk : k₁ = k₂
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₂, v₁) :: m₂)

tactic: have ih := ih (h := h)
state_before: case succ.h_3.inr.inr.inr.inr
ctx : Context
fuel : Nat
ih :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂)
hltk hgtk : ¬blt k₁ k₁ = true
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₁, v₁) :: m₂)

tactic: simp [denote_eq] at ih ⊢
state_before: case succ.h_3.inr.inr.inr.inr
ctx : Context
fuel : Nat
ih✝ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂)
hltk hgtk : ¬blt k₁ k₁ = true
ih : denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
⊢ denote_eq ctx (List.reverse r₁ ++ (k₁, v₁) :: m₁, List.reverse r₂ ++ (k₁, v₁) :: m₂)

tactic: rw [← Nat.add_assoc, ih, Nat.add_assoc]
state_before: case succ.h_3.inr.inr.inr.inr
ctx : Context
fuel : Nat
ih✝ :
  ∀ (m₁ m₂ r₁ r₂ : Poly),
    denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂) → denote_eq ctx (List.reverse r₁ ++ m₁, List.reverse r₂ ++ m₂)
r₁ r₂ m₁✝ m₂✝ : Poly
k₁ : Nat
v₁ : Var
m₁ m₂ : List (Nat × Var)
hltv hgtv : ¬blt v₁ v₁ = true
h : denote_eq ctx (cancelAux fuel m₁ m₂ r₁ r₂)
hltk hgtk : ¬blt k₁ k₁ = true
ih : denote ctx r₁ + denote ctx m₁ = denote ctx r₂ + denote ctx m₂
⊢ denote ctx r₁ + (denote ctx m₁ + k₁ * Var.denote ctx v₁) = denote ctx r₂ + (denote ctx m₂ + k₁ * Var.denote ctx v₁)