Theorem: String.set_next_add
File: src/lean/Init/Data/String/Basic.lean

tactic: simp [next, get, set, endPos, utf8ByteSize] at h ⊢
state_before: s : String
i : Pos
c : Char
b₁ b₂ : Nat
h : (next s i).byteIdx + b₁ = (endPos s).byteIdx + b₂
⊢ (next (set s i c) i).byteIdx + b₁ = (endPos (set s i c)).byteIdx + b₂

tactic: rw [Nat.add_comm i.1, Nat.add_assoc] at h ⊢
state_before: s : String
i : Pos
c : Char
b₁ b₂ : Nat
h : i.byteIdx + csize (utf8GetAux s.data 0 i) + b₁ = utf8ByteSize.go s.data + b₂
⊢ i.byteIdx + csize (utf8GetAux (utf8SetAux c s.data 0 i) 0 i) + b₁ = utf8ByteSize.go (utf8SetAux c s.data 0 i) + b₂

tactic: let rec foo : ∀ cs a b₁ b₂,
  csize (utf8GetAux cs a i) + b₁ = utf8ByteSize.go cs + b₂ →
  csize (utf8GetAux (utf8SetAux c cs a i) a i) + b₁ = utf8ByteSize.go (utf8SetAux c cs a i) + b₂
| [], _, _, _, h => h
| c'::cs, a, b₁, b₂, h => by
  unfold utf8SetAux
  apply iteInduction (motive := fun p => csize (utf8GetAux p a i) + b₁ = utf8ByteSize.go p + b₂) <;>
    intro h' <;> simp [utf8GetAux, h', utf8ByteSize.go] at h ⊢
  next =>
    rw [Nat.add_assoc, Nat.add_left_comm] at h ⊢; rw [Nat.add_left_cancel h]
  next =>
    rw [Nat.add_assoc] at h ⊢
    refine foo cs (a + c') b₁ (csize c' + b₂) h
state_before: s : String
i : Pos
c : Char
b₁ b₂ : Nat
h : csize (utf8GetAux s.data 0 i) + (i.byteIdx + b₁) = utf8ByteSize.go s.data + b₂
⊢ csize (utf8GetAux (utf8SetAux c s.data 0 i) 0 i) + (i.byteIdx + b₁) = utf8ByteSize.go (utf8SetAux c s.data 0 i) + b₂

tactic: exact foo s.1 0 _ _ h
state_before: s : String
i : Pos
c : Char
b₁ b₂ : Nat
h : csize (utf8GetAux s.data 0 i) + (i.byteIdx + b₁) = utf8ByteSize.go s.data + b₂
⊢ csize (utf8GetAux (utf8SetAux c s.data 0 i) 0 i) + (i.byteIdx + b₁) = utf8ByteSize.go (utf8SetAux c s.data 0 i) + b₂

tactic: unfold utf8SetAux
state_before: s : String
i : Pos
c : Char
b₁✝ b₂✝ : Nat
h✝ : csize (utf8GetAux s.data 0 i) + (i.byteIdx + b₁✝) = utf8ByteSize.go s.data + b₂✝
c' : Char
cs : List Char
a : Pos
b₁ b₂ : Nat
h : csize (utf8GetAux (c' :: cs) a i) + b₁ = utf8ByteSize.go (c' :: cs) + b₂
⊢ csize (utf8GetAux (utf8SetAux c (c' :: cs) a i) a i) + b₁ = utf8ByteSize.go (utf8SetAux c (c' :: cs) a i) + b₂

tactic: apply iteInduction (motive := fun p => csize (utf8GetAux p a i) + b₁ = utf8ByteSize.go p + b₂) <;>
  intro h' <;> simp [utf8GetAux, h', utf8ByteSize.go] at h ⊢
state_before: s : String
i : Pos
c : Char
b₁✝ b₂✝ : Nat
h✝ : csize (utf8GetAux s.data 0 i) + (i.byteIdx + b₁✝) = utf8ByteSize.go s.data + b₂✝
c' : Char
cs : List Char
a : Pos
b₁ b₂ : Nat
h : csize (utf8GetAux (c' :: cs) a i) + b₁ = utf8ByteSize.go (c' :: cs) + b₂
⊢ csize (utf8GetAux (ite (a = i) (c :: cs) (c' :: utf8SetAux c cs (a + c') i)) a i) + b₁ =
    utf8ByteSize.go (ite (a = i) (c :: cs) (c' :: utf8SetAux c cs (a + c') i)) + b₂

tactic: next =>
  rw [Nat.add_assoc, Nat.add_left_comm] at h ⊢; rw [Nat.add_left_cancel h]
