l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    

Proof state:
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this : NF a
h' : repr (add a o) = repr a + repr o
nf : NF (a + o)
⊢ repr (oadd e n a + o) = repr (oadd e n a) + repr o

Next tactic:
conv at nf => simp [HAdd.hAdd, Add.add]
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => 

Proof state:
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this : NF a
h' : repr (add a o) = repr a + repr o
nf : NF (a + o)
| NF (a + o)

Next tactic:
simp [HAdd.hAdd, Add.add]
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    

Proof state:
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this : NF a
h' : repr (add a o) = repr a + repr o
nf : NF (add a o)
⊢ repr (oadd e n a + o) = repr (oadd e n a) + repr o

Next tactic:
conv in _ + o => simp [HAdd.hAdd, Add.add]
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => 

Proof state:
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this : NF a
h' : repr (add a o) = repr a + repr o
nf : NF (add a o)
| oadd e n a + o

Next tactic:
simp [HAdd.hAdd, Add.add]
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    

Proof state:
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this : NF a
h' : repr (add a o) = repr a + repr o
nf : NF (add a o)
⊢ repr (add (oadd e n a) o) = repr (oadd e n a) + repr o

Next tactic:
cases' h : add a o with e' n' a'
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      

Proof state:
case zero
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this : NF a
h' : repr (add a o) = repr a + repr o
nf : NF (add a o)
h : add a o = zero
⊢ repr (add (oadd e n a) o) = repr (oadd e n a) + repr o

Next tactic:
simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      

Proof state:
case oadd
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this : NF a
h' : repr (add a o) = repr a + repr o
nf : NF (add a o)
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
⊢ repr (add (oadd e n a) o) = repr (oadd e n a) + repr o

Next tactic:
simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    

