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

full_name: String.lt_trans
code: theorem lt_trans {s₁ s₂ s₃ : String} : s₁ < s₂ → s₂ < s₃ → s₁ < s₃ 
goal: s₁ < s₂ → s₂ < s₃ → s₁ < s₃

full_name: String.lt_antisymm
code: theorem lt_antisymm {s₁ s₂ : String} (h₁ : ¬s₁ < s₂) (h₂ : ¬s₂ < s₁) : s₁ = s₂ 
goal: s₁ = s₂

full_name: String.«instTransOrd_.lake»
code: instance : Batteries.TransOrd String 
goal: Batteries.TransOrd String

full_name: String.«instLTOrd_.lake»
code: instance : Batteries.LTOrd String 
goal: Batteries.LTOrd String

full_name: String.«instBEqOrd_.lake»
code: instance : Batteries.BEqOrd String 
goal: Batteries.BEqOrd String

full_name: String.mk_length
code: @[simp] theorem mk_length (s : List Char) : (String.mk s).length = s.length 
goal: { data := s }.length = s.length

full_name: _private.«.lake».packages.batteries.Batteries.Data.String.Lemmas.0.String.add_csize_pos
code: private theorem add_csize_pos : 0 < i + Char.utf8Size c 
goal: 0 < i + c.utf8Size

full_name: _private.«.lake».packages.batteries.Batteries.Data.String.Lemmas.0.String.ne_add_csize_add_self
code: private theorem ne_add_csize_add_self : i ≠ n + Char.utf8Size c + i 
goal: i ≠ n + c.utf8Size + i

full_name: _private.«.lake».packages.batteries.Batteries.Data.String.Lemmas.0.String.ne_self_add_add_csize
code: private theorem ne_self_add_add_csize : i ≠ i + (n + Char.utf8Size c) 
goal: i ≠ i + (n + c.utf8Size)

full_name: String.utf8Len
code: /-- The UTF-8 byte length of a list of characters. (This is intended for specification purposes.) -/
@[inline] def utf8Len : List Char → Nat 
goal: List Char → Nat

full_name: String.utf8ByteSize.go_eq
code: @[simp] theorem utf8ByteSize.go_eq : utf8ByteSize.go = utf8Len 
goal: String.utf8ByteSize.go = String.utf8Len

full_name: String.utf8ByteSize_mk
code: @[simp] theorem utf8ByteSize_mk (cs) : utf8ByteSize ⟨cs⟩ = utf8Len cs 
goal: { data := cs }.utf8ByteSize = String.utf8Len cs

full_name: String.utf8Len_nil
code: @[simp] theorem utf8Len_nil : utf8Len [] = 0 
goal: String.utf8Len [] = 0

full_name: String.utf8Len_cons
code: @[simp] theorem utf8Len_cons (c cs) : utf8Len (c :: cs) = utf8Len cs + c.utf8Size 
goal: String.utf8Len (c :: cs) = String.utf8Len cs + c.utf8Size

full_name: String.utf8Len_append
code: @[simp] theorem utf8Len_append (cs₁ cs₂) : utf8Len (cs₁ ++ cs₂) = utf8Len cs₁ + utf8Len cs₂ 
goal: String.utf8Len (cs₁ ++ cs₂) = String.utf8Len cs₁ + String.utf8Len cs₂

full_name: String.utf8Len_reverseAux
code: @[simp] theorem utf8Len_reverseAux (cs₁ cs₂) :
    utf8Len (cs₁.reverseAux cs₂) = utf8Len cs₁ + utf8Len cs₂ 
goal: String.utf8Len (cs₁.reverseAux cs₂) = String.utf8Len cs₁ + String.utf8Len cs₂

full_name: String.utf8Len_reverse
code: @[simp] theorem utf8Len_reverse (cs) : utf8Len cs.reverse = utf8Len cs 
goal: String.utf8Len cs.reverse = String.utf8Len cs

full_name: String.utf8Len_eq_zero
code: @[simp] theorem utf8Len_eq_zero : utf8Len l = 0 ↔ l = [] 
goal: String.utf8Len l = 0 ↔ l = []

full_name: String.utf8Len_le_of_sublist
code: theorem utf8Len_le_of_sublist : ∀ {cs₁ cs₂}, cs₁ <+ cs₂ → utf8Len cs₁ ≤ utf8Len cs₂
  
goal: cs₁.Sublist cs₂ → String.utf8Len cs₁ ≤ String.utf8Len cs₂

full_name: String.utf8Len_le_of_infix
code: theorem utf8Len_le_of_infix (h : cs₁ <:+: cs₂) : utf8Len cs₁ ≤ utf8Len cs₂ 
goal: String.utf8Len cs₁ ≤ String.utf8Len cs₂

full_name: String.utf8Len_le_of_suffix
code: theorem utf8Len_le_of_suffix (h : cs₁ <:+ cs₂) : utf8Len cs₁ ≤ utf8Len cs₂ 
goal: String.utf8Len cs₁ ≤ String.utf8Len cs₂

full_name: String.utf8Len_le_of_prefix
code: theorem utf8Len_le_of_prefix (h : cs₁ <+: cs₂) : utf8Len cs₁ ≤ utf8Len cs₂ 
goal: String.utf8Len cs₁ ≤ String.utf8Len cs₂

full_name: String.endPos_eq
code: @[simp] theorem endPos_eq (cs : List Char) : endPos ⟨cs⟩ = ⟨utf8Len cs⟩ 
goal: { data := cs }.endPos = { byteIdx := String.utf8Len cs }

full_name: String.Pos.lt_addChar
code: theorem lt_addChar (p : Pos) (c : Char) : p < p + c 
goal: p < p + c

full_name: _private.«.lake».packages.batteries.Batteries.Data.String.Lemmas.0.String.Pos.zero_ne_addChar
code: private theorem zero_ne_addChar {i : Pos} {c : Char} : 0 ≠ i + c 
goal: 0 ≠ i + c

full_name: String.Pos.Valid
code: /-- A string position is valid if it is equal to the UTF-8 length of an initial substring of `s`. -/
def Valid (s : String) (p : Pos) : Prop 
goal: Prop

full_name: String.Pos.valid_zero
code: @[simp] theorem valid_zero : Valid s 0 
goal: String.Pos.Valid s 0

full_name: String.Pos.valid_endPos
code: @[simp] theorem valid_endPos : Valid s (endPos s) 
goal: String.Pos.Valid s s.endPos

