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

tactic: unfold findAux List.takeWhile
state_before: p : Char → Bool
l r : List Char
⊢ { data := l ++ [] ++ r }.findAux p { byteIdx := utf8Len l + utf8Len [] } { byteIdx := utf8Len l } =
    { byteIdx := utf8Len l + utf8Len (List.takeWhile (fun x => !p x) []) }
state_after: p : Char → Bool
l r : List Char
⊢ (if h : { byteIdx := utf8Len l } < { byteIdx := utf8Len l + utf8Len [] } then
      if p ({ data := l ++ [] ++ r }.get { byteIdx := utf8Len l }) = true then { byteIdx := utf8Len l }
      else
        let_fun this := ⋯;
        { data := l ++ [] ++ r }.findAux p { byteIdx := utf8Len l + utf8Len [] }
          ({ data := l ++ [] ++ r }.next { byteIdx := utf8Len l })
    else { byteIdx := utf8Len l }) =
    { byteIdx := utf8Len l + utf8Len [] }

tactic: simp
state_before: p : Char → Bool
l r : List Char
⊢ (if h : { byteIdx := utf8Len l } < { byteIdx := utf8Len l + utf8Len [] } then
      if p ({ data := l ++ [] ++ r }.get { byteIdx := utf8Len l }) = true then { byteIdx := utf8Len l }
      else
        let_fun this := ⋯;
        { data := l ++ [] ++ r }.findAux p { byteIdx := utf8Len l + utf8Len [] }
          ({ data := l ++ [] ++ r }.next { byteIdx := utf8Len l })
    else { byteIdx := utf8Len l }) =
    { byteIdx := utf8Len l + utf8Len [] }
state_after: no goals

tactic: unfold findAux List.takeWhile
state_before: p : Char → Bool
l : List Char
c : Char
m r : List Char
⊢ { data := l ++ c :: m ++ r }.findAux p { byteIdx := utf8Len l + utf8Len (c :: m) } { byteIdx := utf8Len l } =
    { byteIdx := utf8Len l + utf8Len (List.takeWhile (fun x => !p x) (c :: m)) }
state_after: p : Char → Bool
l : List Char
c : Char
m r : List Char
⊢ (if h : { byteIdx := utf8Len l } < { byteIdx := utf8Len l + utf8Len (c :: m) } then
      if p ({ data := l ++ c :: m ++ r }.get { byteIdx := utf8Len l }) = true then { byteIdx := utf8Len l }
      else
        let_fun this := ⋯;
        { data := l ++ c :: m ++ r }.findAux p { byteIdx := utf8Len l + utf8Len (c :: m) }
          ({ data := l ++ c :: m ++ r }.next { byteIdx := utf8Len l })
    else { byteIdx := utf8Len l }) =
    {
      byteIdx :=
        utf8Len l +
          utf8Len
            (match !p c with
            | true => c :: List.takeWhile (fun x => !p x) m
            | false => []) }

tactic: rw [dif_pos (by exact Nat.lt_add_of_pos_right add_csize_pos)]
state_before: p : Char → Bool
l : List Char
c : Char
m r : List Char
⊢ (if h : { byteIdx := utf8Len l } < { byteIdx := utf8Len l + utf8Len (c :: m) } then
      if p ({ data := l ++ c :: m ++ r }.get { byteIdx := utf8Len l }) = true then { byteIdx := utf8Len l }
      else
        let_fun this := ⋯;
        { data := l ++ c :: m ++ r }.findAux p { byteIdx := utf8Len l + utf8Len (c :: m) }
          ({ data := l ++ c :: m ++ r }.next { byteIdx := utf8Len l })
    else { byteIdx := utf8Len l }) =
    {
      byteIdx :=
        utf8Len l +
          utf8Len
            (match !p c with
            | true => c :: List.takeWhile (fun x => !p x) m
            | false => []) }
state_after: p : Char → Bool
l : List Char
c : Char
m r : List Char
⊢ (if p ({ data := l ++ c :: m ++ r }.get { byteIdx := utf8Len l }) = true then { byteIdx := utf8Len l }
    else
      let_fun this := ⋯;
      { data := l ++ c :: m ++ r }.findAux p { byteIdx := utf8Len l + utf8Len (c :: m) }
        ({ data := l ++ c :: m ++ r }.next { byteIdx := utf8Len l })) =
    {
      byteIdx :=
        utf8Len l +
          utf8Len
            (match !p c with
            | true => c :: List.takeWhile (fun x => !p x) m
            | false => []) }