Proof state:
case oadd
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
⊢ repr
      (match cmp e e' with
      | Ordering.lt => oadd e' n' a'
      | Ordering.eq => oadd e (n + n') a'
      | Ordering.gt => oadd e n (oadd e' n' a')) =
    ω ^ repr e * ↑↑n + (ω ^ repr e' * ↑↑n' + repr a')

Next tactic:
have := h₁.fst
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    have := h₁.fst; 

Proof state:
case oadd
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this✝ : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
this : NF e
⊢ repr
      (match cmp e e' with
      | Ordering.lt => oadd e' n' a'
      | Ordering.eq => oadd e (n + n') a'
      | Ordering.gt => oadd e n (oadd e' n' a')) =
    ω ^ repr e * ↑↑n + (ω ^ repr e' * ↑↑n' + repr a')

Next tactic:
haveI := nf.fst
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    have := h₁.fst; haveI := nf.fst; 

Proof state:
case oadd
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this✝¹ : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
this✝ : NF e
this : NF e'
⊢ repr
      (match cmp e e' with
      | Ordering.lt => oadd e' n' a'
      | Ordering.eq => oadd e (n + n') a'
      | Ordering.gt => oadd e n (oadd e' n' a')) =
    ω ^ repr e * ↑↑n + (ω ^ repr e' * ↑↑n' + repr a')

Next tactic:
have ee := cmp_compares e e'
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    have := h₁.fst; haveI := nf.fst; have ee := cmp_compares e e'
    

Proof state:
case oadd
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this✝¹ : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
this✝ : NF e
this : NF e'
ee : Ordering.Compares (cmp e e') e e'
⊢ repr
      (match cmp e e' with
      | Ordering.lt => oadd e' n' a'
      | Ordering.eq => oadd e (n + n') a'
      | Ordering.gt => oadd e n (oadd e' n' a')) =
    ω ^ repr e * ↑↑n + (ω ^ repr e' * ↑↑n' + repr a')

Next tactic:
cases he: cmp e e'
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    have := h₁.fst; haveI := nf.fst; have ee := cmp_compares e e'
    cases he: cmp e e' <;> 

Proof state:
case oadd.lt
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this✝¹ : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
this✝ : NF e
this : NF e'
ee : Ordering.Compares (cmp e e') e e'
he : cmp e e' = Ordering.lt
⊢ repr
      (match Ordering.lt with
      | Ordering.lt => oadd e' n' a'
      | Ordering.eq => oadd e (n + n') a'
      | Ordering.gt => oadd e n (oadd e' n' a')) =
    ω ^ repr e * ↑↑n + (ω ^ repr e' * ↑↑n' + repr a')

Next tactic:
simp [he] at ee ⊢
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    have := h₁.fst; haveI := nf.fst; have ee := cmp_compares e e'
    cases he: cmp e e' <;> 

Proof state:
case oadd.eq
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this✝¹ : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
this✝ : NF e
this : NF e'
ee : Ordering.Compares (cmp e e') e e'
he : cmp e e' = Ordering.eq
⊢ repr
      (match Ordering.eq with
      | Ordering.lt => oadd e' n' a'
      | Ordering.eq => oadd e (n + n') a'
      | Ordering.gt => oadd e n (oadd e' n' a')) =
    ω ^ repr e * ↑↑n + (ω ^ repr e' * ↑↑n' + repr a')

Next tactic:
simp [he] at ee ⊢
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    have := h₁.fst; haveI := nf.fst; have ee := cmp_compares e e'
    cases he: cmp e e' <;> 

Proof state:
case oadd.gt
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this✝¹ : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
this✝ : NF e
this : NF e'
ee : Ordering.Compares (cmp e e') e e'
he : cmp e e' = Ordering.gt
⊢ repr
      (match Ordering.gt with
      | Ordering.lt => oadd e' n' a'
      | Ordering.eq => oadd e (n + n') a'
      | Ordering.gt => oadd e n (oadd e' n' a')) =
    ω ^ repr e * ↑↑n + (ω ^ repr e' * ↑↑n' + repr a')

Next tactic:
simp [he] at ee ⊢
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    have := h₁.fst; haveI := nf.fst; have ee := cmp_compares e e'
    cases he: cmp e e' <;> simp [he] at ee ⊢
    · 

Proof state:
case oadd.lt
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this✝¹ : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
this✝ : NF e
this : NF e'
he : cmp e e' = Ordering.lt
ee : e < e'
⊢ ω ^ repr e' * ↑↑n' + repr a' = ω ^ repr e * ↑↑n + (ω ^ repr e' * ↑↑n' + repr a')

Next tactic:
rw [← add_assoc, @add_absorp _ (repr e') (ω ^ repr e' * (n' : ℕ))]
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    have := h₁.fst; haveI := nf.fst; have ee := cmp_compares e e'
    cases he: cmp e e' <;> simp [he] at ee ⊢
    · rw [← add_assoc, @add_absorp _ (repr e') (ω ^ repr e' * (n' : ℕ))]
      · 

Proof state:
case oadd.lt.h₁
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this✝¹ : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
this✝ : NF e
this : NF e'
he : cmp e e' = Ordering.lt
ee : e < e'
⊢ ω ^ repr e * ↑↑n < ω ^ repr e'

Next tactic:
have := (h₁.below_of_lt ee).repr_lt
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    have := h₁.fst; haveI := nf.fst; have ee := cmp_compares e e'
    cases he: cmp e e' <;> simp [he] at ee ⊢
    · rw [← add_assoc, @add_absorp _ (repr e') (ω ^ repr e' * (n' : ℕ))]
      · have := (h₁.below_of_lt ee).repr_lt
        

Proof state:
case oadd.lt.h₁
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this✝² : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
this✝¹ : NF e
this✝ : NF e'
he : cmp e e' = Ordering.lt
ee : e < e'
this : repr (oadd e n a) < ω ^ repr e'
⊢ ω ^ repr e * ↑↑n < ω ^ repr e'

Next tactic:
unfold repr at this
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    have := h₁.fst; haveI := nf.fst; have ee := cmp_compares e e'
    cases he: cmp e e' <;> simp [he] at ee ⊢
    · rw [← add_assoc, @add_absorp _ (repr e') (ω ^ repr e' * (n' : ℕ))]
      · have := (h₁.below_of_lt ee).repr_lt
        unfold repr at this
        

Proof state:
case oadd.lt.h₁
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this✝² : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
this✝¹ : NF e
this✝ : NF e'
he : cmp e e' = Ordering.lt
ee : e < e'
this :
  ω ^ repr e * ↑↑n + repr a <
    ω ^
      match e' with
      | zero => 0
      | oadd e n a => ω ^ repr e * ↑↑n + repr a
⊢ ω ^ repr e * ↑↑n < ω ^ repr e'

Next tactic:
cases he': e'
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    have := h₁.fst; haveI := nf.fst; have ee := cmp_compares e e'
    cases he: cmp e e' <;> simp [he] at ee ⊢
    · rw [← add_assoc, @add_absorp _ (repr e') (ω ^ repr e' * (n' : ℕ))]
      · have := (h₁.below_of_lt ee).repr_lt
        unfold repr at this
        cases he': e' <;> 

Proof state:
case oadd.lt.h₁.zero
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this✝² : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
this✝¹ : NF e
this✝ : NF e'
he : cmp e e' = Ordering.lt
ee : e < e'
this :
  ω ^ repr e * ↑↑n + repr a <
    ω ^
      match e' with
      | zero => 0
      | oadd e n a => ω ^ repr e * ↑↑n + repr a
he' : e' = zero
⊢ ω ^ repr e * ↑↑n < ω ^ repr zero

Next tactic:
simp [he'] at this ⊢
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    have := h₁.fst; haveI := nf.fst; have ee := cmp_compares e e'
    cases he: cmp e e' <;> simp [he] at ee ⊢
    · rw [← add_assoc, @add_absorp _ (repr e') (ω ^ repr e' * (n' : ℕ))]
      · have := (h₁.below_of_lt ee).repr_lt
        unfold repr at this
        cases he': e' <;> 

Proof state:
case oadd.lt.h₁.oadd
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this✝² : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
this✝¹ : NF e
this✝ : NF e'
he : cmp e e' = Ordering.lt
ee : e < e'
this :
  ω ^ repr e * ↑↑n + repr a <
    ω ^
      match e' with
      | zero => 0
      | oadd e n a => ω ^ repr e * ↑↑n + repr a
a✝² : ONote
a✝¹ : ℕ+
a✝ : ONote
he' : e' = oadd a✝² a✝¹ a✝
⊢ ω ^ repr e * ↑↑n < ω ^ repr (oadd a✝² a✝¹ a✝)

Next tactic:
simp [he'] at this ⊢
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    have := h₁.fst; haveI := nf.fst; have ee := cmp_compares e e'
    cases he: cmp e e' <;> simp [he] at ee ⊢
    · rw [← add_assoc, @add_absorp _ (repr e') (ω ^ repr e' * (n' : ℕ))]
      · have := (h₁.below_of_lt ee).repr_lt
        unfold repr at this
        cases he': e' <;> simp [he'] at this ⊢ <;>
        

Proof state:
case oadd.lt.h₁.zero
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this✝² : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
this✝¹ : NF e
this✝ : NF e'
he : cmp e e' = Ordering.lt
ee : e < e'
he' : e' = zero
this : ω ^ repr e * ↑↑n + repr a < 1
⊢ ω ^ repr e * ↑↑n < 1

Next tactic:
exact lt_of_le_of_lt (le_add_right _ _) this
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    have := h₁.fst; haveI := nf.fst; have ee := cmp_compares e e'
    cases he: cmp e e' <;> simp [he] at ee ⊢
    · rw [← add_assoc, @add_absorp _ (repr e') (ω ^ repr e' * (n' : ℕ))]
      · have := (h₁.below_of_lt ee).repr_lt
        unfold repr at this
        cases he': e' <;> simp [he'] at this ⊢ <;>
        

Proof state:
case oadd.lt.h₁.oadd
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this✝² : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
this✝¹ : NF e
this✝ : NF e'
he : cmp e e' = Ordering.lt
ee : e < e'
a✝² : ONote
a✝¹ : ℕ+
a✝ : ONote
he' : e' = oadd a✝² a✝¹ a✝
this : ω ^ repr e * ↑↑n + repr a < ω ^ (ω ^ repr a✝² * ↑↑a✝¹ + repr a✝)
⊢ ω ^ repr e * ↑↑n < ω ^ (ω ^ repr a✝² * ↑↑a✝¹ + repr a✝)

Next tactic:
exact lt_of_le_of_lt (le_add_right _ _) this
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    have := h₁.fst; haveI := nf.fst; have ee := cmp_compares e e'
    cases he: cmp e e' <;> simp [he] at ee ⊢
    · rw [← add_assoc, @add_absorp _ (repr e') (ω ^ repr e' * (n' : ℕ))]
      · have := (h₁.below_of_lt ee).repr_lt
        unfold repr at this
        cases he': e' <;> simp [he'] at this ⊢ <;>
        exact lt_of_le_of_lt (le_add_right _ _) this
      · 

Proof state:
case oadd.lt.h₂
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this✝¹ : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
this✝ : NF e
this : NF e'
he : cmp e e' = Ordering.lt
ee : e < e'
⊢ ω ^ repr e' ≤ ω ^ repr e' * ↑↑n'

Next tactic:
simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos (repr e') omega_pos).2
          (nat_cast_le.2 n'.pos)
@[simp]
theorem repr_add : ∀ (o₁ o₂) [NF o₁] [NF o₂], repr (o₁ + o₂) = repr o₁ + repr o₂
  | 0, o, _, _ => by simp
  | oadd e n a, o, h₁, h₂ => by
    haveI := h₁.snd; have h' := repr_add a o
    conv_lhs at h' => simp [HAdd.hAdd, Add.add]
    have nf := ONote.add_nf a o
    conv at nf => simp [HAdd.hAdd, Add.add]
    conv in _ + o => simp [HAdd.hAdd, Add.add]
    cases' h : add a o with e' n' a' <;>
      simp only [Add.add, add, addAux, h'.symm, h, add_assoc, repr] at nf h₁ ⊢
    have := h₁.fst; haveI := nf.fst; have ee := cmp_compares e e'
    cases he: cmp e e' <;> simp [he] at ee ⊢
    · rw [← add_assoc, @add_absorp _ (repr e') (ω ^ repr e' * (n' : ℕ))]
      · have := (h₁.below_of_lt ee).repr_lt
        unfold repr at this
        cases he': e' <;> simp [he'] at this ⊢ <;>
        exact lt_of_le_of_lt (le_add_right _ _) this
      · simpa using (Ordinal.mul_le_mul_iff_left <| opow_pos (repr e') omega_pos).2
          (nat_cast_le.2 n'.pos)
    · 

Proof state:
case oadd.eq
e : ONote
n : ℕ+
a o : ONote
h₁ : NF (oadd e n a)
h₂ : NF o
this✝¹ : NF a
h' : repr (add a o) = repr a + repr o
e' : ONote
n' : ℕ+
a' : ONote
h : add a o = oadd e' n' a'
nf : NF (oadd e' n' a')
this✝ : NF e
this : NF e'
he : cmp e e' = Ordering.eq
ee : e = e'
⊢ ω ^ repr e * (↑↑n + ↑↑n') + repr a' = ω ^ repr e * ↑↑n + (ω ^ repr e' * ↑↑n' + repr a')

Next tactic:
rw [ee, ← add_assoc, ← mul_add, ← Nat.cast_add]
theorem sub_nfBelow : ∀ {o₁ o₂ b}, NFBelow o₁ b → NF o₂ → NFBelow (o₁ - o₂) b
  | 0, o, b, _, h₂ => by 

Proof state:
o : ONote
b : Ordinal.{0}
x✝ : NFBelow 0 b
h₂ : NF o
⊢ NFBelow (0 - o) b

Next tactic:
cases o