full_name: String.Pos.Valid.mk
code: theorem Valid.mk (cs cs' : List Char) : Valid ⟨cs ++ cs'⟩ ⟨utf8Len cs⟩ 
goal: String.Pos.Valid { data := cs ++ cs' } { byteIdx := String.utf8Len cs }

full_name: String.Pos.Valid.le_endPos
code: theorem Valid.le_endPos : ∀ {s p}, Valid s p → p ≤ endPos s
  
goal: String.Pos.Valid s p → p ≤ s.endPos

full_name: String.endPos_eq_zero
code: theorem endPos_eq_zero : ∀ (s : String), endPos s = 0 ↔ s = ""
  
goal: s.endPos = 0 ↔ s = ""

full_name: String.isEmpty_iff
code: theorem isEmpty_iff (s : String) : isEmpty s ↔ s = "" 
goal: s.isEmpty = true ↔ s = ""

full_name: String.utf8InductionOn
code: /--
Induction along the valid positions in a list of characters.
(This definition is intended only for specification purposes.)
-/
def utf8InductionOn {motive : List Char → Pos → Sort u}
    (s : List Char) (i p : Pos)
    (nil : ∀ i, motive [] i)
    (eq  : ∀ c cs, motive (c :: cs) p)
    (ind : ∀ (c : Char) cs i, i ≠ p → motive cs (i + c) → motive (c :: cs) i) :
    motive s i 
goal: motive s i

full_name: String.utf8GetAux_add_right_cancel
code: theorem utf8GetAux_add_right_cancel (s : List Char) (i p n : Nat) :
    utf8GetAux s ⟨i + n⟩ ⟨p + n⟩ = utf8GetAux s ⟨i⟩ ⟨p⟩ 
goal: String.utf8GetAux s { byteIdx := i + n } { byteIdx := p + n } = String.utf8GetAux s { byteIdx := i } { byteIdx := p }

full_name: String.utf8GetAux_addChar_right_cancel
code: theorem utf8GetAux_addChar_right_cancel (s : List Char) (i p : Pos) (c : Char) :
    utf8GetAux s (i + c) (p + c) = utf8GetAux s i p 
goal: String.utf8GetAux s (i + c) (p + c) = String.utf8GetAux s i p

full_name: String.utf8GetAux_of_valid
code: theorem utf8GetAux_of_valid (cs cs' : List Char) {i p : Nat} (hp : i + utf8Len cs = p) :
    utf8GetAux (cs ++ cs') ⟨i⟩ ⟨p⟩ = cs'.headD default 
goal: String.utf8GetAux (cs ++ cs') { byteIdx := i } { byteIdx := p } = cs'.headD default

full_name: String.get_of_valid
code: theorem get_of_valid (cs cs' : List Char) : get ⟨cs ++ cs'⟩ ⟨utf8Len cs⟩ = cs'.headD default 
goal: { data := cs ++ cs' }.get { byteIdx := String.utf8Len cs } = cs'.headD default

full_name: String.get_cons_addChar
code: theorem get_cons_addChar (c : Char) (cs : List Char) (i : Pos) :
    get ⟨c :: cs⟩ (i + c) = get ⟨cs⟩ i 
goal: { data := c :: cs }.get (i + c) = { data := cs }.get i

full_name: String.utf8GetAux?_of_valid
code: theorem utf8GetAux?_of_valid (cs cs' : List Char) {i p : Nat} (hp : i + utf8Len cs = p) :
    utf8GetAux? (cs ++ cs') ⟨i⟩ ⟨p⟩ = cs'.head? 
goal: String.utf8GetAux? (cs ++ cs') { byteIdx := i } { byteIdx := p } = cs'.head?

full_name: String.get?_of_valid
code: theorem get?_of_valid (cs cs' : List Char) : get? ⟨cs ++ cs'⟩ ⟨utf8Len cs⟩ = cs'.head? 
goal: { data := cs ++ cs' }.get? { byteIdx := String.utf8Len cs } = cs'.head?

full_name: String.utf8SetAux_of_valid
code: theorem utf8SetAux_of_valid (c' : Char) (cs cs' : List Char) {i p : Nat} (hp : i + utf8Len cs = p) :
    utf8SetAux c' (cs ++ cs') ⟨i⟩ ⟨p⟩ = cs ++ cs'.modifyHead fun _ => c' 
goal: String.utf8SetAux c' (cs ++ cs') { byteIdx := i } { byteIdx := p } = cs ++ List.modifyHead (fun x => c') cs'

full_name: String.set_of_valid
code: theorem set_of_valid (cs cs' : List Char) (c' : Char) :
    set ⟨cs ++ cs'⟩ ⟨utf8Len cs⟩ c' = ⟨cs ++ cs'.modifyHead fun _ => c'⟩ 
goal: { data := cs ++ cs' }.set { byteIdx := String.utf8Len cs } c' = { data := cs ++ List.modifyHead (fun x => c') cs' }

full_name: String.modify_of_valid
code: theorem modify_of_valid (cs cs' : List Char) :
    modify ⟨cs ++ cs'⟩ ⟨utf8Len cs⟩ f = ⟨cs ++ cs'.modifyHead f⟩ 
goal: { data := cs ++ cs' }.modify { byteIdx := String.utf8Len cs } f = { data := cs ++ List.modifyHead f cs' }

full_name: String.next_of_valid'
code: theorem next_of_valid' (cs cs' : List Char) :
    next ⟨cs ++ cs'⟩ ⟨utf8Len cs⟩ = ⟨utf8Len cs + (cs'.headD default).utf8Size⟩ 
goal: { data := cs ++ cs' }.next { byteIdx := String.utf8Len cs } =
  { byteIdx := String.utf8Len cs + (cs'.headD default).utf8Size }

full_name: String.next_of_valid
code: theorem next_of_valid (cs : List Char) (c : Char) (cs' : List Char) :
    next ⟨cs ++ c :: cs'⟩ ⟨utf8Len cs⟩ = ⟨utf8Len cs + c.utf8Size⟩ 
goal: { data := cs ++ c :: cs' }.next { byteIdx := String.utf8Len cs } = { byteIdx := String.utf8Len cs + c.utf8Size }

full_name: String.atEnd_iff
code: @[simp] theorem atEnd_iff (s : String) (p : Pos) : atEnd s p ↔ s.endPos ≤ p 
goal: s.atEnd p = true ↔ s.endPos ≤ p

full_name: String.valid_next
code: theorem valid_next {p : Pos} (h : p.Valid s) (h₂ : p < s.endPos) : (next s p).Valid s 
goal: String.Pos.Valid s (s.next p)

full_name: String.utf8PrevAux_of_valid
code: theorem utf8PrevAux_of_valid {cs cs' : List Char} {c : Char} {i p : Nat}
    (hp : i + (utf8Len cs + c.utf8Size) = p) :
    utf8PrevAux (cs ++ c :: cs') ⟨i⟩ ⟨p⟩ = ⟨i + utf8Len cs⟩ 
goal: String.utf8PrevAux (cs ++ c :: cs') { byteIdx := i } { byteIdx := p } = { byteIdx := i + String.utf8Len cs }

full_name: String.prev_of_valid
code: theorem prev_of_valid (cs : List Char) (c : Char) (cs' : List Char) :
    prev ⟨cs ++ c :: cs'⟩ ⟨utf8Len cs + c.utf8Size⟩ = ⟨utf8Len cs⟩ 
goal: { data := cs ++ c :: cs' }.prev { byteIdx := String.utf8Len cs + c.utf8Size } = { byteIdx := String.utf8Len cs }

full_name: String.prev_of_valid'
code: theorem prev_of_valid' (cs cs' : List Char) :
    prev ⟨cs ++ cs'⟩ ⟨utf8Len cs⟩ = ⟨utf8Len cs.dropLast⟩ 
goal: { data := cs ++ cs' }.prev { byteIdx := String.utf8Len cs } = { byteIdx := String.utf8Len cs.dropLast }

full_name: String.front_eq
code: theorem front_eq (s : String) : front s = s.1.headD default 
goal: s.front = s.data.headD default

full_name: String.back_eq
code: theorem back_eq (s : String) : back s = s.1.getLastD default 
goal: s.back = s.data.getLastD default

full_name: String.atEnd_of_valid
code: theorem atEnd_of_valid (cs : List Char) (cs' : List Char) :
    atEnd ⟨cs ++ cs'⟩ ⟨utf8Len cs⟩ ↔ cs' = [] 
goal: { data := cs ++ cs' }.atEnd { byteIdx := String.utf8Len cs } = true ↔ cs' = []

full_name: String.posOfAux_eq
code: theorem posOfAux_eq (s c) : posOfAux s c = findAux s (· == c) 
goal: s.posOfAux c = s.findAux fun x => x == c

full_name: String.posOf_eq
code: theorem posOf_eq (s c) : posOf s c = find s (· == c) 
goal: s.posOf c = s.find fun x => x == c

full_name: String.revPosOfAux_eq
code: theorem revPosOfAux_eq (s c) : revPosOfAux s c = revFindAux s (· == c) 
goal: s.revPosOfAux c = s.revFindAux fun x => x == c

full_name: String.revPosOf_eq
code: theorem revPosOf_eq (s c) : revPosOf s c = revFind s (· == c) 
goal: s.revPosOf c = s.revFind fun x => x == c

full_name: String.findAux_of_valid
code: @[nolint unusedHavesSuffices] -- false positive from unfolding String.findAux
theorem findAux_of_valid (p) : ∀ l m r,
    findAux ⟨l ++ m ++ r⟩ p ⟨utf8Len l + utf8Len m⟩ ⟨utf8Len l⟩ =
    ⟨utf8Len l + utf8Len (m.takeWhile (!p ·))⟩
  
goal: { data := l ++ m ++ r }.findAux p { byteIdx := String.utf8Len l + String.utf8Len m } { byteIdx := String.utf8Len l } =
  { byteIdx := String.utf8Len l + String.utf8Len (List.takeWhile (fun x => !p x) m) }

full_name: String.find_of_valid
code: theorem find_of_valid (p s) : find s p = ⟨utf8Len (s.1.takeWhile (!p ·))⟩ 
goal: s.find p = { byteIdx := String.utf8Len (List.takeWhile (fun x => !p x) s.data) }

full_name: String.revFindAux_of_valid
code: @[nolint unusedHavesSuffices] -- false positive from unfolding String.revFindAux
theorem revFindAux_of_valid (p) : ∀ l r,
    revFindAux ⟨l.reverse ++ r⟩ p ⟨utf8Len l⟩ = (l.dropWhile (!p ·)).tail?.map (⟨utf8Len ·⟩)
  
goal: { data := l.reverse ++ r }.revFindAux p { byteIdx := String.utf8Len l } =
  Option.map (fun x => { byteIdx := String.utf8Len x }) (List.dropWhile (fun x => !p x) l).tail?

full_name: String.revFind_of_valid
code: theorem revFind_of_valid (p s) :
    revFind s p = (s.1.reverse.dropWhile (!p ·)).tail?.map (⟨utf8Len ·⟩) 
goal: s.revFind p =
  Option.map (fun x => { byteIdx := String.utf8Len x }) (List.dropWhile (fun x => !p x) s.data.reverse).tail?

full_name: String.firstDiffPos_loop_eq
code: theorem firstDiffPos_loop_eq (l₁ l₂ r₁ r₂ stop p)
    (hl₁ : p = utf8Len l₁) (hl₂ : p = utf8Len l₂)
    (hstop : stop = min (utf8Len l₁ + utf8Len r₁) (utf8Len l₂ + utf8Len r₂)) :
    firstDiffPos.loop ⟨l₁ ++ r₁⟩ ⟨l₂ ++ r₂⟩ ⟨stop⟩ ⟨p⟩ =
      ⟨p + utf8Len (List.takeWhile₂ (· = ·) r₁ r₂).1⟩ 
goal: String.firstDiffPos.loop { data := l₁ ++ r₁ } { data := l₂ ++ r₂ } { byteIdx := stop } { byteIdx := p } =
  { byteIdx := p + String.utf8Len (List.takeWhile₂ (fun x x_1 => decide (x = x_1)) r₁ r₂).fst }

full_name: String.firstDiffPos_eq
code: theorem firstDiffPos_eq (a b : String) :
    firstDiffPos a b = ⟨utf8Len (List.takeWhile₂ (· = ·) a.1 b.1).1⟩ 
goal: a.firstDiffPos b = { byteIdx := String.utf8Len (List.takeWhile₂ (fun x x_1 => decide (x = x_1)) a.data b.data).fst }

full_name: String.extract.go₂_add_right_cancel
code: theorem extract.go₂_add_right_cancel (s : List Char) (i e n : Nat) :
    go₂ s ⟨i + n⟩ ⟨e + n⟩ = go₂ s ⟨i⟩ ⟨e⟩ 
goal: String.extract.go₂ s { byteIdx := i + n } { byteIdx := e + n } = String.extract.go₂ s { byteIdx := i } { byteIdx := e }

full_name: String.extract.go₂_append_left
code: theorem extract.go₂_append_left : ∀ (s t : List Char) (i e : Nat),
    e = utf8Len s + i → go₂ (s ++ t) ⟨i⟩ ⟨e⟩ = s

goal: e = String.utf8Len s + i → String.extract.go₂ (s ++ t) { byteIdx := i } { byteIdx := e } = s

full_name: String.extract.go₁_add_right_cancel
code: theorem extract.go₁_add_right_cancel (s : List Char) (i b e n : Nat) :
    go₁ s ⟨i + n⟩ ⟨b + n⟩ ⟨e + n⟩ = go₁ s ⟨i⟩ ⟨b⟩ ⟨e⟩ 
goal: String.extract.go₁ s { byteIdx := i + n } { byteIdx := b + n } { byteIdx := e + n } =
  String.extract.go₁ s { byteIdx := i } { byteIdx := b } { byteIdx := e }

full_name: String.extract.go₁_cons_addChar
code: theorem extract.go₁_cons_addChar (c : Char) (cs : List Char) (b e : Pos) :
    go₁ (c :: cs) 0 (b + c) (e + c) = go₁ cs 0 b e 
goal: String.extract.go₁ (c :: cs) 0 (b + c) (e + c) = String.extract.go₁ cs 0 b e

full_name: String.extract.go₁_append_right
code: theorem extract.go₁_append_right : ∀ (s t : List Char) (i b : Nat) (e : Pos),
    b = utf8Len s + i → go₁ (s ++ t) ⟨i⟩ ⟨b⟩ e = go₂ t ⟨b⟩ e

goal: b = String.utf8Len s + i →
  String.extract.go₁ (s ++ t) { byteIdx := i } { byteIdx := b } e = String.extract.go₂ t { byteIdx := b } e

full_name: String.extract.go₁_zero_utf8Len
code: theorem extract.go₁_zero_utf8Len (s : List Char) : go₁ s 0 0 ⟨utf8Len s⟩ = s 
goal: String.extract.go₁ s 0 0 { byteIdx := String.utf8Len s } = s

full_name: String.extract_cons_addChar
code: theorem extract_cons_addChar (c : Char) (cs : List Char) (b e : Pos) :
    extract ⟨c :: cs⟩ (b + c) (e + c) = extract ⟨cs⟩ b e 
goal: { data := c :: cs }.extract (b + c) (e + c) = { data := cs }.extract b e

full_name: String.extract_zero_endPos
code: theorem extract_zero_endPos : ∀ (s : String), s.extract 0 (endPos s) = s
  
goal: s.extract 0 s.endPos = s

full_name: String.extract_of_valid
code: theorem extract_of_valid (l m r : List Char) :
    extract ⟨l ++ m ++ r⟩ ⟨utf8Len l⟩ ⟨utf8Len l + utf8Len m⟩ = ⟨m⟩ 
goal: { data := l ++ m ++ r }.extract { byteIdx := String.utf8Len l } { byteIdx := String.utf8Len l + String.utf8Len m } =
  { data := m }

full_name: String.splitAux_of_valid
code: theorem splitAux_of_valid (p l m r acc) :
    splitAux ⟨l ++ m ++ r⟩ p ⟨utf8Len l⟩ ⟨utf8Len l + utf8Len m⟩ acc =
      acc.reverse ++ (List.splitOnP.go p r m.reverse).map mk 
goal: { data := l ++ m ++ r }.splitAux p { byteIdx := String.utf8Len l } { byteIdx := String.utf8Len l + String.utf8Len m }
    acc =
  acc.reverse ++ List.map String.mk (List.splitOnP.go p r m.reverse)

full_name: String.split_of_valid
code: theorem split_of_valid (s p) : split s p = (List.splitOnP p s.1).map mk 
goal: s.split p = List.map String.mk (List.splitOnP p s.data)

full_name: String.toString_toSubstring
code: @[simp] theorem toString_toSubstring (s : String) : s.toSubstring.toString = s 
goal: s.toSubstring.toString = s

full_name: String.join_eq.go
code: theorem join_eq (ss : List String) : join ss = ⟨(ss.map data).join⟩ 
goal: List.foldl (fun x x_1 => x ++ x_1) { data := cs } ss = { data := cs ++ (List.map String.data ss).join }

full_name: String.join_eq
code: theorem join_eq (ss : List String) : join ss = ⟨(ss.map data).join⟩ 
goal: String.join ss = { data := (List.map String.data ss).join }

full_name: String.data_join
code: @[simp] theorem data_join (ss : List String) : (join ss).data = (ss.map data).join 
goal: (String.join ss).data = (List.map String.data ss).join

full_name: String.Iterator.forward_eq_nextn
code: @[simp] theorem forward_eq_nextn : forward = nextn 
goal: String.Iterator.forward = String.Iterator.nextn

full_name: String.Iterator.hasNext_cons_addChar
code: theorem hasNext_cons_addChar (c : Char) (cs : List Char) (i : Pos) :
    hasNext ⟨⟨c :: cs⟩, i + c⟩ = hasNext ⟨⟨cs⟩, i⟩ 
goal: { s := { data := c :: cs }, i := i + c }.hasNext = { s := { data := cs }, i := i }.hasNext

full_name: String.Iterator.Valid
code: /-- Validity for a string iterator. -/
def Valid (it : Iterator) : Prop 
goal: Prop

full_name: String.Iterator.ValidFor
code: /-- `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`. -/
inductive ValidFor (l r : List Char) : Iterator → Prop
  /-- The canonical constructor for `ValidFor`. -/
  | mk : ValidFor l r ⟨⟨l.reverseAux r⟩, ⟨utf8Len l⟩⟩
goal: String.Iterator → Prop

full_name: String.Iterator.ValidFor.mk
code: /-- `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`. -/
inductive ValidFor (l r : List Char) : Iterator → Prop
  /-- The canonical constructor for `ValidFor`. -/
  | mk : ValidFor l r ⟨⟨l.reverseAux r⟩, ⟨utf8Len l⟩⟩
goal: String.Iterator.ValidFor l r { s := { data := l.reverseAux r }, i := { byteIdx := String.utf8Len l } }

full_name: String.Iterator.ValidFor.valid
code: theorem valid : ∀ {it}, ValidFor l r it → Valid it
  
goal: String.Iterator.ValidFor l r it → it.Valid

full_name: String.Iterator.ValidFor.out
code: theorem out : ∀ {it}, ValidFor l r it → it = ⟨⟨l.reverseAux r⟩, ⟨utf8Len l⟩⟩
  
goal: String.Iterator.ValidFor l r it → it = { s := { data := l.reverseAux r }, i := { byteIdx := String.utf8Len l } }

full_name: String.Iterator.ValidFor.out'
code: theorem out' : ∀ {it}, ValidFor l r it → it = ⟨⟨l.reverse ++ r⟩, ⟨utf8Len l.reverse⟩⟩
  
goal: String.Iterator.ValidFor l r it → it = { s := { data := l.reverse ++ r }, i := { byteIdx := String.utf8Len l.reverse } }

full_name: String.Iterator.ValidFor.mk'
code: theorem mk' : ValidFor l r ⟨⟨l.reverse ++ r⟩, ⟨utf8Len l.reverse⟩⟩ 
goal: String.Iterator.ValidFor l r { s := { data := l.reverse ++ r }, i := { byteIdx := String.utf8Len l.reverse } }

full_name: String.Iterator.ValidFor.of_eq
code: theorem of_eq : ∀ it, it.1.1 = l.reverseAux r → it.2.1 = utf8Len l → ValidFor l r it
  
goal: it.s.data = l.reverseAux r → it.i.byteIdx = String.utf8Len l → String.Iterator.ValidFor l r it

full_name: String.validFor_mkIterator
code: theorem _root_.String.validFor_mkIterator (s) : (mkIterator s).ValidFor [] s.1 
goal: String.Iterator.ValidFor [] s.data s.mkIterator

full_name: String.Iterator.ValidFor.remainingBytes
code: theorem remainingBytes : ∀ {it}, ValidFor l r it → it.remainingBytes = utf8Len r
  
goal: String.Iterator.ValidFor l r it → it.remainingBytes = String.utf8Len r

full_name: String.Iterator.ValidFor.toString
code: theorem toString : ∀ {it}, ValidFor l r it → it.1 = ⟨l.reverseAux r⟩
  
goal: String.Iterator.ValidFor l r it → it.s = { data := l.reverseAux r }

full_name: String.Iterator.ValidFor.pos
code: theorem pos : ∀ {it}, ValidFor l r it → it.2 = ⟨utf8Len l⟩
  
goal: String.Iterator.ValidFor l r it → it.i = { byteIdx := String.utf8Len l }

full_name: String.Iterator.ValidFor.pos_eq_zero
code: theorem pos_eq_zero {l r it} (h : ValidFor l r it) : it.2 = 0 ↔ l = [] 
goal: it.i = 0 ↔ l = []

full_name: String.Iterator.ValidFor.pos_eq_endPos
code: theorem pos_eq_endPos {l r it} (h : ValidFor l r it) : it.2 = it.1.endPos ↔ r = [] 
goal: it.i = it.s.endPos ↔ r = []

full_name: String.Iterator.ValidFor.curr
code: theorem curr : ∀ {it}, ValidFor l r it → it.curr = r.headD default
  
goal: String.Iterator.ValidFor l r it → it.curr = r.headD default

full_name: String.Iterator.ValidFor.next
code: theorem next : ∀ {it}, ValidFor l (c :: r) it → ValidFor (c :: l) r it.next
  
goal: String.Iterator.ValidFor l (c :: r) it → String.Iterator.ValidFor (c :: l) r it.next

full_name: String.Iterator.ValidFor.prev
code: theorem prev : ∀ {it}, ValidFor (c :: l) r it → ValidFor l (c :: r) it.prev
  
goal: String.Iterator.ValidFor (c :: l) r it → String.Iterator.ValidFor l (c :: r) it.prev

full_name: String.Iterator.ValidFor.prev_nil
code: theorem prev_nil : ∀ {it}, ValidFor [] r it → ValidFor [] r it.prev
  
goal: String.Iterator.ValidFor [] r it → String.Iterator.ValidFor [] r it.prev

full_name: String.Iterator.ValidFor.atEnd
code: theorem atEnd : ∀ {it}, ValidFor l r it → (it.atEnd ↔ r = [])
  
goal: String.Iterator.ValidFor l r it → (it.atEnd = true ↔ r = [])

full_name: String.Iterator.ValidFor.hasNext
code: theorem hasNext : ∀ {it}, ValidFor l r it → (it.hasNext ↔ r ≠ [])
  
goal: String.Iterator.ValidFor l r it → (it.hasNext = true ↔ r ≠ [])

full_name: String.Iterator.ValidFor.hasPrev
code: theorem hasPrev : ∀ {it}, ValidFor l r it → (it.hasPrev ↔ l ≠ [])
  
goal: String.Iterator.ValidFor l r it → (it.hasPrev = true ↔ l ≠ [])

full_name: String.Iterator.ValidFor.setCurr'
code: theorem setCurr' : ∀ {it}, ValidFor l r it →
    ValidFor l (r.modifyHead fun _ => c) (it.setCurr c)
  
goal: String.Iterator.ValidFor l r it → String.Iterator.ValidFor l (List.modifyHead (fun x => c) r) (it.setCurr c)

full_name: String.Iterator.ValidFor.setCurr
code: theorem setCurr (h : ValidFor l (c :: r) it) :
    ValidFor l (c :: r) (it.setCurr c) 
goal: String.Iterator.ValidFor l (c :: r) (it.setCurr c)

full_name: String.Iterator.ValidFor.toEnd
code: theorem toEnd (h : ValidFor l r it) : ValidFor (r.reverse ++ l) [] it.toEnd 
goal: String.Iterator.ValidFor (r.reverse ++ l) [] it.toEnd

full_name: String.Iterator.ValidFor.toEnd'
code: theorem toEnd' (it : Iterator) : ValidFor it.s.1.reverse [] it.toEnd 
goal: String.Iterator.ValidFor it.s.data.reverse [] it.toEnd

full_name: String.Iterator.ValidFor.extract
code: theorem extract (h₁ : ValidFor l (m ++ r) it₁) (h₂ : ValidFor (m.reverse ++ l) r it₂) :
    it₁.extract it₂ = ⟨m⟩ 
goal: it₁.extract it₂ = { data := m }

full_name: String.Iterator.ValidFor.remainingToString
code: theorem remainingToString {it} (h : ValidFor l r it) : it.remainingToString = ⟨r⟩ 
goal: it.remainingToString = { data := r }

full_name: String.Iterator.ValidFor.nextn
code: theorem nextn : ∀ {it}, ValidFor l r it →
      ∀ n, n ≤ r.length → ValidFor ((r.take n).reverse ++ l) (r.drop n) (it.nextn n)
  
goal: String.Iterator.ValidFor l r it →
  ∀ (n : Nat), n ≤ r.length → String.Iterator.ValidFor ((List.take n r).reverse ++ l) (List.drop n r) (it.nextn n)

full_name: String.Iterator.ValidFor.prevn
code: theorem prevn : ∀ {it}, ValidFor l r it →
      ∀ n, n ≤ l.length → ValidFor (l.drop n) ((l.take n).reverse ++ r) (it.prevn n)
  
goal: String.Iterator.ValidFor l r it →
  ∀ (n : Nat), n ≤ l.length → String.Iterator.ValidFor (List.drop n l) ((List.take n l).reverse ++ r) (it.prevn n)

full_name: String.Iterator.Valid.validFor
code: theorem validFor : ∀ {it}, Valid it → ∃ l r, ValidFor l r it
  
goal: it.Valid → ∃ l r, String.Iterator.ValidFor l r it

full_name: String.valid_mkIterator
code: theorem _root_.String.valid_mkIterator (s) : (mkIterator s).Valid 
goal: s.mkIterator.Valid

full_name: String.Iterator.Valid.remainingBytes_le
code: theorem remainingBytes_le : ∀ {it}, Valid it → it.remainingBytes ≤ utf8ByteSize it.s
  
goal: it.Valid → it.remainingBytes ≤ it.s.utf8ByteSize

full_name: String.Iterator.Valid.next
code: theorem next : ∀ {it}, Valid it → it.hasNext → Valid it.next
  
goal: it.Valid → it.hasNext = true → it.next.Valid

full_name: String.Iterator.Valid.prev
code: theorem prev : ∀ {it}, Valid it → Valid it.prev
  
goal: it.Valid → it.prev.Valid

full_name: String.Iterator.Valid.setCurr
code: theorem setCurr : ∀ {it}, Valid it → Valid (it.setCurr c)
  
goal: it.Valid → (it.setCurr c).Valid

full_name: String.Iterator.Valid.toEnd
code: theorem toEnd (it : String.Iterator) : Valid it.toEnd 
goal: it.toEnd.Valid

full_name: String.Iterator.Valid.remainingToString
code: theorem remainingToString {it} (h : ValidFor l r it) : it.remainingToString = ⟨r⟩ 
goal: it.remainingToString = { data := r }

full_name: String.Iterator.Valid.prevn
code: theorem prevn (h : Valid it) : ∀ n, Valid (it.prevn n)
  
goal: (it.prevn n).Valid

full_name: String.offsetOfPosAux_of_valid
code: @[nolint unusedHavesSuffices] -- false positive from unfolding String.offsetOfPosAux
theorem offsetOfPosAux_of_valid : ∀ l m r n,
    offsetOfPosAux ⟨l ++ m ++ r⟩ ⟨utf8Len l + utf8Len m⟩ ⟨utf8Len l⟩ n = n + m.length
  
goal: { data := l ++ m ++ r }.offsetOfPosAux { byteIdx := String.utf8Len l + String.utf8Len m }
    { byteIdx := String.utf8Len l } n =
  n + m.length

full_name: String.offsetOfPos_of_valid
code: theorem offsetOfPos_of_valid (l r) : offsetOfPos ⟨l ++ r⟩ ⟨utf8Len l⟩ = l.length 
goal: { data := l ++ r }.offsetOfPos { byteIdx := String.utf8Len l } = l.length

full_name: String.foldlAux_of_valid
code: @[nolint unusedHavesSuffices] -- false positive from unfolding String.foldlAux
theorem foldlAux_of_valid (f : α → Char → α) : ∀ l m r a,
    foldlAux f ⟨l ++ m ++ r⟩ ⟨utf8Len l + utf8Len m⟩ ⟨utf8Len l⟩ a = m.foldl f a
  
goal: String.foldlAux f { data := l ++ m ++ r } { byteIdx := String.utf8Len l + String.utf8Len m }
    { byteIdx := String.utf8Len l } a =
  List.foldl f a m

full_name: String.foldl_eq
code: theorem foldl_eq (f : α → Char → α) (s a) : foldl f a s = s.1.foldl f a 
goal: String.foldl f a s = List.foldl f a s.data

full_name: String.foldrAux_of_valid
code: @[nolint unusedHavesSuffices] -- false positive from unfolding String.foldrAux
theorem foldrAux_of_valid (f : Char → α → α) (l m r a) :
    foldrAux f a ⟨l ++ m ++ r⟩ ⟨utf8Len l + utf8Len m⟩ ⟨utf8Len l⟩ = m.foldr f a 
goal: String.foldrAux f a { data := l ++ m ++ r } { byteIdx := String.utf8Len l + String.utf8Len m }
    { byteIdx := String.utf8Len l } =
  List.foldr f a m

full_name: String.foldr_eq
code: theorem foldr_eq (f : Char → α → α) (s a) : foldr f a s = s.1.foldr f a 
goal: String.foldr f a s = List.foldr f a s.data

full_name: String.anyAux_of_valid
code: @[nolint unusedHavesSuffices] -- false positive from unfolding String.anyAux
theorem anyAux_of_valid (p : Char → Bool) : ∀ l m r,
    anyAux ⟨l ++ m ++ r⟩ ⟨utf8Len l + utf8Len m⟩ p ⟨utf8Len l⟩ = m.any p
  
goal: { data := l ++ m ++ r }.anyAux { byteIdx := String.utf8Len l + String.utf8Len m } p { byteIdx := String.utf8Len l } =
  m.any p

full_name: String.any_eq
code: theorem any_eq (s : String) (p : Char → Bool) : any s p = s.1.any p 
goal: s.any p = s.data.any p

full_name: String.any_iff
code: theorem any_iff (s : String) (p : Char → Bool) : any s p ↔ ∃ c ∈ s.1, p c 
goal: s.any p = true ↔ ∃ c, c ∈ s.data ∧ p c = true

full_name: String.all_eq
code: theorem all_eq (s : String) (p : Char → Bool) : all s p = s.1.all p 
goal: s.all p = s.data.all p

full_name: String.all_iff
code: theorem all_iff (s : String) (p : Char → Bool) : all s p ↔ ∀ c ∈ s.1, p c 
goal: s.all p = true ↔ ∀ (c : Char), c ∈ s.data → p c = true

full_name: String.contains_iff
code: theorem contains_iff (s : String) (c : Char) : contains s c ↔ c ∈ s.1 
goal: s.contains c = true ↔ c ∈ s.data

full_name: String.mapAux_of_valid
code: @[nolint unusedHavesSuffices] -- false positive from unfolding String.mapAux
theorem mapAux_of_valid (f : Char → Char) : ∀ l r, mapAux f ⟨utf8Len l⟩ ⟨l ++ r⟩ = ⟨l ++ r.map f⟩
  
goal: String.mapAux f { byteIdx := String.utf8Len l } { data := l ++ r } = { data := l ++ List.map f r }

full_name: String.map_eq
code: theorem map_eq (f : Char → Char) (s) : map f s = ⟨s.1.map f⟩ 
goal: String.map f s = { data := List.map f s.data }

full_name: String.takeWhileAux_of_valid
code: @[nolint unusedHavesSuffices] -- false positive from unfolding String.takeWhileAux
theorem takeWhileAux_of_valid (p : Char → Bool) : ∀ l m r,
    Substring.takeWhileAux ⟨l ++ m ++ r⟩ ⟨utf8Len l + utf8Len m⟩ p ⟨utf8Len l⟩ =
      ⟨utf8Len l + utf8Len (m.takeWhile p)⟩
  
goal: Substring.takeWhileAux { data := l ++ m ++ r } { byteIdx := String.utf8Len l + String.utf8Len m } p
    { byteIdx := String.utf8Len l } =
  { byteIdx := String.utf8Len l + String.utf8Len (List.takeWhile p m) }

full_name: Substring.Valid.stopValid
code: /-- Validity for a substring. -/
structure Valid (s : Substring) : Prop where
  /-- The start position of a valid substring is valid. -/
  startValid : s.startPos.Valid s.str
  /-- The stop position of a valid substring is valid. -/
  stopValid : s.stopPos.Valid s.str
  /-- The stop position of a substring is at least the start. -/
  le : s.startPos ≤ s.stopPos
goal: String.Pos.Valid s.str s.stopPos

full_name: Substring.Valid.le
code: /-- Validity for a substring. -/
structure Valid (s : Substring) : Prop where
  /-- The start position of a valid substring is valid. -/
  startValid : s.startPos.Valid s.str
  /-- The stop position of a valid substring is valid. -/
  stopValid : s.stopPos.Valid s.str
  /-- The stop position of a substring is at least the start. -/
  le : s.startPos ≤ s.stopPos
goal: s.startPos ≤ s.stopPos

full_name: Substring.Valid.startValid
code: /-- Validity for a substring. -/
structure Valid (s : Substring) : Prop where
  /-- The start position of a valid substring is valid. -/
  startValid : s.startPos.Valid s.str
  /-- The stop position of a valid substring is valid. -/
  stopValid : s.stopPos.Valid s.str
  /-- The stop position of a substring is at least the start. -/
  le : s.startPos ≤ s.stopPos
goal: String.Pos.Valid s.str s.startPos

full_name: Substring.Valid
code: /-- Validity for a substring. -/
structure Valid (s : Substring) : Prop where
  /-- The start position of a valid substring is valid. -/
  startValid : s.startPos.Valid s.str
  /-- The stop position of a valid substring is valid. -/
  stopValid : s.stopPos.Valid s.str
  /-- The stop position of a substring is at least the start. -/
  le : s.startPos ≤ s.stopPos
goal: Prop

full_name: Substring.Valid_default
code: theorem Valid_default : Valid default 
goal: default.Valid

full_name: Substring.ValidFor
code: /-- 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. -/
inductive ValidFor (l m r : List Char) : Substring → Prop
  /-- The constructor for `ValidFor`. -/
  | mk : ValidFor l m r ⟨⟨l ++ m ++ r⟩, ⟨utf8Len l⟩, ⟨utf8Len l + utf8Len m⟩⟩
goal: Substring → Prop

full_name: Substring.ValidFor.mk
code: /-- 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. -/
inductive ValidFor (l m r : List Char) : Substring → Prop
  /-- The constructor for `ValidFor`. -/
  | mk : ValidFor l m r ⟨⟨l ++ m ++ r⟩, ⟨utf8Len l⟩, ⟨utf8Len l + utf8Len m⟩⟩
goal: Substring.ValidFor l m r
  { str := { data := l ++ m ++ r }, startPos := { byteIdx := String.utf8Len l },
    stopPos := { byteIdx := String.utf8Len l + String.utf8Len m } }

full_name: Substring.ValidFor.valid
code: theorem valid : ∀ {s}, ValidFor l m r s → Valid s
  
goal: Substring.ValidFor l m r s → s.Valid

full_name: Substring.ValidFor.of_eq
code: theorem of_eq : ∀ s,
    s.str.1 = l ++ m ++ r →
    s.startPos.1 = utf8Len l →
    s.stopPos.1 = utf8Len l + utf8Len m →
    ValidFor l m r s
  
goal: s.str.data = l ++ m ++ r →
  s.startPos.byteIdx = String.utf8Len l →
    s.stopPos.byteIdx = String.utf8Len l + String.utf8Len m → Substring.ValidFor l m r s

full_name: String.validFor_toSubstring
code: theorem _root_.String.validFor_toSubstring (s : String) : ValidFor [] s.1 [] s 
goal: Substring.ValidFor [] s.data [] s.toSubstring

full_name: Substring.ValidFor.str
code: theorem str : ∀ {s}, ValidFor l m r s → s.str = ⟨l ++ m ++ r⟩
  
goal: Substring.ValidFor l m r s → s.str = { data := l ++ m ++ r }

full_name: Substring.ValidFor.startPos
code: theorem startPos : ∀ {s}, ValidFor l m r s → s.startPos = ⟨utf8Len l⟩
  
goal: Substring.ValidFor l m r s → s.startPos = { byteIdx := String.utf8Len l }

full_name: Substring.ValidFor.stopPos
code: theorem stopPos : ∀ {s}, ValidFor l m r s → s.stopPos = ⟨utf8Len l + utf8Len m⟩
  
goal: Substring.ValidFor l m r s → s.stopPos = { byteIdx := String.utf8Len l + String.utf8Len m }

full_name: Substring.ValidFor.bsize
code: theorem bsize : ∀ {s}, ValidFor l m r s → s.bsize = utf8Len m
  
goal: Substring.ValidFor l m r s → s.bsize = String.utf8Len m

full_name: Substring.ValidFor.isEmpty
code: theorem isEmpty : ∀ {s}, ValidFor l m r s → (s.isEmpty ↔ m = [])
  
goal: Substring.ValidFor l m r s → (s.isEmpty = true ↔ m = [])

full_name: Substring.ValidFor.toString
code: theorem toString : ∀ {s}, ValidFor l m r s → s.toString = ⟨m⟩
  
goal: Substring.ValidFor l m r s → s.toString = { data := m }

full_name: Substring.ValidFor.toIterator
code: theorem toIterator : ∀ {s}, ValidFor l m r s → s.toIterator.ValidFor l.reverse (m ++ r)
  
goal: Substring.ValidFor l m r s → String.Iterator.ValidFor l.reverse (m ++ r) s.toIterator

full_name: Substring.ValidFor.get
code: theorem get : ∀ {s}, ValidFor l (m₁ ++ c :: m₂) r s → s.get ⟨utf8Len m₁⟩ = c
  
goal: Substring.ValidFor l (m₁ ++ c :: m₂) r s → s.get { byteIdx := String.utf8Len m₁ } = c

full_name: Substring.ValidFor.next
code: theorem next : ∀ {s}, ValidFor l (m₁ ++ c :: m₂) r s →
    s.next ⟨utf8Len m₁⟩ = ⟨utf8Len m₁ + c.utf8Size⟩
  
goal: Substring.ValidFor l (m₁ ++ c :: m₂) r s →
  s.next { byteIdx := String.utf8Len m₁ } = { byteIdx := String.utf8Len m₁ + c.utf8Size }

full_name: Substring.ValidFor.next_stop
code: theorem next_stop : ∀ {s}, ValidFor l m r s → s.next ⟨utf8Len m⟩ = ⟨utf8Len m⟩
  
goal: Substring.ValidFor l m r s → s.next { byteIdx := String.utf8Len m } = { byteIdx := String.utf8Len m }

full_name: Substring.ValidFor.prev
code: theorem prev : ∀ {s}, ValidFor l (m₁ ++ c :: m₂) r s →
    s.prev ⟨utf8Len m₁ + c.utf8Size⟩ = ⟨utf8Len m₁⟩
  
goal: Substring.ValidFor l (m₁ ++ c :: m₂) r s →
  s.prev { byteIdx := String.utf8Len m₁ + c.utf8Size } = { byteIdx := String.utf8Len m₁ }

full_name: Substring.ValidFor.nextn_stop
code: theorem nextn_stop : ∀ {s}, ValidFor l m r s → ∀ n, s.nextn n ⟨utf8Len m⟩ = ⟨utf8Len m⟩
  
goal: Substring.ValidFor l m r s → ∀ (n : Nat), s.nextn n { byteIdx := String.utf8Len m } = { byteIdx := String.utf8Len m }

full_name: Substring.ValidFor.nextn
code: theorem nextn : ∀ {s}, ValidFor l (m₁ ++ m₂) r s →
    ∀ n, s.nextn n ⟨utf8Len m₁⟩ = ⟨utf8Len m₁ + utf8Len (m₂.take n)⟩
  
goal: Substring.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₂) }

full_name: Substring.ValidFor.prevn
code: theorem prevn : ∀ {s}, ValidFor l (m₁.reverse ++ m₂) r s →
    ∀ n, s.prevn n ⟨utf8Len m₁⟩ = ⟨utf8Len (m₁.drop n)⟩
  
goal: Substring.ValidFor l (m₁.reverse ++ m₂) r s →
  ∀ (n : Nat), s.prevn n { byteIdx := String.utf8Len m₁ } = { byteIdx := String.utf8Len (List.drop n m₁) }

full_name: Substring.ValidFor.front
code: theorem front : ∀ {s}, ValidFor l (c :: m) r s → s.front = c
  
goal: Substring.ValidFor l (c :: m) r s → s.front = c

full_name: Substring.ValidFor.drop
code: theorem drop : ∀ {s}, ValidFor l m r s → ∀ n, ValidFor (l ++ m.take n) (m.drop n) r (s.drop n)
  
goal: Substring.ValidFor l m r s → ∀ (n : Nat), Substring.ValidFor (l ++ List.take n m) (List.drop n m) r (s.drop n)

full_name: Substring.ValidFor.take
code: theorem take : ∀ {s}, ValidFor l m r s → ∀ n, ValidFor l (m.take n) (m.drop n ++ r) (s.take n)
  
goal: Substring.ValidFor l m r s → ∀ (n : Nat), Substring.ValidFor l (List.take n m) (List.drop n m ++ r) (s.take n)

full_name: Substring.ValidFor.atEnd
code: theorem atEnd : ∀ {s}, ValidFor l m r s → (s.atEnd ⟨p⟩ ↔ p = utf8Len m)
  
goal: Substring.ValidFor l m r s → (s.atEnd { byteIdx := p } = true ↔ p = String.utf8Len m)

full_name: Substring.ValidFor.extract
code: theorem extract : ∀ {s}, ValidFor l m r s → ValidFor ml mm mr ⟨⟨m⟩, b, e⟩ →
    ∃ l' r', ValidFor l' mm r' (s.extract b e)
  
goal: Substring.ValidFor l m r s →
  Substring.ValidFor ml mm mr { str := { data := m }, startPos := b, stopPos := e } →
    ∃ l' r', Substring.ValidFor l' mm r' (s.extract b e)

full_name: Substring.ValidFor.foldl
code: theorem foldl (f) (init : α) : ∀ {s}, ValidFor l m r s → s.foldl f init = m.foldl f init
  
goal: Substring.ValidFor l m r s → Substring.foldl f init s = List.foldl f init m

full_name: Substring.ValidFor.foldr
code: theorem foldr (f) (init : α) : ∀ {s}, ValidFor l m r s → s.foldr f init = m.foldr f init
  
goal: Substring.ValidFor l m r s → Substring.foldr f init s = List.foldr f init m

full_name: Substring.ValidFor.any
code: theorem any (f) : ∀ {s}, ValidFor l m r s → s.any f = m.any f
  
goal: Substring.ValidFor l m r s → s.any f = m.any f

full_name: Substring.ValidFor.all
code: theorem all (f) : ∀ {s}, ValidFor l m r s → s.all f = m.all f
  
goal: Substring.ValidFor l m r s → s.all f = m.all f

full_name: Substring.ValidFor.contains
code: theorem contains (c) : ∀ {s}, ValidFor l m r s → (s.contains c ↔ c ∈ m)
  
goal: Substring.ValidFor l m r s → (s.contains c = true ↔ c ∈ m)

full_name: Substring.ValidFor.takeWhile
code: theorem takeWhile (p : Char → Bool) : ∀ {s}, ValidFor l m r s →
    ValidFor l (m.takeWhile p) (m.dropWhile p ++ r) (s.takeWhile p)
  
goal: Substring.ValidFor l m r s → Substring.ValidFor l (List.takeWhile p m) (List.dropWhile p m ++ r) (s.takeWhile p)

full_name: Substring.ValidFor.dropWhile
code: theorem dropWhile (p : Char → Bool) : ∀ {s}, ValidFor l m r s →
    ValidFor (l ++ m.takeWhile p) (m.dropWhile p) r (s.dropWhile p)
  
goal: Substring.ValidFor l m r s → Substring.ValidFor (l ++ List.takeWhile p m) (List.dropWhile p m) r (s.dropWhile p)

full_name: Substring.Valid.validFor
code: theorem validFor : ∀ {s}, Valid s → ∃ l m r, ValidFor l m r s
  
goal: s.Valid → ∃ l m r, Substring.ValidFor l m r s

full_name: Substring.Valid.valid
code: theorem valid : ∀ {s}, ValidFor l m r s → Valid s
  
goal: Substring.ValidFor l m r s → s.Valid

full_name: String.valid_toSubstring
code: theorem _root_.String.valid_toSubstring (s : String) : Valid s 
goal: s.toSubstring.Valid

full_name: Substring.Valid.bsize
code: theorem bsize : ∀ {s}, Valid s → s.bsize = utf8Len s.toString.1
  
goal: s.Valid → s.bsize = String.utf8Len s.toString.data

full_name: Substring.Valid.isEmpty
code: theorem isEmpty : ∀ {s}, Valid s → (s.isEmpty ↔ s.toString = "")
  
goal: s.Valid → (s.isEmpty = true ↔ s.toString = "")

full_name: Substring.Valid.get
code: theorem get : ∀ {s}, Valid s → s.toString.1 = m₁ ++ c :: m₂ → s.get ⟨utf8Len m₁⟩ = c
  
goal: s.Valid → s.toString.data = m₁ ++ c :: m₂ → s.get { byteIdx := String.utf8Len m₁ } = c

full_name: Substring.Valid.next
code: theorem next : ∀ {s}, Valid s → s.toString.1 = m₁ ++ c :: m₂ →
    s.next ⟨utf8Len m₁⟩ = ⟨utf8Len m₁ + c.utf8Size⟩
  
goal: s.Valid →
  s.toString.data = m₁ ++ c :: m₂ →
    s.next { byteIdx := String.utf8Len m₁ } = { byteIdx := String.utf8Len m₁ + c.utf8Size }

full_name: Substring.Valid.next_stop
code: theorem next_stop : ∀ {s}, Valid s → s.next ⟨s.bsize⟩ = ⟨s.bsize⟩
  
goal: s.Valid → s.next { byteIdx := s.bsize } = { byteIdx := s.bsize }

full_name: Substring.Valid.prev
code: theorem prev : ∀ {s}, Valid s → s.toString.1 = m₁ ++ c :: m₂ →
    s.prev ⟨utf8Len m₁ + c.utf8Size⟩ = ⟨utf8Len m₁⟩
  
goal: s.Valid →
  s.toString.data = m₁ ++ c :: m₂ →
    s.prev { byteIdx := String.utf8Len m₁ + c.utf8Size } = { byteIdx := String.utf8Len m₁ }

full_name: Substring.Valid.nextn_stop
code: theorem nextn_stop : ∀ {s}, Valid s → ∀ n, s.nextn n ⟨s.bsize⟩ = ⟨s.bsize⟩
  
goal: s.Valid → ∀ (n : Nat), s.nextn n { byteIdx := s.bsize } = { byteIdx := s.bsize }

full_name: Substring.Valid.nextn
code: theorem nextn : ∀ {s}, Valid s → s.toString.1 = m₁ ++ m₂ →
    ∀ n, s.nextn n ⟨utf8Len m₁⟩ = ⟨utf8Len m₁ + utf8Len (m₂.take n)⟩
  
goal: s.Valid →
  s.toString.data = m₁ ++ m₂ →
    ∀ (n : Nat),
      s.nextn n { byteIdx := String.utf8Len m₁ } = { byteIdx := String.utf8Len m₁ + String.utf8Len (List.take n m₂) }

full_name: Substring.Valid.prevn
code: theorem prevn : ∀ {s}, Valid s → s.toString.1 = m₁.reverse ++ m₂ →
    ∀ n, s.prevn n ⟨utf8Len m₁⟩ = ⟨utf8Len (m₁.drop n)⟩
  
goal: s.Valid →
  s.toString.data = m₁.reverse ++ m₂ →
    ∀ (n : Nat), s.prevn n { byteIdx := String.utf8Len m₁ } = { byteIdx := String.utf8Len (List.drop n m₁) }

full_name: Substring.Valid.front
code: theorem front : ∀ {s}, Valid s → s.toString.1 = c :: m → s.front = c
  
goal: s.Valid → s.toString.data = c :: m → s.front = c

full_name: Substring.Valid.drop
code: theorem drop : ∀ {s}, Valid s → ∀ n, Valid (s.drop n)
  
goal: s.Valid → ∀ (n : Nat), (s.drop n).Valid

full_name: Substring.Valid.data_drop
code: theorem data_drop : ∀ {s}, Valid s → ∀ n, (s.drop n).toString.1 = s.toString.1.drop n
  
goal: s.Valid → ∀ (n : Nat), (s.drop n).toString.data = List.drop n s.toString.data

full_name: Substring.Valid.take
code: theorem take : ∀ {s}, Valid s → ∀ n, Valid (s.take n)
  
goal: s.Valid → ∀ (n : Nat), (s.take n).Valid

full_name: Substring.Valid.data_take
code: theorem data_take : ∀ {s}, Valid s → ∀ n, (s.take n).toString.1 = s.toString.1.take n
  
goal: s.Valid → ∀ (n : Nat), (s.take n).toString.data = List.take n s.toString.data

full_name: Substring.Valid.atEnd
code: theorem atEnd : ∀ {s}, Valid s → (s.atEnd ⟨p⟩ ↔ p = utf8ByteSize s.toString)
  
goal: s.Valid → (s.atEnd { byteIdx := p } = true ↔ p = s.toString.utf8ByteSize)

full_name: Substring.Valid.extract
code: theorem extract : ∀ {s}, Valid s → Valid ⟨s.toString, b, e⟩ → Valid (s.extract b e)
  
goal: s.Valid → { str := s.toString, startPos := b, stopPos := e }.Valid → (s.extract b e).Valid

full_name: Substring.Valid.toString_extract
code: theorem toString_extract : ∀ {s}, Valid s → Valid ⟨s.toString, b, e⟩ →
    (s.extract b e).toString = s.toString.extract b e
  
goal: s.Valid → { str := s.toString, startPos := b, stopPos := e }.Valid → (s.extract b e).toString = s.toString.extract b e

full_name: Substring.Valid.foldl
code: theorem foldl (f) (init : α) : ∀ {s}, Valid s → s.foldl f init = s.toString.1.foldl f init
  
goal: s.Valid → Substring.foldl f init s = List.foldl f init s.toString.data

full_name: Substring.Valid.foldr
code: theorem foldr (f) (init : α) : ∀ {s}, Valid s → s.foldr f init = s.toString.1.foldr f init
  
goal: s.Valid → Substring.foldr f init s = List.foldr f init s.toString.data

full_name: Substring.Valid.any
code: theorem any (f) : ∀ {s}, Valid s → s.any f = s.toString.1.any f
  
goal: s.Valid → s.any f = s.toString.data.any f

full_name: Substring.Valid.all
code: theorem all (f) : ∀ {s}, Valid s → s.all f = s.toString.1.all f
  
goal: s.Valid → s.all f = s.toString.data.all f

full_name: Substring.Valid.contains
code: theorem contains (c) : ∀ {s}, Valid s → (s.contains c ↔ c ∈ s.toString.1)
  
goal: s.Valid → (s.contains c = true ↔ c ∈ s.toString.data)

full_name: Substring.Valid.takeWhile
code: theorem takeWhile (p : Char → Bool) : ∀ {s}, Valid s → Valid (s.takeWhile p)
  
goal: s.Valid → (s.takeWhile p).Valid

full_name: Substring.Valid.data_takeWhile
code: theorem data_takeWhile (p) : ∀ {s}, Valid s →
    (s.takeWhile p).toString.1 = s.toString.1.takeWhile p
  
goal: s.Valid → (s.takeWhile p).toString.data = List.takeWhile p s.toString.data

full_name: Substring.Valid.dropWhile
code: theorem dropWhile (p : Char → Bool) : ∀ {s}, Valid s → Valid (s.dropWhile p)
  
goal: s.Valid → (s.dropWhile p).Valid

full_name: Substring.Valid.data_dropWhile
code: theorem data_dropWhile (p) : ∀ {s}, Valid s →
    (s.dropWhile p).toString.1 = s.toString.1.dropWhile p
  
goal: s.Valid → (s.dropWhile p).toString.data = List.dropWhile p s.toString.data

full_name: String.drop_eq
code: theorem drop_eq (s : String) (n : Nat) : s.drop n = ⟨s.1.drop n⟩ 
goal: s.drop n = { data := List.drop n s.data }

full_name: String.data_drop
code: @[simp] theorem data_drop (s : String) (n : Nat) : (s.drop n).1 = s.1.drop n 
goal: (s.drop n).data = List.drop n s.data

full_name: String.drop_empty
code: @[simp] theorem drop_empty {n : Nat} : "".drop n = "" 
goal: "".drop n = ""

full_name: String.take_eq
code: theorem take_eq (s : String) (n : Nat) : s.take n = ⟨s.1.take n⟩ 
goal: s.take n = { data := List.take n s.data }

full_name: String.data_take
code: @[simp] theorem data_take (s : String) (n : Nat) : (s.take n).1 = s.1.take n 
goal: (s.take n).data = List.take n s.data

full_name: String.takeWhile_eq
code: theorem takeWhile_eq (p : Char → Bool) (s : String) : s.takeWhile p = ⟨s.1.takeWhile p⟩ 
goal: s.takeWhile p = { data := List.takeWhile p s.data }

full_name: String.data_takeWhile
code: @[simp] theorem data_takeWhile (p : Char → Bool) (s : String) :
    (s.takeWhile p).1 = s.1.takeWhile p 
goal: (s.takeWhile p).data = List.takeWhile p s.data

full_name: String.dropWhile_eq
code: theorem dropWhile_eq (p : Char → Bool) (s : String) : s.dropWhile p = ⟨s.1.dropWhile p⟩ 
goal: s.dropWhile p = { data := List.dropWhile p s.data }

full_name: String.data_dropWhile
code: @[simp] theorem data_dropWhile (p : Char → Bool) (s : String) :
    (s.dropWhile p).1 = s.1.dropWhile p 
goal: (s.dropWhile p).data = List.dropWhile p s.data