Theorem: String.firstDiffPos_loop_eq
File: .lake/packages/batteries/Batteries/Data/String/Lemmas.lean

Proof steps:
state_before: l₁ l₂ r₁ r₂ : List Char
stop p : Nat
hl₁ : p = utf8Len l₁
hl₂ : p = utf8Len l₂
hstop : stop = min (utf8Len l₁ + utf8Len r₁) (utf8Len l₂ + utf8Len r₂)
⊢ firstDiffPos.loop { data := l₁ ++ r₁ } { data := l₂ ++ r₂ } { byteIdx := stop } { byteIdx := p } =
    { byteIdx := p + utf8Len (List.takeWhile₂ (fun x x_1 => decide (x = x_1)) r₁ r₂).fst }
state_after: l₁ l₂ r₁ r₂ : List Char
stop p : Nat
hl₁ : p = utf8Len l₁
hl₂ : p = utf8Len l₂
hstop : stop = min (utf8Len l₁ + utf8Len r₁) (utf8Len l₂ + utf8Len r₂)
⊢ firstDiffPos.loop { data := l₁ ++ r₁ } { data := l₂ ++ r₂ } { byteIdx := stop } { byteIdx := p } =
    {
      byteIdx :=
        p +
          utf8Len
            (match r₁, r₂ with
              | a :: as, b :: bs =>
                if decide (a = b) = true then
                  match List.takeWhile₂ (fun x x_1 => decide (x = x_1)) as bs with
                  | (as', bs') => (a :: as', b :: bs')
                else ([], [])
              | x, x_1 => ([], [])).fst }
tactic: unfold List.takeWhile₂
state_before: l₁ l₂ r₁ r₂ : List Char
stop p : Nat
hl₁ : p = utf8Len l₁
hl₂ : p = utf8Len l₂
hstop : stop = min (utf8Len l₁ + utf8Len r₁) (utf8Len l₂ + utf8Len r₂)
⊢ firstDiffPos.loop { data := l₁ ++ r₁ } { data := l₂ ++ r₂ } { byteIdx := stop } { byteIdx := p } =
    {
      byteIdx :=
        p +
          utf8Len
            (match r₁, r₂ with
              | a :: as, b :: bs =>
                if decide (a = b) = true then
                  match List.takeWhile₂ (fun x x_1 => decide (x = x_1)) as bs with
                  | (as', bs') => (a :: as', b :: bs')
                else ([], [])
              | x, x_1 => ([], [])).fst }
state_after: case h_1
l₁ l₂ : List Char
stop p : Nat
hl₁ : p = utf8Len l₁
hl₂ : p = utf8Len l₂
x✝¹ x✝ : List Char
a✝ : Char
as✝ : List Char
b✝ : Char
bs✝ : List Char
hstop : stop = min (utf8Len l₁ + utf8Len (a✝ :: as✝)) (utf8Len l₂ + utf8Len (b✝ :: bs✝))
⊢ (if h : { byteIdx := p } < { byteIdx := stop } then
      if
          ({ data := l₁ ++ a✝ :: as✝ }.get { byteIdx := p } != { data := l₂ ++ b✝ :: bs✝ }.get { byteIdx := p }) =
            true then
        { byteIdx := p }
      else
        let_fun this := ⋯;
        firstDiffPos.loop { data := l₁ ++ a✝ :: as✝ } { data := l₂ ++ b✝ :: bs✝ } { byteIdx := stop }
          ({ data := l₁ ++ a✝ :: as✝ }.next { byteIdx := p })
    else { byteIdx := p }) =
    {
      byteIdx :=
        p +
          utf8Len
            (if decide (a✝ = b✝) = true then
                match List.takeWhile₂ (fun x x_1 => decide (x = x_1)) as✝ bs✝ with
                | (as', bs') => (a✝ :: as', b✝ :: bs')
              else ([], [])).fst }

case h_2
l₁ l₂ r₁ r₂ : List Char
stop p : Nat
hl₁ : p = utf8Len l₁
hl₂ : p = utf8Len l₂
hstop : stop = min (utf8Len l₁ + utf8Len r₁) (utf8Len l₂ + utf8Len r₂)
x✝² x✝¹ : List Char
x✝ : ∀ (a : Char) (as : List Char) (b : Char) (bs : List Char), r₁ = a :: as → r₂ = b :: bs → False
⊢ (if h : { byteIdx := p } < { byteIdx := stop } then
      if ({ data := l₁ ++ r₁ }.get { byteIdx := p } != { data := l₂ ++ r₂ }.get { byteIdx := p }) = true then
        { byteIdx := p }
      else
        let_fun this := ⋯;
        firstDiffPos.loop { data := l₁ ++ r₁ } { data := l₂ ++ r₂ } { byteIdx := stop }
          ({ data := l₁ ++ r₁ }.next { byteIdx := p })
    else { byteIdx := p }) =
    { byteIdx := p + utf8Len ([], []).fst }
tactic: split <;> unfold firstDiffPos.loop