tactic: have h1 := get_of_valid l (c::m++r)
state_before: p : Char → Bool
l : List Char
c : Char
m r : List Char
⊢ (if p ({ data := l ++ c :: m ++ r }.get { byteIdx := utf8Len l }) = true then { byteIdx := utf8Len l }
    else
      let_fun this := ⋯;
      { data := l ++ c :: m ++ r }.findAux p { byteIdx := utf8Len l + utf8Len (c :: m) }
        ({ data := l ++ c :: m ++ r }.next { byteIdx := utf8Len l })) =
    {
      byteIdx :=
        utf8Len l +
          utf8Len
            (match !p c with
            | true => c :: List.takeWhile (fun x => !p x) m
            | false => []) }
state_after: p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ (c :: m ++ r) }.get { byteIdx := utf8Len l } = (c :: m ++ r).headD default
⊢ (if p ({ data := l ++ c :: m ++ r }.get { byteIdx := utf8Len l }) = true then { byteIdx := utf8Len l }
    else
      let_fun this := ⋯;
      { data := l ++ c :: m ++ r }.findAux p { byteIdx := utf8Len l + utf8Len (c :: m) }
        ({ data := l ++ c :: m ++ r }.next { byteIdx := utf8Len l })) =
    {
      byteIdx :=
        utf8Len l +
          utf8Len
            (match !p c with
            | true => c :: List.takeWhile (fun x => !p x) m
            | false => []) }

tactic: have h2 := next_of_valid l c (m++r)
state_before: p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ (c :: m ++ r) }.get { byteIdx := utf8Len l } = (c :: m ++ r).headD default
⊢ (if p ({ data := l ++ c :: m ++ r }.get { byteIdx := utf8Len l }) = true then { byteIdx := utf8Len l }
    else
      let_fun this := ⋯;
      { data := l ++ c :: m ++ r }.findAux p { byteIdx := utf8Len l + utf8Len (c :: m) }
        ({ data := l ++ c :: m ++ r }.next { byteIdx := utf8Len l })) =
    {
      byteIdx :=
        utf8Len l +
          utf8Len
            (match !p c with
            | true => c :: List.takeWhile (fun x => !p x) m
            | false => []) }
state_after: p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ (c :: m ++ r) }.get { byteIdx := utf8Len l } = (c :: m ++ r).headD default
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
⊢ (if p ({ data := l ++ c :: m ++ r }.get { byteIdx := utf8Len l }) = true then { byteIdx := utf8Len l }
    else
      let_fun this := ⋯;
      { data := l ++ c :: m ++ r }.findAux p { byteIdx := utf8Len l + utf8Len (c :: m) }
        ({ data := l ++ c :: m ++ r }.next { byteIdx := utf8Len l })) =
    {
      byteIdx :=
        utf8Len l +
          utf8Len
            (match !p c with
            | true => c :: List.takeWhile (fun x => !p x) m
            | false => []) }

tactic: simp only [List.cons_append, Char.reduceDefault, List.headD_cons] at h1 h2
state_before: p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ (c :: m ++ r) }.get { byteIdx := utf8Len l } = (c :: m ++ r).headD default
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
⊢ (if p ({ data := l ++ c :: m ++ r }.get { byteIdx := utf8Len l }) = true then { byteIdx := utf8Len l }
    else
      let_fun this := ⋯;
      { data := l ++ c :: m ++ r }.findAux p { byteIdx := utf8Len l + utf8Len (c :: m) }
        ({ data := l ++ c :: m ++ r }.next { byteIdx := utf8Len l })) =
    {
      byteIdx :=
        utf8Len l +
          utf8Len
            (match !p c with
            | true => c :: List.takeWhile (fun x => !p x) m
            | false => []) }
state_after: p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ c :: (m ++ r) }.get { byteIdx := utf8Len l } = c
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
⊢ (if p ({ data := l ++ c :: m ++ r }.get { byteIdx := utf8Len l }) = true then { byteIdx := utf8Len l }
    else
      let_fun this := ⋯;
      { data := l ++ c :: m ++ r }.findAux p { byteIdx := utf8Len l + utf8Len (c :: m) }
        ({ data := l ++ c :: m ++ r }.next { byteIdx := utf8Len l })) =
    {
      byteIdx :=
        utf8Len l +
          utf8Len
            (match !p c with
            | true => c :: List.takeWhile (fun x => !p x) m
            | false => []) }

