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

tactic: unfold revFindAux List.dropWhile
state_before: p : Char → Bool
r : List Char
⊢ revFindAux { data := List.reverse [] ++ r } p { byteIdx := utf8Len [] } =
    Option.map (fun x => { byteIdx := utf8Len x }) (List.tail? (List.dropWhile (fun x => !p x) []))

tactic: simp
state_before: p : Char → Bool
r : List Char
⊢ (if h : { byteIdx := utf8Len [] } = 0 then none
    else
      let_fun this :=
        (_ :
          (prev { data := List.reverse [] ++ r } { byteIdx := utf8Len [] }).byteIdx <
            { byteIdx := utf8Len [] }.byteIdx);
      let pos := prev { data := List.reverse [] ++ r } { byteIdx := utf8Len [] };
      if p (get { data := List.reverse [] ++ r } pos) = true then some pos
      else revFindAux { data := List.reverse [] ++ r } p pos) =
    Option.map (fun x => { byteIdx := utf8Len x }) (List.tail? [])

tactic: unfold revFindAux List.dropWhile
state_before: p : Char → Bool
c : Char
l r : List Char
⊢ revFindAux { data := List.reverse (c :: l) ++ r } p { byteIdx := utf8Len (c :: l) } =
    Option.map (fun x => { byteIdx := utf8Len x }) (List.tail? (List.dropWhile (fun x => !p x) (c :: l)))

tactic: rw [dif_neg (by exact Pos.ne_of_gt add_csize_pos)]
state_before: p : Char → Bool
c : Char
l r : List Char
⊢ (if h : { byteIdx := utf8Len (c :: l) } = 0 then none
    else
      let_fun this :=
        (_ :
          (prev { data := List.reverse (c :: l) ++ r } { byteIdx := utf8Len (c :: l) }).byteIdx <
            { byteIdx := utf8Len (c :: l) }.byteIdx);
      let pos := prev { data := List.reverse (c :: l) ++ r } { byteIdx := utf8Len (c :: l) };
      if p (get { data := List.reverse (c :: l) ++ r } pos) = true then some pos
      else revFindAux { data := List.reverse (c :: l) ++ r } p pos) =
    Option.map (fun x => { byteIdx := utf8Len x })
      (List.tail?
        (match !p c with
        | true => List.dropWhile (fun x => !p x) l
        | false => c :: l))

tactic: have h1 := get_of_valid l.reverse (c::r)
state_before: p : Char → Bool
c : Char
l r : List Char
⊢ (let_fun this :=
      (_ :
        (prev { data := List.reverse (c :: l) ++ r } { byteIdx := utf8Len (c :: l) }).byteIdx <
          { byteIdx := utf8Len (c :: l) }.byteIdx);
    let pos := prev { data := List.reverse (c :: l) ++ r } { byteIdx := utf8Len (c :: l) };
    if p (get { data := List.reverse (c :: l) ++ r } pos) = true then some pos
    else revFindAux { data := List.reverse (c :: l) ++ r } p pos) =
    Option.map (fun x => { byteIdx := utf8Len x })
      (List.tail?
        (match !p c with
        | true => List.dropWhile (fun x => !p x) l
        | false => c :: l))

tactic: have h2 := prev_of_valid l.reverse c r
state_before: p : Char → Bool
c : Char
l r : List Char
h1 : get { data := List.reverse l ++ c :: r } { byteIdx := utf8Len (List.reverse l) } = List.headD (c :: r) default
⊢ (let_fun this :=
      (_ :
        (prev { data := List.reverse (c :: l) ++ r } { byteIdx := utf8Len (c :: l) }).byteIdx <
          { byteIdx := utf8Len (c :: l) }.byteIdx);
    let pos := prev { data := List.reverse (c :: l) ++ r } { byteIdx := utf8Len (c :: l) };
    if p (get { data := List.reverse (c :: l) ++ r } pos) = true then some pos
    else revFindAux { data := List.reverse (c :: l) ++ r } p pos) =
    Option.map (fun x => { byteIdx := utf8Len x })
      (List.tail?
        (match !p c with
        | true => List.dropWhile (fun x => !p x) l
        | false => c :: l))

