Theorem: String.foldrAux_of_valid
File: Std/Data/String/Lemmas.lean

tactic: rw [← m.reverse_reverse]
state_before: α : Type u_1
f : Char → α → α
l m r : List Char
a : α
⊢ foldrAux f a { data := l ++ m ++ r } { byteIdx := utf8Len l + utf8Len m } { byteIdx := utf8Len l } = List.foldr f a m

tactic: induction m.reverse generalizing r a with (unfold foldrAux; simp)
| cons c m IH =>
  rw [dif_pos (by exact Nat.lt_add_of_pos_right add_csize_pos)]
  simp [← Nat.add_assoc, by simpa using prev_of_valid (l++m.reverse) c r]
  simp [by simpa using get_of_valid (l++m.reverse) (c::r)]
  simpa using IH (c::r) (f c a)
state_before: α : Type u_1
f : Char → α → α
l m r : List Char
a : α
⊢ foldrAux f a { data := l ++ List.reverse (List.reverse m) ++ r }
      { byteIdx := utf8Len l + utf8Len (List.reverse (List.reverse m)) } { byteIdx := utf8Len l } =
    List.foldr f a (List.reverse (List.reverse m))

tactic: unfold foldrAux
state_before: case nil
α : Type u_1
f : Char → α → α
l m r : List Char
a : α
⊢ foldrAux f a { data := l ++ List.reverse [] ++ r } { byteIdx := utf8Len l + utf8Len (List.reverse []) }
      { byteIdx := utf8Len l } =
    List.foldr f a (List.reverse [])

tactic: simp
state_before: case nil
α : Type u_1
f : Char → α → α
l m r : List Char
a : α
⊢ (if h : { byteIdx := utf8Len l } < { byteIdx := utf8Len l + utf8Len (List.reverse []) } then
      let_fun this :=
        (_ :
          (prev { data := l ++ List.reverse [] ++ r } { byteIdx := utf8Len l + utf8Len (List.reverse []) }).byteIdx <
            { byteIdx := utf8Len l + utf8Len (List.reverse []) }.byteIdx);
      let i := prev { data := l ++ List.reverse [] ++ r } { byteIdx := utf8Len l + utf8Len (List.reverse []) };
      let a := f (get { data := l ++ List.reverse [] ++ r } i) a;
      foldrAux f a { data := l ++ List.reverse [] ++ r } i { byteIdx := utf8Len l }
    else a) =
    List.foldr f a (List.reverse [])

tactic: rw [dif_pos (by exact Nat.lt_add_of_pos_right add_csize_pos)]
state_before: case cons
α : Type u_1
f : Char → α → α
l m✝ : List Char
c : Char
m : List Char
IH :
  ∀ (r : List Char) (a : α),
    foldrAux f a { data := l ++ List.reverse m ++ r } { byteIdx := utf8Len l + utf8Len (List.reverse m) }
        { byteIdx := utf8Len l } =
      List.foldr f a (List.reverse m)
r : List Char
a : α
⊢ (if h : utf8Len l < utf8Len l + (utf8Len m + csize c) then
      foldrAux f
        (f
          (get { data := l ++ (List.reverse m ++ c :: r) }
            (prev { data := l ++ (List.reverse m ++ c :: r) } { byteIdx := utf8Len l + (utf8Len m + csize c) }))
          a)
        { data := l ++ (List.reverse m ++ c :: r) }
        (prev { data := l ++ (List.reverse m ++ c :: r) } { byteIdx := utf8Len l + (utf8Len m + csize c) })
        { byteIdx := utf8Len l }
    else a) =
    List.foldl (fun x y => f y x) (f c a) m

tactic: simp [← Nat.add_assoc, by simpa using prev_of_valid (l++m.reverse) c r]
state_before: case cons
α : Type u_1
f : Char → α → α
l m✝ : List Char
c : Char
m : List Char
IH :
  ∀ (r : List Char) (a : α),
    foldrAux f a { data := l ++ List.reverse m ++ r } { byteIdx := utf8Len l + utf8Len (List.reverse m) }
        { byteIdx := utf8Len l } =
      List.foldr f a (List.reverse m)