tactic: simp only [List.append_assoc, List.cons_append, h1, utf8Len_cons, h2]
state_before: p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ c :: (m ++ r) }.get { byteIdx := utf8Len l } = c
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
⊢ (if p ({ data := l ++ c :: m ++ r }.get { byteIdx := utf8Len l }) = true then { byteIdx := utf8Len l }
    else
      let_fun this := ⋯;
      { data := l ++ c :: m ++ r }.findAux p { byteIdx := utf8Len l + utf8Len (c :: m) }
        ({ data := l ++ c :: m ++ r }.next { byteIdx := utf8Len l })) =
    {
      byteIdx :=
        utf8Len l +
          utf8Len
            (match !p c with
            | true => c :: List.takeWhile (fun x => !p x) m
            | false => []) }
state_after: p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ c :: (m ++ r) }.get { byteIdx := utf8Len l } = c
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
⊢ (if p c = true then { byteIdx := utf8Len l }
    else
      { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + (utf8Len m + c.utf8Size) }
        { byteIdx := utf8Len l + c.utf8Size }) =
    {
      byteIdx :=
        utf8Len l +
          utf8Len
            (match !p c with
            | true => c :: List.takeWhile (fun x => !p x) m
            | false => []) }

tactic: cases p c
state_before: p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ c :: (m ++ r) }.get { byteIdx := utf8Len l } = c
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
⊢ (if p c = true then { byteIdx := utf8Len l }
    else
      { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + (utf8Len m + c.utf8Size) }
        { byteIdx := utf8Len l + c.utf8Size }) =
    {
      byteIdx :=
        utf8Len l +
          utf8Len
            (match !p c with
            | true => c :: List.takeWhile (fun x => !p x) m
            | false => []) }
state_after: case false
p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ c :: (m ++ r) }.get { byteIdx := utf8Len l } = c
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
⊢ (if false = true then { byteIdx := utf8Len l }
    else
      { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + (utf8Len m + c.utf8Size) }
        { byteIdx := utf8Len l + c.utf8Size }) =
    {
      byteIdx :=
        utf8Len l +
          utf8Len
            (match !false with
            | true => c :: List.takeWhile (fun x => !p x) m
            | false => []) }

case true
p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ c :: (m ++ r) }.get { byteIdx := utf8Len l } = c
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
⊢ (if true = true then { byteIdx := utf8Len l }
    else
      { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + (utf8Len m + c.utf8Size) }
        { byteIdx := utf8Len l + c.utf8Size }) =
    {
      byteIdx :=
        utf8Len l +
          utf8Len
            (match !true with
            | true => c :: List.takeWhile (fun x => !p x) m
            | false => []) }

tactic: exact Nat.lt_add_of_pos_right add_csize_pos
state_before: p : Char → Bool
l : List Char
c : Char
m r : List Char
⊢ { byteIdx := utf8Len l } < { byteIdx := utf8Len l + utf8Len (c :: m) }
state_after: no goals

tactic: simp only [Bool.false_eq_true, ↓reduceIte, Bool.not_false, utf8Len_cons]
state_before: case false
p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ c :: (m ++ r) }.get { byteIdx := utf8Len l } = c
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
⊢ (if false = true then { byteIdx := utf8Len l }
    else
      { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + (utf8Len m + c.utf8Size) }
        { byteIdx := utf8Len l + c.utf8Size }) =
    {
      byteIdx :=
        utf8Len l +
          utf8Len
            (match !false with
            | true => c :: List.takeWhile (fun x => !p x) m
            | false => []) }
state_after: case false
p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ c :: (m ++ r) }.get { byteIdx := utf8Len l } = c
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
⊢ { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + (utf8Len m + c.utf8Size) }
      { byteIdx := utf8Len l + c.utf8Size } =
    { byteIdx := utf8Len l + (utf8Len (List.takeWhile (fun x => !p x) m) + c.utf8Size) }

tactic: have foo := findAux_of_valid p (l++[c]) m r
state_before: case false
p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ c :: (m ++ r) }.get { byteIdx := utf8Len l } = c
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
⊢ { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + (utf8Len m + c.utf8Size) }
      { byteIdx := utf8Len l + c.utf8Size } =
    { byteIdx := utf8Len l + (utf8Len (List.takeWhile (fun x => !p x) m) + c.utf8Size) }
state_after: case false
p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ c :: (m ++ r) }.get { byteIdx := utf8Len l } = c
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
foo :
  { data := l ++ [c] ++ m ++ r }.findAux p { byteIdx := utf8Len (l ++ [c]) + utf8Len m }
      { byteIdx := utf8Len (l ++ [c]) } =
    { byteIdx := utf8Len (l ++ [c]) + utf8Len (List.takeWhile (fun x => !p x) m) }