tactic: simp at h1 h2
state_before: p : Char → Bool
c : Char
l r : List Char
h1 : get { data := List.reverse l ++ c :: r } { byteIdx := utf8Len (List.reverse l) } = List.headD (c :: r) default
h2 :
  prev { data := List.reverse l ++ c :: r } { byteIdx := utf8Len (List.reverse l) + csize c } =
    { byteIdx := utf8Len (List.reverse l) }
⊢ (let_fun this :=
      (_ :
        (prev { data := List.reverse (c :: l) ++ r } { byteIdx := utf8Len (c :: l) }).byteIdx <
          { byteIdx := utf8Len (c :: l) }.byteIdx);
    let pos := prev { data := List.reverse (c :: l) ++ r } { byteIdx := utf8Len (c :: l) };
    if p (get { data := List.reverse (c :: l) ++ r } pos) = true then some pos
    else revFindAux { data := List.reverse (c :: l) ++ r } p pos) =
    Option.map (fun x => { byteIdx := utf8Len x })
      (List.tail?
        (match !p c with
        | true => List.dropWhile (fun x => !p x) l
        | false => c :: l))

tactic: simp [h1, h2]
state_before: p : Char → Bool
c : Char
l r : List Char
h1 : get { data := List.reverse l ++ c :: r } { byteIdx := utf8Len l } = c
h2 : prev { data := List.reverse l ++ c :: r } { byteIdx := utf8Len l + csize c } = { byteIdx := utf8Len l }
⊢ (let_fun this :=
      (_ :
        (prev { data := List.reverse (c :: l) ++ r } { byteIdx := utf8Len (c :: l) }).byteIdx <
          { byteIdx := utf8Len (c :: l) }.byteIdx);
    let pos := prev { data := List.reverse (c :: l) ++ r } { byteIdx := utf8Len (c :: l) };
    if p (get { data := List.reverse (c :: l) ++ r } pos) = true then some pos
    else revFindAux { data := List.reverse (c :: l) ++ r } p pos) =
    Option.map (fun x => { byteIdx := utf8Len x })
      (List.tail?
        (match !p c with
        | true => List.dropWhile (fun x => !p x) l
        | false => c :: l))

tactic: cases p c <;> simp
state_before: p : Char → Bool
c : Char
l r : List Char
h1 : get { data := List.reverse l ++ c :: r } { byteIdx := utf8Len l } = c
h2 : prev { data := List.reverse l ++ c :: r } { byteIdx := utf8Len l + csize c } = { byteIdx := utf8Len l }
⊢ (if p c = true then some { byteIdx := utf8Len l }
    else revFindAux { data := List.reverse l ++ c :: r } p { byteIdx := utf8Len l }) =
    Option.map (fun x => { byteIdx := utf8Len x })
      (List.tail?
        (match !p c with
        | true => List.dropWhile (fun x => !p x) l
        | false => c :: l))

tactic: simpa using revFindAux_of_valid p l (c::r)
state_before: case false
p : Char → Bool
c : Char
l r : List Char
h1 : get { data := List.reverse l ++ c :: r } { byteIdx := utf8Len l } = c
h2 : prev { data := List.reverse l ++ c :: r } { byteIdx := utf8Len l + csize c } = { byteIdx := utf8Len l }
⊢ revFindAux { data := List.reverse l ++ c :: r } p { byteIdx := utf8Len l } =
    Option.map (fun x => { byteIdx := utf8Len x }) (List.tail? (List.dropWhile (fun x => !p x) l))

tactic: exact Pos.ne_of_gt add_csize_pos
state_before: p : Char → Bool
c : Char
l r : List Char
⊢ ¬{ byteIdx := utf8Len (c :: l) } = 0