state_before: case hpos
s : String
i : Pos
c : Char
b₁✝ b₂✝ : Nat
h✝ : csize (utf8GetAux s.data 0 i) + (i.byteIdx + b₁✝) = utf8ByteSize.go s.data + b₂✝
c' : Char
cs : List Char
a : Pos
b₁ b₂ : Nat
h' : a = i
h : csize c' + b₁ = utf8ByteSize.go cs + csize c' + b₂
⊢ csize c + b₁ = utf8ByteSize.go cs + csize c + b₂

case hneg
s : String
i : Pos
c : Char
b₁✝ b₂✝ : Nat
h✝ : csize (utf8GetAux s.data 0 i) + (i.byteIdx + b₁✝) = utf8ByteSize.go s.data + b₂✝
c' : Char
cs : List Char
a : Pos
b₁ b₂ : Nat
h' : ¬a = i
h : csize (utf8GetAux cs (a + c') i) + b₁ = utf8ByteSize.go cs + csize c' + b₂
⊢ csize (utf8GetAux (utf8SetAux c cs (a + c') i) (a + c') i) + b₁ =
    utf8ByteSize.go (utf8SetAux c cs (a + c') i) + csize c' + b₂

tactic: next =>
  rw [Nat.add_assoc] at h ⊢
  refine foo cs (a + c') b₁ (csize c' + b₂) h
state_before: case hneg
s : String
i : Pos
c : Char
b₁✝ b₂✝ : Nat
h✝ : csize (utf8GetAux s.data 0 i) + (i.byteIdx + b₁✝) = utf8ByteSize.go s.data + b₂✝
c' : Char
cs : List Char
a : Pos
b₁ b₂ : Nat
h' : ¬a = i
h : csize (utf8GetAux cs (a + c') i) + b₁ = utf8ByteSize.go cs + csize c' + b₂
⊢ csize (utf8GetAux (utf8SetAux c cs (a + c') i) (a + c') i) + b₁ =
    utf8ByteSize.go (utf8SetAux c cs (a + c') i) + csize c' + b₂

tactic: rw [Nat.add_assoc, Nat.add_left_comm] at h ⊢
state_before: s : String
i : Pos
c : Char
b₁✝ b₂✝ : Nat
h✝ : csize (utf8GetAux s.data 0 i) + (i.byteIdx + b₁✝) = utf8ByteSize.go s.data + b₂✝
c' : Char
cs : List Char
a : Pos
b₁ b₂ : Nat
h' : a = i
h : csize c' + b₁ = utf8ByteSize.go cs + csize c' + b₂
⊢ csize c + b₁ = utf8ByteSize.go cs + csize c + b₂

tactic: rw [Nat.add_left_cancel h]
state_before: s : String
i : Pos
c : Char
b₁✝ b₂✝ : Nat
h✝ : csize (utf8GetAux s.data 0 i) + (i.byteIdx + b₁✝) = utf8ByteSize.go s.data + b₂✝
c' : Char
cs : List Char
a : Pos
b₁ b₂ : Nat
h' : a = i
h : csize c' + b₁ = csize c' + (utf8ByteSize.go cs + b₂)
⊢ csize c + b₁ = csize c + (utf8ByteSize.go cs + b₂)

tactic: rw [Nat.add_assoc] at h ⊢
state_before: s : String
i : Pos
c : Char
b₁✝ b₂✝ : Nat
h✝ : csize (utf8GetAux s.data 0 i) + (i.byteIdx + b₁✝) = utf8ByteSize.go s.data + b₂✝
c' : Char
cs : List Char
a : Pos
b₁ b₂ : Nat
h' : ¬a = i
h : csize (utf8GetAux cs (a + c') i) + b₁ = utf8ByteSize.go cs + csize c' + b₂
⊢ csize (utf8GetAux (utf8SetAux c cs (a + c') i) (a + c') i) + b₁ =
    utf8ByteSize.go (utf8SetAux c cs (a + c') i) + csize c' + b₂

tactic: refine foo cs (a + c') b₁ (csize c' + b₂) h
state_before: s : String
i : Pos
c : Char
b₁✝ b₂✝ : Nat
h✝ : csize (utf8GetAux s.data 0 i) + (i.byteIdx + b₁✝) = utf8ByteSize.go s.data + b₂✝
c' : Char
cs : List Char
a : Pos
b₁ b₂ : Nat
h' : ¬a = i
h : csize (utf8GetAux cs (a + c') i) + b₁ = utf8ByteSize.go cs + (csize c' + b₂)
⊢ csize (utf8GetAux (utf8SetAux c cs (a + c') i) (a + c') i) + b₁ =
    utf8ByteSize.go (utf8SetAux c cs (a + c') i) + (csize c' + b₂)