Documentation

Batteries.Data.String.Lemmas

theorem String.lt_antisymm {s₁ s₂ : String} (h₁ : ¬s₁ < s₂) (h₂ : ¬s₂ < s₁) :
s₁ = s₂
@[deprecated String.length_ofList (since := "2025-10-31")]
theorem String.mk_length (s : List Char) :
(ofList s).length = s.length
theorem String.Pos.Raw.offsetBy_eq {p q : Raw} :
p.offsetBy q = { byteIdx := q.byteIdx + p.byteIdx }
@[inline]
def String.utf8Len :
List CharNat

The UTF-8 byte length of a list of characters. (This is intended for specification purposes.)

Equations
Instances For
    theorem String.utf8ByteSize_ofList (cs : List Char) :
    (ofList cs).utf8ByteSize = utf8Len cs
    @[deprecated String.utf8ByteSize_ofList (since := "2025-10-31")]
    theorem String.utf8ByteSize_mk (cs : List Char) :
    (ofList cs).utf8ByteSize = utf8Len cs
    @[simp]
    theorem String.utf8Len_cons (c : Char) (cs : List Char) :
    utf8Len (c :: cs) = utf8Len cs + c.utf8Size
    @[simp]
    theorem String.utf8Len_append (cs₁ cs₂ : List Char) :
    utf8Len (cs₁ ++ cs₂) = utf8Len cs₁ + utf8Len cs₂
    theorem String.utf8Len_reverseAux (cs₁ cs₂ : List Char) :
    utf8Len (cs₁.reverseAux cs₂) = utf8Len cs₁ + utf8Len cs₂
    @[simp]
    theorem String.utf8Len_reverse (cs : List Char) :
    utf8Len cs.reverse = utf8Len cs
    @[simp]
    theorem String.utf8Len_eq_zero {l : List Char} :
    utf8Len l = 0 l = []
    theorem String.utf8Len_le_of_sublist {cs₁ cs₂ : List Char} :
    cs₁.Sublist cs₂utf8Len cs₁ utf8Len cs₂
    theorem String.utf8Len_le_of_infix {cs₁ cs₂ : List Char} (h : cs₁ <:+: cs₂) :
    utf8Len cs₁ utf8Len cs₂
    theorem String.utf8Len_le_of_suffix {cs₁ cs₂ : List Char} (h : cs₁ <:+ cs₂) :
    utf8Len cs₁ utf8Len cs₂
    theorem String.utf8Len_le_of_prefix {cs₁ cs₂ : List Char} (h : cs₁ <+: cs₂) :
    utf8Len cs₁ utf8Len cs₂
    @[simp]
    theorem String.rawEndPos_ofList (cs : List Char) :
    (ofList cs).rawEndPos = { byteIdx := utf8Len cs }
    @[deprecated String.rawEndPos_ofList (since := "2025-10-31")]
    theorem String.rawEndPos_asString (cs : List Char) :
    (ofList cs).rawEndPos = { byteIdx := utf8Len cs }
    @[deprecated String.rawEndPos_ofList (since := "2025-10-21")]
    theorem String.endPos_asString (cs : List Char) :
    (ofList cs).rawEndPos = { byteIdx := utf8Len cs }
    @[deprecated String.rawEndPos_ofList (since := "2025-10-21")]
    theorem String.rawEndPos_mk (cs : List Char) :
    (ofList cs).rawEndPos = { byteIdx := utf8Len cs }
    @[deprecated String.rawEndPos_ofList (since := "2025-10-21")]
    theorem String.endPos_mk (cs : List Char) :
    (ofList cs).rawEndPos = { byteIdx := utf8Len cs }
    @[simp]
    theorem String.utf8Len_toList (s : String) :
    utf8Len s.toList = s.utf8ByteSize
    @[deprecated String.utf8Len_toList (since := "2025-10-21")]
    theorem String.utf8Len_data (s : String) :
    utf8Len s.toList = s.utf8ByteSize
    theorem String.Pos.Raw.lt_addChar (p : Raw) (c : Char) :
    p < p + c
    inductive String.Pos.Raw.Valid :
    StringRawProp

    A string position is valid if it is equal to the UTF-8 length of an initial substring of s.

    • mk (cs cs' : List Char) {p : Raw} (hp : p.byteIdx = utf8Len cs) : Valid (ofList (cs ++ cs')) p

      A string position is valid if it is equal to the UTF-8 length of an initial substring of s.

    Instances For
      theorem String.Pos.Raw.Valid.intro {s : String} {p : Raw} (h : (cs : List Char), (cs' : List Char), cs ++ cs' = s.toList p.byteIdx = utf8Len cs) :
      Valid s p
      theorem String.Pos.Raw.Valid.exists {s : String} {p : Raw} :
      Valid s p (cs : List Char), (cs' : List Char), ofList (cs ++ cs') = s p = { byteIdx := utf8Len cs }
      @[simp]
      theorem String.Pos.Raw.valid_zero {s : String} :
      Valid s 0
      @[simp]
      theorem String.Pos.Raw.valid_rawEndPos {s : String} :
      Valid s s.rawEndPos
      @[deprecated String.Pos.Raw.valid_rawEndPos (since := "2025-10-21")]
      theorem String.Pos.Raw.valid_endPos {s : String} :
      Valid s s.rawEndPos
      theorem String.Pos.Raw.Valid.le_rawEndPos {s : String} {p : Raw} :
      Valid s pp s.rawEndPos
      @[deprecated String.Pos.Raw.Valid.le_rawEndPos (since := "2025-10-21")]
      theorem String.Pos.Raw.Valid.le_endPos {s : String} {p : Raw} :
      Valid s pp s.rawEndPos
      @[deprecated String.rawEndPos_eq_zero_iff (since := "2025-10-21")]
      theorem String.endPos_eq_zero (s : String) :
      s.rawEndPos = 0 s = ""
      def String.utf8InductionOn {motive : List CharPos.RawSort u} (s : List Char) (i p : Pos.Raw) (nil : (i : Pos.Raw) → motive [] i) (eq : (c : Char) → (cs : List Char) → motive (c :: cs) p) (ind : (c : Char) → (cs : List Char) → (i : Pos.Raw) → i pmotive cs (i + c)motive (c :: cs) i) :
      motive s i

      Induction along the valid positions in a list of characters. (This definition is intended only for specification purposes.)

      Equations
      Instances For
        theorem String.utf8GetAux_add_right_cancel (s : List Char) (i p n : Nat) :
        Pos.Raw.utf8GetAux s { byteIdx := i + n } { byteIdx := p + n } = Pos.Raw.utf8GetAux s { byteIdx := i } { byteIdx := p }
        theorem String.utf8GetAux_addChar_right_cancel (s : List Char) (i p : Pos.Raw) (c : Char) :
        Pos.Raw.utf8GetAux s (i + c) (p + c) = Pos.Raw.utf8GetAux s i p
        theorem String.utf8GetAux_of_valid (cs cs' : List Char) {i p : Nat} (hp : i + utf8Len cs = p) :
        Pos.Raw.utf8GetAux (cs ++ cs') { byteIdx := i } { byteIdx := p } = cs'.headD default
        theorem String.get_of_valid (cs cs' : List Char) :
        Pos.Raw.get (ofList (cs ++ cs')) { byteIdx := utf8Len cs } = cs'.headD default
        theorem String.get_cons_addChar (c : Char) (cs : List Char) (i : Pos.Raw) :
        Pos.Raw.get (ofList (c :: cs)) (i + c) = Pos.Raw.get (ofList cs) i
        theorem String.utf8GetAux?_of_valid (cs cs' : List Char) {i p : Nat} (hp : i + utf8Len cs = p) :
        Pos.Raw.utf8GetAux? (cs ++ cs') { byteIdx := i } { byteIdx := p } = cs'.head?
        theorem String.get?_of_valid (cs cs' : List Char) :
        Pos.Raw.get? (ofList (cs ++ cs')) { byteIdx := utf8Len cs } = cs'.head?
        theorem String.utf8SetAux_of_valid (c' : Char) (cs cs' : List Char) {i p : Nat} (hp : i + utf8Len cs = p) :
        Pos.Raw.utf8SetAux c' (cs ++ cs') { byteIdx := i } { byteIdx := p } = cs ++ List.modifyHead (fun (x : Char) => c') cs'
        theorem String.set_of_valid (cs cs' : List Char) (c' : Char) :
        Pos.Raw.set (ofList (cs ++ cs')) { byteIdx := utf8Len cs } c' = ofList (cs ++ List.modifyHead (fun (x : Char) => c') cs')
        theorem String.modify_of_valid {f : CharChar} (cs cs' : List Char) :
        Pos.Raw.modify (ofList (cs ++ cs')) { byteIdx := utf8Len cs } f = ofList (cs ++ List.modifyHead f cs')
        theorem String.next_of_valid' (cs cs' : List Char) :
        Pos.Raw.next (ofList (cs ++ cs')) { byteIdx := utf8Len cs } = { byteIdx := utf8Len cs + (cs'.headD default).utf8Size }
        theorem String.next_of_valid (cs : List Char) (c : Char) (cs' : List Char) :
        Pos.Raw.next (ofList (cs ++ c :: cs')) { byteIdx := utf8Len cs } = { byteIdx := utf8Len cs + c.utf8Size }
        @[simp]
        theorem String.atEnd_iff (s : String) (p : Pos.Raw) :
        Pos.Raw.atEnd s p = true s.rawEndPos p
        theorem String.valid_next {s : String} {p : Pos.Raw} (h : Pos.Raw.Valid s p) (h₂ : p < s.rawEndPos) :
        Pos.Raw.Valid s (Pos.Raw.next s p)
        theorem String.utf8PrevAux_of_valid {cs cs' : List Char} {c : Char} {i p : Nat} (hp : i + (utf8Len cs + c.utf8Size) = p) :
        Pos.Raw.utf8PrevAux (cs ++ c :: cs') { byteIdx := i } { byteIdx := p } = { byteIdx := i + utf8Len cs }
        theorem String.prev_of_valid (cs : List Char) (c : Char) (cs' : List Char) :
        Pos.Raw.prev (ofList (cs ++ c :: cs')) { byteIdx := utf8Len cs + c.utf8Size } = { byteIdx := utf8Len cs }
        theorem String.prev_of_valid' (cs cs' : List Char) :
        Pos.Raw.prev (ofList (cs ++ cs')) { byteIdx := utf8Len cs } = { byteIdx := utf8Len cs.dropLast }
        theorem String.front_eq (s : String) :
        Legacy.front s = s.toList.headD default
        theorem String.back_eq_get_prev_rawEndPos {s : String} :
        Legacy.back s = Pos.Raw.get s (Pos.Raw.prev s s.rawEndPos)
        theorem String.back_eq (s : String) :
        Legacy.back s = s.toList.getLastD default
        theorem String.atEnd_of_valid (cs cs' : List Char) :
        Pos.Raw.atEnd (ofList (cs ++ cs')) { byteIdx := utf8Len cs } = true cs' = []
        theorem String.posOfAux_eq (s : String) (c : Char) :
        Legacy.posOfAux s c = Legacy.findAux s fun (x : Char) => x == c
        theorem String.posOf_eq (s : String) (c : Char) :
        Legacy.posOf s c = Legacy.find s fun (x : Char) => x == c
        theorem String.revPosOfAux_eq (s : String) (c : Char) :
        Legacy.revPosOfAux s c = Legacy.revFindAux s fun (x : Char) => x == c
        theorem String.revPosOf_eq (s : String) (c : Char) :
        Legacy.revPosOf s c = Legacy.revFind s fun (x : Char) => x == c
        theorem String.findAux_of_valid (p : CharBool) (l m r : List Char) :
        Legacy.findAux (ofList (l ++ m ++ r)) p { byteIdx := utf8Len l + utf8Len m } { byteIdx := utf8Len l } = { byteIdx := utf8Len l + utf8Len (List.takeWhile (fun (x : Char) => !p x) m) }
        theorem String.find_of_valid (p : CharBool) (s : String) :
        Legacy.find s p = { byteIdx := utf8Len (List.takeWhile (fun (x : Char) => !p x) s.toList) }
        theorem String.revFindAux_of_valid (p : CharBool) (l r : List Char) :
        Legacy.revFindAux (ofList (l.reverse ++ r)) p { byteIdx := utf8Len l } = Option.map (fun (x : List Char) => { byteIdx := utf8Len x }) (List.dropWhile (fun (x : Char) => !p x) l).tail?
        theorem String.revFind_of_valid (p : CharBool) (s : String) :
        Legacy.revFind s p = Option.map (fun (x : List Char) => { byteIdx := utf8Len x }) (List.dropWhile (fun (x : Char) => !p x) s.toList.reverse).tail?
        @[irreducible]
        theorem String.firstDiffPos_loop_eq (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 (ofList (l₁ ++ r₁)) (ofList (l₂ ++ r₂)) { byteIdx := stop } { byteIdx := p } = { byteIdx := p + utf8Len (List.takeWhile₂ (fun (x1 x2 : Char) => decide (x1 = x2)) r₁ r₂).fst }
        theorem String.firstDiffPos_eq (a b : String) :
        a.firstDiffPos b = { byteIdx := utf8Len (List.takeWhile₂ (fun (x1 x2 : Char) => decide (x1 = x2)) a.toList b.toList).fst }
        theorem String.Pos.Raw.extract.go₂_add_right_cancel (s : List Char) (i e n : Nat) :
        go₂ s { byteIdx := i + n } { byteIdx := e + n } = go₂ s { byteIdx := i } { byteIdx := e }
        theorem String.Pos.Raw.extract.go₂_append_left (s t : List Char) (i e : Nat) :
        e = utf8Len s + igo₂ (s ++ t) { byteIdx := i } { byteIdx := e } = s
        theorem String.Pos.Raw.extract.go₁_add_right_cancel (s : List Char) (i b e n : Nat) :
        go₁ s { byteIdx := i + n } { byteIdx := b + n } { byteIdx := e + n } = go₁ s { byteIdx := i } { byteIdx := b } { byteIdx := e }
        theorem String.Pos.Raw.extract.go₁_cons_addChar (c : Char) (cs : List Char) (b e : Raw) :
        go₁ (c :: cs) 0 (b + c) (e + c) = go₁ cs 0 b e
        theorem String.Pos.Raw.extract.go₁_append_right (s t : List Char) (i b : Nat) (e : Raw) :
        b = utf8Len s + igo₁ (s ++ t) { byteIdx := i } { byteIdx := b } e = go₂ t { byteIdx := b } e
        theorem String.Pos.Raw.extract.go₁_zero_utf8Len (s : List Char) :
        go₁ s 0 0 { byteIdx := utf8Len s } = s
        theorem String.extract_cons_addChar (c : Char) (cs : List Char) (b e : Pos.Raw) :
        Pos.Raw.extract (ofList (c :: cs)) (b + c) (e + c) = Pos.Raw.extract (ofList cs) b e
        theorem String.extract_zero_rawEndPos (s : String) :
        Pos.Raw.extract s 0 s.rawEndPos = s
        @[deprecated String.extract_zero_rawEndPos (since := "2025-10-21")]
        theorem String.extract_zero_endPos (s : String) :
        Pos.Raw.extract s 0 s.rawEndPos = s
        theorem String.extract_of_valid (l m r : List Char) :
        Pos.Raw.extract (ofList (l ++ m ++ r)) { byteIdx := utf8Len l } { byteIdx := utf8Len l + utf8Len m } = ofList m
        @[irreducible]
        theorem String.splitAux_of_valid (p : CharBool) (l m r : List Char) (acc : List String) :
        (ofList (l ++ m ++ r)).splitAux p { byteIdx := utf8Len l } { byteIdx := utf8Len l + utf8Len m } acc = acc.reverse ++ List.map ofList (List.splitOnP.go p r m.reverse)
        theorem String.splitToList_of_valid (s : String) (p : CharBool) :
        s.splitToList p = List.map ofList (List.splitOnP p s.toList)
        @[deprecated String.splitToList_of_valid (since := "2025-10-18")]
        theorem String.split_of_valid (s : String) (p : CharBool) :
        s.splitToList p = List.map ofList (List.splitOnP p s.toList)
        @[simp]
        theorem String.toString_toSubstring (s : String) :
        s.toRawSubstring.toString = s
        theorem String.join_eq (ss : List String) :
        join ss = ofList (List.map toList ss).flatten
        @[simp]
        theorem String.toList_join (ss : List String) :
        (join ss).toList = (List.map toList ss).flatten
        @[deprecated String.toList_join (since := "2025-10-31")]
        theorem String.data_join (ss : List String) :
        (join ss).toList = (List.map toList ss).flatten
        @[simp]
        theorem String.Legacy.Iterator.hasNext_cons_addChar (c : Char) (cs : List Char) (i : Pos.Raw) :
        { s := ofList (c :: cs), i := i + c }.hasNext = { s := ofList cs, i := i }.hasNext
        def String.Legacy.Iterator.Valid (it : Iterator) :

        Validity for a string iterator.

        Equations
        Instances For
          inductive String.Legacy.Iterator.ValidFor (l r : List Char) :
          IteratorProp

          it.ValidFor l r means that it is a string iterator whose underlying string is l.reverse ++ r, and where the cursor is pointing at the end of l.reverse.

          • mk {l r : List Char} : ValidFor l r { s := ofList (l.reverseAux r), i := { byteIdx := utf8Len l } }

            The canonical constructor for ValidFor.

          Instances For
            theorem String.Legacy.Iterator.ValidFor.valid {l r : List Char} {it : Iterator} :
            ValidFor l r itit.Valid
            theorem String.Legacy.Iterator.ValidFor.out {l r : List Char} {it : Iterator} :
            ValidFor l r itit = { s := ofList (l.reverseAux r), i := { byteIdx := utf8Len l } }
            theorem String.Legacy.Iterator.ValidFor.out' {l r : List Char} {it : Iterator} :
            ValidFor l r itit = { s := ofList (l.reverse ++ r), i := { byteIdx := utf8Len l.reverse } }
            theorem String.Legacy.Iterator.ValidFor.mk' {l r : List Char} :
            ValidFor l r { s := ofList (l.reverse ++ r), i := { byteIdx := utf8Len l.reverse } }
            theorem String.Legacy.Iterator.ValidFor.of_eq {l r : List Char} (it : Iterator) :
            it.s.toList = l.reverseAux rit.i.byteIdx = utf8Len lValidFor l r it
            theorem String.validFor_mkIterator (s : String) :
            Legacy.Iterator.ValidFor [] s.toList (Legacy.mkIterator s)
            theorem String.Legacy.Iterator.ValidFor.remainingBytes {l r : List Char} {it : Iterator} :
            ValidFor l r itit.remainingBytes = utf8Len r
            theorem String.Legacy.Iterator.ValidFor.toString {l r : List Char} {it : Iterator} :
            ValidFor l r itit.s = ofList (l.reverseAux r)
            theorem String.Legacy.Iterator.ValidFor.pos {l r : List Char} {it : Iterator} :
            ValidFor l r itit.i = { byteIdx := utf8Len l }
            theorem String.Legacy.Iterator.ValidFor.pos_eq_zero {l r : List Char} {it : Iterator} (h : ValidFor l r it) :
            it.i = 0 l = []
            theorem String.Legacy.Iterator.ValidFor.pos_eq_rawEndPos {l r : List Char} {it : Iterator} (h : ValidFor l r it) :
            it.i = it.s.rawEndPos r = []
            @[deprecated String.Legacy.Iterator.ValidFor.pos_eq_rawEndPos (since := "2025-10-21")]
            theorem String.Legacy.Iterator.ValidFor.pos_eq_endPos {l r : List Char} {it : Iterator} (h : ValidFor l r it) :
            it.i = it.s.rawEndPos r = []
            theorem String.Legacy.Iterator.ValidFor.curr {l r : List Char} {it : Iterator} :
            ValidFor l r itit.curr = r.headD default
            theorem String.Legacy.Iterator.ValidFor.next {l : List Char} {c : Char} {r : List Char} {it : Iterator} :
            ValidFor l (c :: r) itValidFor (c :: l) r it.next
            theorem String.Legacy.Iterator.ValidFor.prev {c : Char} {l r : List Char} {it : Iterator} :
            ValidFor (c :: l) r itValidFor l (c :: r) it.prev
            theorem String.Legacy.Iterator.ValidFor.prev_nil {r : List Char} {it : Iterator} :
            ValidFor [] r itValidFor [] r it.prev
            theorem String.Legacy.Iterator.ValidFor.atEnd {l r : List Char} {it : Iterator} :
            ValidFor l r it(it.atEnd = true r = [])
            theorem String.Legacy.Iterator.ValidFor.hasNext {l r : List Char} {it : Iterator} :
            ValidFor l r it(it.hasNext = true r [])
            theorem String.Legacy.Iterator.ValidFor.hasPrev {l r : List Char} {it : Iterator} :
            ValidFor l r it(it.hasPrev = true l [])
            theorem String.Legacy.Iterator.ValidFor.setCurr' {l r : List Char} {c : Char} {it : Iterator} :
            ValidFor l r itValidFor l (List.modifyHead (fun (x : Char) => c) r) (it.setCurr c)
            theorem String.Legacy.Iterator.ValidFor.setCurr {l : List Char} {c : Char} {r : List Char} {it : Iterator} (h : ValidFor l (c :: r) it) :
            ValidFor l (c :: r) (it.setCurr c)
            theorem String.Legacy.Iterator.ValidFor.toEnd {l r : List Char} {it : Iterator} (h : ValidFor l r it) :
            ValidFor (r.reverse ++ l) [] it.toEnd
            theorem String.Legacy.Iterator.ValidFor.toEnd' (it : Iterator) :
            ValidFor it.s.toList.reverse [] it.toEnd
            theorem String.Legacy.Iterator.ValidFor.extract {l m r : List Char} {it₁ it₂ : Iterator} (h₁ : ValidFor l (m ++ r) it₁) (h₂ : ValidFor (m.reverse ++ l) r it₂) :
            it₁.extract it₂ = ofList m
            theorem String.Legacy.Iterator.ValidFor.remainingToString {l r : List Char} {it : Iterator} (h : ValidFor l r it) :
            it.remainingToString = ofList r
            theorem String.Legacy.Iterator.ValidFor.nextn {l r : List Char} {it : Iterator} :
            ValidFor l r it∀ (n : Nat), n r.lengthValidFor ((List.take n r).reverse ++ l) (List.drop n r) (it.nextn n)
            theorem String.Legacy.Iterator.ValidFor.prevn {l r : List Char} {it : Iterator} :
            ValidFor l r it∀ (n : Nat), n l.lengthValidFor (List.drop n l) ((List.take n l).reverse ++ r) (it.prevn n)
            theorem String.Legacy.Iterator.Valid.validFor {it : Iterator} :
            it.Valid (l : List Char), (r : List Char), ValidFor l r it
            theorem String.valid_mkIterator (s : String) :
            (Legacy.mkIterator s).Valid
            theorem String.Legacy.Iterator.Valid.remainingBytes_le {it : Iterator} :
            it.Validit.remainingBytes it.s.utf8ByteSize
            theorem String.Legacy.Iterator.Valid.next {it : Iterator} :
            it.Validit.hasNext = trueit.next.Valid
            theorem String.Legacy.Iterator.Valid.prev {it : Iterator} :
            it.Validit.prev.Valid
            theorem String.Legacy.Iterator.Valid.setCurr {c : Char} {it : Iterator} :
            it.Valid(it.setCurr c).Valid
            theorem String.Legacy.Iterator.Valid.remainingToString {l r : List Char} {it : Iterator} (h : ValidFor l r it) :
            it.remainingToString = ofList r
            theorem String.Legacy.Iterator.Valid.prevn {it : Iterator} (h : it.Valid) (n : Nat) :
            (it.prevn n).Valid
            theorem String.offsetOfPosAux_of_valid (l m r : List Char) (n : Nat) :
            Pos.Raw.offsetOfPosAux (ofList (l ++ m ++ r)) { byteIdx := utf8Len l + utf8Len m } { byteIdx := utf8Len l } n = n + m.length
            theorem String.offsetOfPos_of_valid (l r : List Char) :
            Pos.Raw.offsetOfPos (ofList (l ++ r)) { byteIdx := utf8Len l } = l.length
            theorem String.foldlAux_of_valid {α : Type u_1} (f : αCharα) (l m r : List Char) (a : α) :
            Legacy.foldlAux f (ofList (l ++ m ++ r)) { byteIdx := utf8Len l + utf8Len m } { byteIdx := utf8Len l } a = List.foldl f a m
            theorem String.foldl_eq {α : Type u_1} (f : αCharα) (s : String) (a : α) :
            Legacy.foldl f a s = List.foldl f a s.toList
            theorem String.foldrAux_of_valid {α : Type u_1} (f : Charαα) (l m r : List Char) (a : α) :
            Legacy.foldrAux f a (ofList (l ++ m ++ r)) { byteIdx := utf8Len l + utf8Len m } { byteIdx := utf8Len l } = List.foldr f a m
            theorem String.foldr_eq {α : Type u_1} (f : Charαα) (s : String) (a : α) :
            Legacy.foldr f a s = List.foldr f a s.toList
            theorem String.anyAux_of_valid (p : CharBool) (l m r : List Char) :
            Legacy.anyAux (ofList (l ++ m ++ r)) { byteIdx := utf8Len l + utf8Len m } p { byteIdx := utf8Len l } = m.any p
            theorem String.any_eq (s : String) (p : CharBool) :
            Legacy.any s p = s.toList.any p
            theorem String.any_iff (s : String) (p : CharBool) :
            Legacy.any s p = true (c : Char), c s.toList p c = true
            theorem String.all_eq (s : String) (p : CharBool) :
            Legacy.all s p = s.toList.all p
            theorem String.all_iff (s : String) (p : CharBool) :
            Legacy.all s p = true ∀ (c : Char), c s.toListp c = true
            theorem String.contains_iff (s : String) (c : Char) :
            Legacy.contains s c = true c s.toList
            theorem String.mapAux_of_valid (f : CharChar) (l r : List Char) :
            Legacy.mapAux f { byteIdx := utf8Len l } (ofList (l ++ r)) = ofList (l ++ List.map f r)
            theorem String.map_eq (f : CharChar) (s : String) :
            Legacy.map f s = ofList (List.map f s.toList)
            theorem String.takeWhileAux_of_valid (p : CharBool) (l m r : List Char) :
            Substring.Raw.takeWhileAux (ofList (l ++ m ++ r)) { byteIdx := utf8Len l + utf8Len m } p { byteIdx := utf8Len l } = { byteIdx := utf8Len l + utf8Len (List.takeWhile p m) }
            @[simp]
            theorem String.map_eq_empty_iff (s : String) (f : CharChar) :
            Legacy.map f s = "" s = ""
            @[simp]
            theorem String.map_isEmpty_eq_isEmpty (s : String) (f : CharChar) :
            (Legacy.map f s).isEmpty = s.isEmpty
            @[simp]
            theorem String.Legacy.length_map (s : String) (f : CharChar) :
            (map f s).length = s.length
            theorem String.Legacy.length_eq_of_map_eq {a b : String} {f g : CharChar} :
            map f a = map g ba.length = b.length
            theorem String.length_eq_of_map_eq {a b : String} {f g : CharChar} :
            map f a = map g ba.length = b.length
            structure Substring.Raw.Valid (s : Raw) :

            Validity for a substring.

            • startValid : String.Pos.Raw.Valid s.str s.startPos

              The start position of a valid substring is valid.

            • stopValid : String.Pos.Raw.Valid s.str s.stopPos

              The stop position of a valid substring is valid.

            • le : s.startPos s.stopPos

              The stop position of a substring is at least the start.

            Instances For
              inductive Substring.Raw.ValidFor (l m r : List Char) :
              RawProp

              A substring is represented by three lists l m r, where m is the middle section (the actual substring) and l ++ m ++ r is the underlying string.

              Instances For
                theorem Substring.Raw.ValidFor.valid {l m r : List Char} {s : Raw} :
                ValidFor l m r ss.Valid
                theorem Substring.Raw.ValidFor.of_eq {l m r : List Char} (s : Raw) :
                s.str.toList = l ++ m ++ rs.startPos.byteIdx = String.utf8Len ls.stopPos.byteIdx = String.utf8Len l + String.utf8Len mValidFor l m r s
                theorem String.validFor_toSubstring (s : String) :
                Substring.Raw.ValidFor [] s.toList [] s.toRawSubstring
                theorem Substring.Raw.ValidFor.str {l m r : List Char} {s : Raw} :
                ValidFor l m r ss.str = String.ofList (l ++ m ++ r)
                theorem Substring.Raw.ValidFor.startPos {l m r : List Char} {s : Raw} :
                ValidFor l m r ss.startPos = { byteIdx := String.utf8Len l }
                theorem Substring.Raw.ValidFor.stopPos {l m r : List Char} {s : Raw} :
                ValidFor l m r ss.stopPos = { byteIdx := String.utf8Len l + String.utf8Len m }
                theorem Substring.Raw.ValidFor.bsize {l m r : List Char} {s : Raw} :
                ValidFor l m r ss.bsize = String.utf8Len m
                theorem Substring.Raw.ValidFor.isEmpty {l m r : List Char} {s : Raw} :
                ValidFor l m r s(s.isEmpty = true m = [])
                theorem Substring.Raw.ValidFor.toString {l m r : List Char} {s : Raw} :
                ValidFor l m r ss.toString = String.ofList m
                theorem Substring.Raw.ValidFor.toIterator {l m r : List Char} {s : Raw} :
                ValidFor l m r sString.Legacy.Iterator.ValidFor l.reverse (m ++ r) s.toLegacyIterator
                theorem Substring.Raw.ValidFor.get {l m₁ : List Char} {c : Char} {m₂ r : List Char} {s : Raw} :
                ValidFor l (m₁ ++ c :: m₂) r ss.get { byteIdx := String.utf8Len m₁ } = c
                theorem Substring.Raw.ValidFor.next {l m₁ : List Char} {c : Char} {m₂ r : List Char} {s : Raw} :
                ValidFor l (m₁ ++ c :: m₂) r ss.next { byteIdx := String.utf8Len m₁ } = { byteIdx := String.utf8Len m₁ + c.utf8Size }
                theorem Substring.Raw.ValidFor.next_stop {l m r : List Char} {s : Raw} :
                ValidFor l m r ss.next { byteIdx := String.utf8Len m } = { byteIdx := String.utf8Len m }
                theorem Substring.Raw.ValidFor.prev {l m₁ : List Char} {c : Char} {m₂ r : List Char} {s : Raw} :
                ValidFor l (m₁ ++ c :: m₂) r ss.prev { byteIdx := String.utf8Len m₁ + c.utf8Size } = { byteIdx := String.utf8Len m₁ }
                theorem Substring.Raw.ValidFor.nextn_stop {l m r : List Char} {s : Raw} :
                ValidFor l m r s∀ (n : Nat), s.nextn n { byteIdx := String.utf8Len m } = { byteIdx := String.utf8Len m }
                theorem Substring.Raw.ValidFor.nextn {l m₁ m₂ r : List Char} {s : Raw} :
                ValidFor l (m₁ ++ m₂) r s∀ (n : Nat), s.nextn n { byteIdx := String.utf8Len m₁ } = { byteIdx := String.utf8Len m₁ + String.utf8Len (List.take n m₂) }
                theorem Substring.Raw.ValidFor.prevn {l m₂ r m₁ : List Char} {s : Raw} :
                ValidFor l (m₁.reverse ++ m₂) r s∀ (n : Nat), s.prevn n { byteIdx := String.utf8Len m₁ } = { byteIdx := String.utf8Len (List.drop n m₁) }
                theorem Substring.Raw.ValidFor.front {l : List Char} {c : Char} {m r : List Char} {s : Raw} :
                ValidFor l (c :: m) r ss.front = c
                theorem Substring.Raw.ValidFor.drop {l m r : List Char} {s : Raw} :
                ValidFor l m r s∀ (n : Nat), ValidFor (l ++ List.take n m) (List.drop n m) r (s.drop n)
                theorem Substring.Raw.ValidFor.take {l m r : List Char} {s : Raw} :
                ValidFor l m r s∀ (n : Nat), ValidFor l (List.take n m) (List.drop n m ++ r) (s.take n)
                theorem Substring.Raw.ValidFor.atEnd {l m r : List Char} {p : Nat} {s : Raw} :
                ValidFor l m r s(s.atEnd { byteIdx := p } = true p = String.utf8Len m)
                theorem Substring.Raw.ValidFor.extract' {l ml mm mr r : List Char} {b e : String.Pos.Raw} {s : Raw} :
                ValidFor l (ml ++ mm ++ mr) r sValidFor ml mm mr { str := String.ofList (ml ++ mm ++ mr), startPos := b, stopPos := e } (l' : List Char), (r' : List Char), ValidFor l' mm r' (s.extract b e)
                theorem Substring.Raw.ValidFor.extract {l m r ml mm mr : List Char} {b e : String.Pos.Raw} {s : Raw} :
                ValidFor l m r sValidFor ml mm mr { str := String.ofList m, startPos := b, stopPos := e } (l' : List Char), (r' : List Char), ValidFor l' mm r' (s.extract b e)
                theorem Substring.Raw.ValidFor.foldl {α : Type u_1} {l m r : List Char} (f : αCharα) (init : α) {s : Raw} :
                ValidFor l m r sLegacy.foldl f init s = List.foldl f init m
                theorem Substring.Raw.ValidFor.foldr {α : Type u_1} {l m r : List Char} (f : Charαα) (init : α) {s : Raw} :
                ValidFor l m r sLegacy.foldr f init s = List.foldr f init m
                theorem Substring.Raw.ValidFor.any {l m r : List Char} (f : CharBool) {s : Raw} :
                ValidFor l m r sLegacy.any s f = m.any f
                theorem Substring.Raw.ValidFor.all {l m r : List Char} (f : CharBool) {s : Raw} :
                ValidFor l m r sLegacy.all s f = m.all f
                theorem Substring.Raw.ValidFor.contains {l m r : List Char} (c : Char) {s : Raw} :
                ValidFor l m r s(Legacy.contains s c = true c m)
                theorem Substring.Raw.ValidFor.takeWhile {l m r : List Char} (p : CharBool) {s : Raw} :
                ValidFor l m r sValidFor l (List.takeWhile p m) (List.dropWhile p m ++ r) (s.takeWhile p)
                theorem Substring.Raw.ValidFor.dropWhile {l m r : List Char} (p : CharBool) {s : Raw} :
                ValidFor l m r sValidFor (l ++ List.takeWhile p m) (List.dropWhile p m) r (s.dropWhile p)
                theorem Substring.Raw.Valid.validFor {s : Raw} :
                s.Valid (l : List Char), (m : List Char), (r : List Char), ValidFor l m r s
                theorem Substring.Raw.Valid.valid {l m r : List Char} {s : Raw} :
                ValidFor l m r ss.Valid
                theorem String.valid_toSubstring (s : String) :
                s.toRawSubstring.Valid
                theorem Substring.Raw.Valid.bsize {s : Raw} :
                s.Valids.bsize = String.utf8Len s.toString.toList
                theorem Substring.Raw.Valid.isEmpty {s : Raw} :
                s.Valid(s.isEmpty = true s.toString = "")
                theorem Substring.Raw.Valid.get {m₁ : List Char} {c : Char} {m₂ : List Char} {s : Raw} :
                s.Valids.toString.toList = m₁ ++ c :: m₂s.get { byteIdx := String.utf8Len m₁ } = c
                theorem Substring.Raw.Valid.next {m₁ : List Char} {c : Char} {m₂ : List Char} {s : Raw} :
                s.Valids.toString.toList = m₁ ++ c :: m₂s.next { byteIdx := String.utf8Len m₁ } = { byteIdx := String.utf8Len m₁ + c.utf8Size }
                theorem Substring.Raw.Valid.next_stop {s : Raw} :
                s.Valids.next { byteIdx := s.bsize } = { byteIdx := s.bsize }
                theorem Substring.Raw.Valid.prev {m₁ : List Char} {c : Char} {m₂ : List Char} {s : Raw} :
                s.Valids.toString.toList = m₁ ++ c :: m₂s.prev { byteIdx := String.utf8Len m₁ + c.utf8Size } = { byteIdx := String.utf8Len m₁ }
                theorem Substring.Raw.Valid.nextn_stop {s : Raw} :
                s.Valid∀ (n : Nat), s.nextn n { byteIdx := s.bsize } = { byteIdx := s.bsize }
                theorem Substring.Raw.Valid.nextn {m₁ m₂ : List Char} {s : Raw} :
                s.Valids.toString.toList = m₁ ++ m₂∀ (n : Nat), s.nextn n { byteIdx := String.utf8Len m₁ } = { byteIdx := String.utf8Len m₁ + String.utf8Len (List.take n m₂) }
                theorem Substring.Raw.Valid.prevn {m₂ m₁ : List Char} {s : Raw} :
                s.Valids.toString.toList = m₁.reverse ++ m₂∀ (n : Nat), s.prevn n { byteIdx := String.utf8Len m₁ } = { byteIdx := String.utf8Len (List.drop n m₁) }
                theorem Substring.Raw.Valid.front {c : Char} {m : List Char} {s : Raw} :
                s.Valids.toString.toList = c :: ms.front = c
                theorem Substring.Raw.Valid.drop {s : Raw} :
                s.Valid∀ (n : Nat), (s.drop n).Valid
                theorem Substring.Raw.Valid.data_drop {s : Raw} :
                s.Valid∀ (n : Nat), (s.drop n).toString.toList = List.drop n s.toString.toList
                theorem Substring.Raw.Valid.take {s : Raw} :
                s.Valid∀ (n : Nat), (s.take n).Valid
                theorem Substring.Raw.Valid.data_take {s : Raw} :
                s.Valid∀ (n : Nat), (s.take n).toString.toList = List.take n s.toString.toList
                theorem Substring.Raw.Valid.atEnd {p : Nat} {s : Raw} :
                s.Valid(s.atEnd { byteIdx := p } = true p = s.toString.utf8ByteSize)
                theorem Substring.Raw.Valid.extract {b e : String.Pos.Raw} {s : Raw} :
                s.Valid{ str := s.toString, startPos := b, stopPos := e }.Valid(s.extract b e).Valid
                theorem Substring.Raw.Valid.toString_extract {b e : String.Pos.Raw} {s : Raw} :
                s.Valid{ str := s.toString, startPos := b, stopPos := e }.Valid(s.extract b e).toString = String.Pos.Raw.extract s.toString b e
                theorem Substring.Raw.Valid.foldl {α : Type u_1} (f : αCharα) (init : α) {s : Raw} :
                s.ValidLegacy.foldl f init s = List.foldl f init s.toString.toList
                theorem Substring.Raw.Valid.foldr {α : Type u_1} (f : Charαα) (init : α) {s : Raw} :
                s.ValidLegacy.foldr f init s = List.foldr f init s.toString.toList
                theorem Substring.Raw.Valid.any (f : CharBool) {s : Raw} :
                s.ValidLegacy.any s f = s.toString.toList.any f
                theorem Substring.Raw.Valid.all (f : CharBool) {s : Raw} :
                s.ValidLegacy.all s f = s.toString.toList.all f
                theorem Substring.Raw.Valid.contains (c : Char) {s : Raw} :
                s.Valid(Legacy.contains s c = true c s.toString.toList)
                theorem Substring.Raw.Valid.takeWhile (p : CharBool) {s : Raw} :
                s.Valid(s.takeWhile p).Valid
                theorem Substring.Raw.Valid.data_takeWhile (p : CharBool) {s : Raw} :
                s.Valid(s.takeWhile p).toString.toList = List.takeWhile p s.toString.toList
                theorem Substring.Raw.Valid.dropWhile (p : CharBool) {s : Raw} :
                s.Valid(s.dropWhile p).Valid
                theorem Substring.Raw.Valid.data_dropWhile (p : CharBool) {s : Raw} :
                s.Valid(s.dropWhile p).toString.toList = List.dropWhile p s.toString.toList
                theorem String.drop_eq (s : String) (n : Nat) :
                Legacy.drop s n = ofList (List.drop n s.toList)
                @[simp]
                theorem String.toList_drop (s : String) (n : Nat) :
                (Legacy.drop s n).toList = List.drop n s.toList
                @[simp]
                theorem String.drop_empty {n : Nat} :
                Legacy.drop "" n = ""
                theorem String.take_eq (s : String) (n : Nat) :
                Legacy.take s n = ofList (List.take n s.toList)
                @[simp]
                theorem String.toList_take (s : String) (n : Nat) :
                (Legacy.take s n).toList = List.take n s.toList
                theorem String.takeWhile_eq (p : CharBool) (s : String) :
                Legacy.takeWhile s p = ofList (List.takeWhile p s.toList)
                @[simp]
                theorem String.toList_takeWhile (p : CharBool) (s : String) :
                (Legacy.takeWhile s p).toList = List.takeWhile p s.toList
                theorem String.dropWhile_eq (p : CharBool) (s : String) :
                Legacy.dropWhile s p = ofList (List.dropWhile p s.toList)
                @[simp]
                theorem String.toList_dropWhile (p : CharBool) (s : String) :
                (Legacy.dropWhile s p).toList = List.dropWhile p s.toList