Theorem: String.extract.go₂_add_right_cancel
File: .lake/packages/batteries/Batteries/Data/String/Lemmas.lean

Proof steps:
state_before: s : List Char
i e n : Nat
⊢ go₂ s { byteIdx := i + n } { byteIdx := e + n } = go₂ s { byteIdx := i } { byteIdx := e }
state_after: case ind
s : List Char
i e n : Nat
⊢ ∀ (c : Char) (cs : List Char) (i : Pos),
    ¬i = { byteIdx := e } →
      go₂ cs { byteIdx := i.byteIdx + c.utf8Size + n } { byteIdx := e + n } = go₂ cs (i + c) { byteIdx := e } →
        (if { byteIdx := i.byteIdx + n } = { byteIdx := e + n } then []
          else c :: go₂ cs ({ byteIdx := i.byteIdx + n } + c) { byteIdx := e + n }) =
          if i = { byteIdx := e } then [] else c :: go₂ cs (i + c) { byteIdx := e }
tactic: apply utf8InductionOn s ⟨i⟩ ⟨e⟩ (motive := fun s i =>
    go₂ s ⟨i.byteIdx + n⟩ ⟨e + n⟩ = go₂ s i ⟨e⟩)
    <;> simp only [ne_eq, go₂, pos_add_char, implies_true, ↓reduceIte]
state_before: case ind
s : List Char
i e n : Nat
⊢ ∀ (c : Char) (cs : List Char) (i : Pos),
    ¬i = { byteIdx := e } →
      go₂ cs { byteIdx := i.byteIdx + c.utf8Size + n } { byteIdx := e + n } = go₂ cs (i + c) { byteIdx := e } →
        (if { byteIdx := i.byteIdx + n } = { byteIdx := e + n } then []
          else c :: go₂ cs ({ byteIdx := i.byteIdx + n } + c) { byteIdx := e + n }) =
          if i = { byteIdx := e } then [] else c :: go₂ cs (i + c) { byteIdx := e }
state_after: case ind
s : List Char
i✝ e n : Nat
c : Char
cs : List Char
i : Nat
h : ¬{ byteIdx := i } = { byteIdx := e }
ih :
  go₂ cs { byteIdx := { byteIdx := i }.byteIdx + c.utf8Size + n } { byteIdx := e + n } =
    go₂ cs ({ byteIdx := i } + c) { byteIdx := e }
⊢ (if { byteIdx := { byteIdx := i }.byteIdx + n } = { byteIdx := e + n } then []
    else c :: go₂ cs ({ byteIdx := { byteIdx := i }.byteIdx + n } + c) { byteIdx := e + n }) =
    if { byteIdx := i } = { byteIdx := e } then [] else c :: go₂ cs ({ byteIdx := i } + c) { byteIdx := e }
tactic: intro c cs ⟨i⟩ h ih
state_before: case ind
s : List Char
i✝ e n : Nat
c : Char
cs : List Char
i : Nat
h : ¬{ byteIdx := i } = { byteIdx := e }
ih :
  go₂ cs { byteIdx := { byteIdx := i }.byteIdx + c.utf8Size + n } { byteIdx := e + n } =
    go₂ cs ({ byteIdx := i } + c) { byteIdx := e }
⊢ (if { byteIdx := { byteIdx := i }.byteIdx + n } = { byteIdx := e + n } then []
    else c :: go₂ cs ({ byteIdx := { byteIdx := i }.byteIdx + n } + c) { byteIdx := e + n }) =
    if { byteIdx := i } = { byteIdx := e } then [] else c :: go₂ cs ({ byteIdx := i } + c) { byteIdx := e }
state_after: case ind
s : List Char
i✝ e n : Nat
c : Char
cs : List Char
i : Nat
ih :
  go₂ cs { byteIdx := { byteIdx := i }.byteIdx + c.utf8Size + n } { byteIdx := e + n } =
    go₂ cs ({ byteIdx := i } + c) { byteIdx := e }
h : ¬i = e
⊢ (if i + n = e + n then [] else c :: go₂ cs { byteIdx := i + n + c.utf8Size } { byteIdx := e + n }) =
    if i = e then [] else c :: go₂ cs { byteIdx := i + c.utf8Size } { byteIdx := e }
tactic: simp only [Pos.ext_iff, Pos.addChar_eq] at h ⊢
state_before: case ind
s : List Char
i✝ e n : Nat
c : Char
cs : List Char
i : Nat
ih :
  go₂ cs { byteIdx := { byteIdx := i }.byteIdx + c.utf8Size + n } { byteIdx := e + n } =
    go₂ cs ({ byteIdx := i } + c) { byteIdx := e }
h : ¬i = e
⊢ (if i + n = e + n then [] else c :: go₂ cs { byteIdx := i + n + c.utf8Size } { byteIdx := e + n }) =
    if i = e then [] else c :: go₂ cs { byteIdx := i + c.utf8Size } { byteIdx := e }
state_after: case ind
s : List Char
i✝ e n : Nat
c : Char
cs : List Char
i : Nat
ih :
  go₂ cs { byteIdx := { byteIdx := i }.byteIdx + c.utf8Size + n } { byteIdx := e + n } =
    go₂ cs ({ byteIdx := i } + c) { byteIdx := e }
h : ¬i = e
⊢ go₂ cs { byteIdx := i + n + c.utf8Size } { byteIdx := e + n } = go₂ cs { byteIdx := i + c.utf8Size } { byteIdx := e }
tactic: simp only [Nat.add_right_cancel_iff, h, ↓reduceIte, List.cons.injEq, true_and]
state_before: case ind
s : List Char
i✝ e n : Nat
c : Char
cs : List Char
i : Nat
ih :
  go₂ cs { byteIdx := { byteIdx := i }.byteIdx + c.utf8Size + n } { byteIdx := e + n } =
    go₂ cs ({ byteIdx := i } + c) { byteIdx := e }
h : ¬i = e
⊢ go₂ cs { byteIdx := i + n + c.utf8Size } { byteIdx := e + n } = go₂ cs { byteIdx := i + c.utf8Size } { byteIdx := e }
state_after: case ind
s : List Char
i✝ e n : Nat
c : Char
cs : List Char
i : Nat
ih :
  go₂ cs { byteIdx := { byteIdx := i }.byteIdx + c.utf8Size + n } { byteIdx := e + n } =
    go₂ cs ({ byteIdx := i } + c) { byteIdx := e }
h : ¬i = e
⊢ go₂ cs { byteIdx := i + c.utf8Size + n } { byteIdx := e + n } = go₂ cs { byteIdx := i + c.utf8Size } { byteIdx := e }
tactic: rw [Nat.add_right_comm]
state_before: case ind
s : List Char
i✝ e n : Nat
c : Char
cs : List Char
i : Nat
ih :
  go₂ cs { byteIdx := { byteIdx := i }.byteIdx + c.utf8Size + n } { byteIdx := e + n } =
    go₂ cs ({ byteIdx := i } + c) { byteIdx := e }
h : ¬i = e
⊢ go₂ cs { byteIdx := i + c.utf8Size + n } { byteIdx := e + n } = go₂ cs { byteIdx := i + c.utf8Size } { byteIdx := e }
state_after: no goals
tactic: exact ih