r : List Char
a : α
⊢ foldrAux f
      (f
        (get { data := l ++ (List.reverse m ++ c :: r) }
          (prev { data := l ++ (List.reverse m ++ c :: r) } { byteIdx := utf8Len l + (utf8Len m + csize c) }))
        a)
      { data := l ++ (List.reverse m ++ c :: r) }
      (prev { data := l ++ (List.reverse m ++ c :: r) } { byteIdx := utf8Len l + (utf8Len m + csize c) })
      { byteIdx := utf8Len l } =
    List.foldl (fun x y => f y x) (f c a) m

tactic: simp [by simpa using get_of_valid (l++m.reverse) (c::r)]
state_before: case cons
α : Type u_1
f : Char → α → α
l m✝ : List Char
c : Char
m : List Char
IH :
  ∀ (r : List Char) (a : α),
    foldrAux f a { data := l ++ List.reverse m ++ r } { byteIdx := utf8Len l + utf8Len (List.reverse m) }
        { byteIdx := utf8Len l } =
      List.foldr f a (List.reverse m)
r : List Char
a : α
⊢ foldrAux f (f (get { data := l ++ (List.reverse m ++ c :: r) } { byteIdx := utf8Len l + utf8Len m }) a)
      { data := l ++ (List.reverse m ++ c :: r) } { byteIdx := utf8Len l + utf8Len m } { byteIdx := utf8Len l } =
    List.foldl (fun x y => f y x) (f c a) m

tactic: simpa using IH (c::r) (f c a)
state_before: case cons
α : Type u_1
f : Char → α → α
l m✝ : List Char
c : Char
m : List Char
IH :
  ∀ (r : List Char) (a : α),
    foldrAux f a { data := l ++ List.reverse m ++ r } { byteIdx := utf8Len l + utf8Len (List.reverse m) }
        { byteIdx := utf8Len l } =
      List.foldr f a (List.reverse m)
r : List Char
a : α
⊢ foldrAux f (f c a) { data := l ++ (List.reverse m ++ c :: r) } { byteIdx := utf8Len l + utf8Len m }
      { byteIdx := utf8Len l } =
    List.foldl (fun x y => f y x) (f c a) m

tactic: exact Nat.lt_add_of_pos_right add_csize_pos
state_before: α : Type u_1
f : Char → α → α
l m✝ : List Char
c : Char
m : List Char
IH :
  ∀ (r : List Char) (a : α),
    foldrAux f a { data := l ++ List.reverse m ++ r } { byteIdx := utf8Len l + utf8Len (List.reverse m) }
        { byteIdx := utf8Len l } =
      List.foldr f a (List.reverse m)
r : List Char
a : α
⊢ utf8Len l < utf8Len l + (utf8Len m + csize c)

tactic: simpa using prev_of_valid (l++m.reverse) c r
state_before: α : Type u_1
f : Char → α → α
l m✝ : List Char
c : Char
m : List Char
IH :
  ∀ (r : List Char) (a : α),
    foldrAux f a { data := l ++ List.reverse m ++ r } { byteIdx := utf8Len l + utf8Len (List.reverse m) }
        { byteIdx := utf8Len l } =
      List.foldr f a (List.reverse m)
r : List Char
a : α
⊢ ?m.168183

tactic: simpa using get_of_valid (l++m.reverse) (c::r)
state_before: α : Type u_1
f : Char → α → α
l m✝ : List Char
c : Char
m : List Char
IH :
  ∀ (r : List Char) (a : α),
    foldrAux f a { data := l ++ List.reverse m ++ r } { byteIdx := utf8Len l + utf8Len (List.reverse m) }
        { byteIdx := utf8Len l } =
      List.foldr f a (List.reverse m)
r : List Char
a : α
⊢ ?m.168355