⊢ { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + (utf8Len m + c.utf8Size) }
      { byteIdx := utf8Len l + c.utf8Size } =
    { byteIdx := utf8Len l + (utf8Len (List.takeWhile (fun x => !p x) m) + c.utf8Size) }

tactic: simp only [List.append_assoc, List.singleton_append, List.cons_append, utf8Len_append,
  utf8Len_cons, utf8Len_nil, Nat.zero_add, List.nil_append] at foo
state_before: case false
p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ c :: (m ++ r) }.get { byteIdx := utf8Len l } = c
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
foo :
  { data := l ++ [c] ++ m ++ r }.findAux p { byteIdx := utf8Len (l ++ [c]) + utf8Len m }
      { byteIdx := utf8Len (l ++ [c]) } =
    { byteIdx := utf8Len (l ++ [c]) + utf8Len (List.takeWhile (fun x => !p x) m) }
⊢ { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + (utf8Len m + c.utf8Size) }
      { byteIdx := utf8Len l + c.utf8Size } =
    { byteIdx := utf8Len l + (utf8Len (List.takeWhile (fun x => !p x) m) + c.utf8Size) }
state_after: case false
p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ c :: (m ++ r) }.get { byteIdx := utf8Len l } = c
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
foo :
  { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + c.utf8Size + utf8Len m }
      { byteIdx := utf8Len l + c.utf8Size } =
    { byteIdx := utf8Len l + c.utf8Size + utf8Len (List.takeWhile (fun x => !p x) m) }
⊢ { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + (utf8Len m + c.utf8Size) }
      { byteIdx := utf8Len l + c.utf8Size } =
    { byteIdx := utf8Len l + (utf8Len (List.takeWhile (fun x => !p x) m) + c.utf8Size) }

tactic: rw [Nat.add_right_comm, Nat.add_assoc] at foo
state_before: case false
p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ c :: (m ++ r) }.get { byteIdx := utf8Len l } = c
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
foo :
  { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + c.utf8Size + utf8Len m }
      { byteIdx := utf8Len l + c.utf8Size } =
    { byteIdx := utf8Len l + c.utf8Size + utf8Len (List.takeWhile (fun x => !p x) m) }
⊢ { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + (utf8Len m + c.utf8Size) }
      { byteIdx := utf8Len l + c.utf8Size } =
    { byteIdx := utf8Len l + (utf8Len (List.takeWhile (fun x => !p x) m) + c.utf8Size) }
state_after: case false
p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ c :: (m ++ r) }.get { byteIdx := utf8Len l } = c
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
foo :
  { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + (utf8Len m + c.utf8Size) }
      { byteIdx := utf8Len l + c.utf8Size } =
    { byteIdx := utf8Len l + c.utf8Size + utf8Len (List.takeWhile (fun x => !p x) m) }
⊢ { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + (utf8Len m + c.utf8Size) }
      { byteIdx := utf8Len l + c.utf8Size } =
    { byteIdx := utf8Len l + (utf8Len (List.takeWhile (fun x => !p x) m) + c.utf8Size) }

tactic: rw [foo, Nat.add_right_comm, Nat.add_assoc]
state_before: case false
p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ c :: (m ++ r) }.get { byteIdx := utf8Len l } = c
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
foo :
  { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + (utf8Len m + c.utf8Size) }
      { byteIdx := utf8Len l + c.utf8Size } =
    { byteIdx := utf8Len l + c.utf8Size + utf8Len (List.takeWhile (fun x => !p x) m) }
⊢ { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + (utf8Len m + c.utf8Size) }
      { byteIdx := utf8Len l + c.utf8Size } =
    { byteIdx := utf8Len l + (utf8Len (List.takeWhile (fun x => !p x) m) + c.utf8Size) }
state_after: no goals

tactic: simp
state_before: case true
p : Char → Bool
l : List Char
c : Char
m r : List Char
h1 : { data := l ++ c :: (m ++ r) }.get { byteIdx := utf8Len l } = c
h2 : { data := l ++ c :: (m ++ r) }.next { byteIdx := utf8Len l } = { byteIdx := utf8Len l + c.utf8Size }
⊢ (if true = true then { byteIdx := utf8Len l }
    else
      { data := l ++ c :: (m ++ r) }.findAux p { byteIdx := utf8Len l + (utf8Len m + c.utf8Size) }
        { byteIdx := utf8Len l + c.utf8Size }) =
    {
      byteIdx :=
        utf8Len l +
          utf8Len
            (match !true with
            | true => c :: List.takeWhile (fun x => !p x) m
            | false => []) }
state_after: no goals