@@ -1104,7 +1104,7 @@ def Slice.slice? (s : Slice) (newStart newEnd : s.Pos) : Option Slice :=
11041104/-- Given a slice and two valid positions within the slice, obtain a new slice on the same underlying
11051105string formed by the new bounds, or panic if the given end is strictly less than the given start. -/
11061106def Slice.slice! (s : Slice) (newStart newEnd : s.Pos) : Slice :=
1107- if h : newStart.offset ≤ newEnd.offset then
1107+ if h : newStart ≤ newEnd then
11081108 s.slice newStart newEnd h
11091109 else
11101110 panic! "Starting position must be less than or equal to end position."
@@ -1219,12 +1219,12 @@ theorem Pos.offset_toSlice {s : String} {pos : s.Pos} : pos.toSlice.offset = pos
12191219/-- Given a string `s`, turns a valid position on the slice `s.toSlice` into a valid position on the
12201220string `s`. -/
12211221@[inline, expose]
1222- def Slice. Pos.ofSlice {s : String} (pos : s.toSlice.Pos) : s.Pos where
1222+ def Pos.ofToSlice {s : String} (pos : s.toSlice.Pos) : s.Pos where
12231223 offset := pos.offset
12241224 isValid := pos.isValidForSlice.ofSlice
12251225
12261226@[simp]
1227- theorem Slice. Pos.offset_ofSlice {s : String} {pos : s.toSlice.Pos} : pos.ofSlice .offset = pos.offset := (rfl)
1227+ theorem Pos.offset_ofToSlice {s : String} {pos : s.toSlice.Pos} : (ofToSlice pos) .offset = pos.offset := (rfl)
12281228
12291229@[simp]
12301230theorem rawEndPos_toSlice {s : String} : s.toSlice.rawEndPos = s.rawEndPos := by
@@ -1239,44 +1239,44 @@ theorem startPos_toSlice {s : String} : s.toSlice.startPos = s.startPos.toSlice
12391239 Slice.Pos.ext (by simp)
12401240
12411241@[simp]
1242- theorem Pos.ofSlice_toSlice {s : String} (pos : s.Pos) : pos.toSlice.ofSlice = pos :=
1242+ theorem Pos.ofToSlice_toSlice {s : String} (pos : s.Pos) : (ofToSlice pos.toSlice) = pos :=
12431243 Pos.ext (by simp)
12441244
12451245@[simp]
1246- theorem Slice.Pos.toSlice_ofSlice {s : String} (pos : s.toSlice.Pos) : pos.ofSlice .toSlice = pos :=
1246+ theorem Slice.Pos.toSlice_ofToSlice {s : String} (pos : s.toSlice.Pos) : (Pos.ofToSlice pos) .toSlice = pos :=
12471247 Slice.Pos.ext (by simp)
12481248
12491249@[simp]
1250- theorem Slice. Pos.toSlice_comp_ofSlice {s : String} :
1251- Pos.toSlice ∘ (ofSlice (s := s)) = id := by ext; simp
1250+ theorem Pos.toSlice_comp_ofToSlice {s : String} :
1251+ Pos.toSlice ∘ (Pos.ofToSlice (s := s)) = id := by ext; simp
12521252
12531253@[simp]
1254- theorem Pos.ofSlice_comp_toSlice {s : String} :
1255- Slice. Pos.ofSlice ∘ (toSlice (s := s)) = id := by ext; simp
1254+ theorem Pos.ofToSlice_comp_toSlice {s : String} :
1255+ Pos.ofToSlice ∘ (toSlice (s := s)) = id := by ext; simp
12561256
12571257theorem Pos.toSlice_inj {s : String} {p q : s.Pos} : p.toSlice = q.toSlice ↔ p = q :=
1258- ⟨fun h => by simpa using congrArg Slice. Pos.ofSlice h, (· ▸ rfl)⟩
1258+ ⟨fun h => by simpa using congrArg Pos.ofToSlice h, (· ▸ rfl)⟩
12591259
1260- theorem Slice. Pos.ofSlice_inj {s : String} {p q : s.toSlice.Pos} : p.ofSlice = q.ofSlice ↔ p = q :=
1260+ theorem Pos.ofToSlice_inj {s : String} {p q : s.toSlice.Pos} : ofToSlice p = ofToSlice q ↔ p = q :=
12611261 ⟨fun h => by simpa using congrArg Pos.toSlice h, (· ▸ rfl)⟩
12621262
12631263@[simp]
12641264theorem Pos.toSlice_le {s : String} {p q : s.Pos} : p.toSlice ≤ q.toSlice ↔ p ≤ q := by
12651265 simp [le_iff, Slice.Pos.le_iff]
12661266
12671267@[simp]
1268- theorem Slice. Pos.ofSlice_le {s : String} {p q : s.toSlice.Pos} :
1269- p.ofSlice ≤ q.ofSlice ↔ p ≤ q := by
1270- simp [String.Pos. le_iff, le_iff]
1268+ theorem Pos.ofToSlice_le {s : String} {p q : s.toSlice.Pos} :
1269+ ofToSlice p ≤ ofToSlice q ↔ p ≤ q := by
1270+ simp [le_iff, Slice.Pos. le_iff]
12711271
12721272@[simp]
12731273theorem Pos.toSlice_lt {s : String} {p q : s.Pos} : p.toSlice < q.toSlice ↔ p < q := by
12741274 simp [lt_iff, Slice.Pos.lt_iff]
12751275
12761276@[simp]
1277- theorem Slice. Pos.ofSlice_lt {s : String} {p q : s.toSlice.Pos} :
1278- p.ofSlice < q.ofSlice ↔ p < q := by
1279- simp [String.Pos. lt_iff, lt_iff]
1277+ theorem Pos.ofToSlice_lt {s : String} {p q : s.toSlice.Pos} :
1278+ ofToSlice p < ofToSlice q ↔ p < q := by
1279+ simp [lt_iff, Slice.Pos. lt_iff]
12801280
12811281/--
12821282Returns the character at the position `pos` of a string, taking a proof that `p` is not the
@@ -1290,7 +1290,7 @@ Examples:
12901290 -/
12911291@[inline, expose]
12921292def Pos.get {s : String} (pos : s.Pos) (h : pos ≠ s.endPos) : Char :=
1293- pos.toSlice.get (ne_of_apply_ne Slice. Pos.ofSlice (by simp [h]))
1293+ pos.toSlice.get (ne_of_apply_ne Pos.ofToSlice (by simp [h]))
12941294
12951295/--
12961296Returns the character at the position `pos` of a string, or `none` if the position is the
@@ -1317,7 +1317,7 @@ Returns the byte at the position `pos` of a string.
13171317-/
13181318@[inline, expose]
13191319def Pos.byte {s : String} (pos : s.Pos) (h : pos ≠ s.endPos) : UInt8 :=
1320- pos.toSlice.byte (ne_of_apply_ne Slice. Pos.ofSlice (by simp [h]))
1320+ pos.toSlice.byte (ne_of_apply_ne Pos.ofToSlice (by simp [h]))
13211321
13221322theorem Pos.isUTF8FirstByte_byte {s : String} {pos : s.Pos} {h : pos ≠ s.endPos} :
13231323 (pos.byte h).IsUTF8FirstByte :=
@@ -1661,60 +1661,56 @@ def Slice.pos! (s : Slice) (off : String.Pos.Raw) : s.Pos :=
16611661position is not the past-the-end position, which guarantees that such a position exists. -/
16621662@[expose, extern "lean_string_utf8_next_fast"]
16631663def Pos.next {s : @& String} (pos : @& s.Pos) (h : pos ≠ s.endPos) : s.Pos :=
1664- (Slice.Pos.next pos.toSlice (ne_of_apply_ne Slice. Pos.ofSlice (by simpa))).ofSlice
1664+ ofToSlice (Slice.Pos.next pos.toSlice (ne_of_apply_ne Pos.ofToSlice (by simpa)))
16651665
16661666@[simp]
16671667theorem Slice.Pos.str_inj {s : Slice} (p₁ p₂ : s.Pos) : p₁.str = p₂.str ↔ p₁ = p₂ := by
16681668 simp [Slice.Pos.ext_iff, String.Pos.ext_iff, Pos.Raw.ext_iff]
16691669
1670- @[expose, extern "lean_string_utf8_next_fast"]
1671- def String.Pos.next {s : @& String} (pos : @& s.Pos) (h : pos ≠ s.endPos) : s.Pos :=
1672- (Slice.Pos.next pos.toSlice (ne_of_apply_ne Slice.Pos.ofSlice (by simpa))).ofSlice
1673-
16741670/-- Advances a valid position on a string to the next valid position, or returns `none` if the
16751671given position is the past-the-end position. -/
16761672@[inline, expose]
16771673def Pos.next? {s : String} (pos : s.Pos) : Option s.Pos :=
1678- pos.toSlice.next?.map Slice. Pos.ofSlice
1674+ pos.toSlice.next?.map Pos.ofToSlice
16791675
16801676/-- Advances a valid position on a string to the next valid position, or panics if the given
16811677position is the past-the-end position. -/
16821678@[inline, expose]
16831679def Pos.next! {s : String} (pos : s.Pos) : s.Pos :=
1684- pos.toSlice.next!.ofSlice
1680+ ofToSlice pos.toSlice.next!
16851681
16861682/-- Returns the previous valid position before the given position, given a proof that the position
16871683is not the start position, which guarantees that such a position exists. -/
16881684@[inline, expose]
16891685def Pos.prev {s : String} (pos : s.Pos) (h : pos ≠ s.startPos) : s.Pos :=
1690- (pos.toSlice.prev (ne_of_apply_ne Slice. Pos.ofSlice (by simpa))).ofSlice
1686+ ofToSlice (pos.toSlice.prev (ne_of_apply_ne Pos.ofToSlice (by simpa)))
16911687
16921688/-- Returns the previous valid position before the given position, or `none` if the position is
16931689the start position. -/
16941690@[inline, expose]
16951691def Pos.prev? {s : String} (pos : s.Pos) : Option s.Pos :=
1696- pos.toSlice.prev?.map Slice. Pos.ofSlice
1692+ pos.toSlice.prev?.map Pos.ofToSlice
16971693
16981694/-- Returns the previous valid position before the given position, or panics if the position is
16991695the start position. -/
17001696@[inline, expose]
17011697def Pos.prev! {s : String} (pos : s.Pos) : s.Pos :=
1702- pos.toSlice.prev!.ofSlice
1698+ ofToSlice pos.toSlice.prev!
17031699
17041700/-- Constructs a valid position on `s` from a position and a proof that it is valid. -/
17051701@[inline, expose]
17061702def pos (s : String) (off : Pos.Raw) (h : off.IsValid s) : s.Pos :=
1707- (s.toSlice.pos off h.toSlice).ofSlice
1703+ Pos.ofToSlice (s.toSlice.pos off h.toSlice)
17081704
17091705/-- Constructs a valid position on `s` from a position, returning `none` if the position is not valid. -/
17101706@[inline, expose]
17111707def pos? (s : String) (off : Pos.Raw) : Option s.Pos :=
1712- (s.toSlice.pos? off).map Slice. Pos.ofSlice
1708+ (s.toSlice.pos? off).map Pos.ofToSlice
17131709
17141710/-- Constructs a valid position `s` from a position, panicking if the position is not valid. -/
17151711@[inline, expose]
17161712def pos! (s : String) (off : Pos.Raw) : s.Pos :=
1717- (s.toSlice.pos! off).ofSlice
1713+ Pos.ofToSlice (s.toSlice.pos! off)
17181714
17191715@[simp]
17201716theorem offset_pos {s : String} {off : Pos.Raw} {h} : (s.pos off h).offset = off := rfl
@@ -1814,10 +1810,10 @@ theorem Slice.Pos.prev_ne_endPos {s : Slice} {p : s.Pos} {h} : p.prev h ≠ s.en
18141810
18151811@[simp]
18161812theorem Pos.prev_ne_endPos {s : String} {p : s.Pos} {h} : p.prev h ≠ s.endPos :=
1817- mt (congrArg (·.toSlice)) (Slice.Pos.prev_ne_endPos (h := mt (congrArg (·.ofSlice)) h ))
1813+ mt (congrArg (·.toSlice)) (Slice.Pos.prev_ne_endPos (h := mt (congrArg Pos.ofToSlice) ( by simpa) ))
18181814
18191815theorem Pos.toSlice_prev {s : String} {p : s.Pos} {h} :
1820- (p.prev h).toSlice = p.toSlice.prev (ne_of_apply_ne Slice. Pos.ofSlice (by simpa)) := by
1816+ (p.prev h).toSlice = p.toSlice.prev (ne_of_apply_ne Pos.ofToSlice (by simpa)) := by
18211817 simp [prev]
18221818
18231819theorem Slice.Pos.offset_prev_lt_offset {s : Slice} {p : s.Pos} {h} : (p.prev h).offset < p.offset := by
@@ -1936,7 +1932,7 @@ theorem Pos.get_toSlice {s : String} {p : s.Pos} {h} :
19361932 rfl
19371933
19381934theorem Pos.get_eq_get_toSlice {s : String} {p : s.Pos} {h} :
1939- p.get h = p.toSlice.get (ne_of_apply_ne Slice. Pos.ofSlice (by simp [h])) := rfl
1935+ p.get h = p.toSlice.get (ne_of_apply_ne Pos.ofToSlice (by simp [h])) := rfl
19401936
19411937@[simp]
19421938theorem Pos.offset_next {s : String} (p : s.Pos) (h : p ≠ s.endPos) :
@@ -1948,7 +1944,7 @@ theorem Pos.byteIdx_offset_next {s : String} (p : s.Pos) (h : p ≠ s.endPos) :
19481944 simp
19491945
19501946theorem Pos.toSlice_next {s : String} {p : s.Pos} {h} :
1951- (p.next h).toSlice = p.toSlice.next (ne_of_apply_ne Slice. Pos.ofSlice (by simpa)) := by
1947+ (p.next h).toSlice = p.toSlice.next (ne_of_apply_ne Pos.ofToSlice (by simpa)) := by
19521948 simp [next]
19531949
19541950theorem Pos.byteIdx_lt_utf8ByteSize {s : String} (p : s.Pos) (h : p ≠ s.endPos) :
@@ -2052,15 +2048,15 @@ theorem Slice.Pos.next_le_of_lt {s : Slice} {p q : s.Pos} {h} : p < q → p.next
20522048 · have := (p.next h).str.isValid.le_utf8ByteSize
20532049 simpa [Nat.add_assoc] using this
20542050
2055- theorem Slice. Pos.ofSlice_le_iff {s : String} {p : s.toSlice.Pos} {q : s.Pos} :
2056- p.ofSlice ≤ q ↔ p ≤ q.toSlice := Iff.rfl
2051+ theorem Pos.ofToSlice_le_iff {s : String} {p : s.toSlice.Pos} {q : s.Pos} :
2052+ ofToSlice p ≤ q ↔ p ≤ q.toSlice := Iff.rfl
20572053
20582054@[simp]
20592055theorem Pos.toSlice_lt_toSlice_iff {s : String} {p q : s.Pos} :
20602056 p.toSlice < q.toSlice ↔ p < q := Iff.rfl
20612057
20622058theorem Pos.next_le_of_lt {s : String} {p q : s.Pos} {h} : p < q → p.next h ≤ q := by
2063- rw [next, Slice. Pos.ofSlice_le_iff , ← Pos.toSlice_lt_toSlice_iff]
2059+ rw [next, Pos.ofToSlice_le_iff , ← Pos.toSlice_lt_toSlice_iff]
20642060 exact Slice.Pos.next_le_of_lt
20652061
20662062theorem Slice.Pos.get_eq_get_str {s : Slice} {p : s.Pos} {h} :
@@ -2159,23 +2155,22 @@ This happens to be equivalent to the constructor of `String.Slice`.
21592155-/
21602156@[inline, expose] -- For the defeq `(s.slice p₁ p₂).str = s`
21612157def slice (s : String) (startInclusive endExclusive : s.Pos)
2162- (h : startInclusive ≤ endExclusive) : String.Slice where
2163- str := s
2164- startInclusive
2165- endExclusive
2166- startInclusive_le_endExclusive := h
2158+ (h : startInclusive ≤ endExclusive) : String.Slice :=
2159+ s.toSlice.slice startInclusive.toSlice endExclusive.toSlice (by simpa)
21672160
21682161@[simp]
21692162theorem str_slice {s : String} {startInclusive endExclusive h} :
21702163 (s.slice startInclusive endExclusive h).str = s := rfl
21712164
21722165@[simp]
21732166theorem startInclusive_slice {s : String} {startInclusive endExclusive h} :
2174- (s.slice startInclusive endExclusive h).startInclusive = startInclusive := rfl
2167+ (s.slice startInclusive endExclusive h).startInclusive = startInclusive := by
2168+ simp [slice]
21752169
21762170@[simp]
21772171theorem endExclusive_slice {s : String} {startInclusive endExclusive h} :
2178- (s.slice startInclusive endExclusive h).endExclusive = endExclusive := rfl
2172+ (s.slice startInclusive endExclusive h).endExclusive = endExclusive := by
2173+ simp [slice]
21792174
21802175/-- Given a string and two valid positions within the string, obtain a slice on the string formed
21812176by the new bounds, or return `none` if the given end is strictly less then the given start. -/
@@ -2311,6 +2306,127 @@ def Pos.toReplaceEnd {s : String} (p₀ : s.Pos) (pos : s.Pos) (h : pos ≤ p₀
23112306theorem Pos.offset_sliceTo {s : String} {p₀ : s.Pos} {pos : s.Pos} {h : pos ≤ p₀} :
23122307 (sliceTo p₀ pos h).offset = pos.offset := (rfl)
23132308
2309+ theorem Pos.Raw.isValidForSlice_slice {s : Slice} {p₀ p₁ : s.Pos} {h} (pos : Pos.Raw) :
2310+ pos.IsValidForSlice (s.slice p₀ p₁ h) ↔
2311+ pos.offsetBy p₀.offset ≤ p₁.offset ∧ (pos.offsetBy p₀.offset).IsValidForSlice s := by
2312+ refine ⟨fun ⟨h₁, h₂⟩ => ?_, fun ⟨h₁, h₂⟩ => ⟨?_, ?_⟩⟩
2313+ · have : pos.offsetBy p₀.offset ≤ p₁.offset := by
2314+ simp [Slice.Pos.le_iff, Pos.Raw.le_iff, Slice.utf8ByteSize_eq] at h h₁ ⊢
2315+ omega
2316+ exact ⟨this, ⟨Pos.Raw.le_trans this p₁.isValidForSlice.le_rawEndPos, by simpa [offsetBy_assoc]⟩⟩
2317+ · simp [Slice.Pos.le_iff, Pos.Raw.le_iff, Slice.utf8ByteSize_eq] at h h₁ ⊢
2318+ omega
2319+ · simpa [offsetBy_assoc] using h₂.isValid_offsetBy
2320+
2321+ theorem Pos.Raw.isValidForSlice_stringSlice {s : String} {p₀ p₁ : s.Pos} {h} (pos : Pos.Raw) :
2322+ pos.IsValidForSlice (s.slice p₀ p₁ h) ↔
2323+ pos.offsetBy p₀.offset ≤ p₁.offset ∧ (pos.offsetBy p₀.offset).IsValid s := by
2324+ simp [slice, isValidForSlice_slice]
2325+
2326+ /-- Given a position in `s.slice p₀ p₁ h`, obtain the corresponding position in `s`. -/
2327+ @[inline]
2328+ def Slice.Pos.ofSlice {s : Slice} {p₀ p₁ : s.Pos} {h} (pos : (s.slice p₀ p₁ h).Pos) : s.Pos where
2329+ offset := pos.offset.offsetBy p₀.offset
2330+ isValidForSlice := (Pos.Raw.isValidForSlice_slice _).1 pos.isValidForSlice |>.2
2331+ @[simp]
2332+ theorem Slice.Pos.offset_ofSlice {s : Slice} {p₀ p₁ : s.Pos} {h} {pos : (s.slice p₀ p₁ h).Pos} :
2333+ (Pos.ofSlice pos).offset = pos.offset.offsetBy p₀.offset := (rfl)
2334+
2335+ /-- Given a position in `s.slice p₀ p₁ h`, obtain the corresponding position in `s`. -/
2336+ @[inline]
2337+ def Pos.ofSlice {s : String} {p₀ p₁ : s.Pos} {h} (pos : (s.slice p₀ p₁ h).Pos) : s.Pos :=
2338+ ofToSlice (Slice.Pos.ofSlice pos)
2339+
2340+ @[simp]
2341+ theorem Pos.offset_ofSlice {s : String} {p₀ p₁ : s.Pos} {h} {pos : (s.slice p₀ p₁ h).Pos} :
2342+ (Pos.ofSlice pos).offset = pos.offset.offsetBy p₀.offset := (rfl)
2343+
2344+ theorem Slice.Pos.le_trans {s : Slice} {p q r : s.Pos} : p ≤ q → q ≤ r → p ≤ r := by
2345+ simpa [Pos.le_iff, Pos.Raw.le_iff] using Nat.le_trans
2346+
2347+ /-- Given a position in `s` that is between `p₀` and `p₁`, obtain the corresponding position in
2348+ `s.slice p₀ p₁ h`. -/
2349+ @[inline]
2350+ def Slice.Pos.slice {s : Slice} (pos : s.Pos) (p₀ p₁ : s.Pos) (h₁ : p₀ ≤ pos) (h₂ : pos ≤ p₁) :
2351+ (s.slice p₀ p₁ (Slice.Pos.le_trans h₁ h₂)).Pos where
2352+ offset := pos.offset.unoffsetBy p₀.offset
2353+ isValidForSlice := (Pos.Raw.isValidForSlice_slice _).2
2354+ (by simp [Pos.Raw.offsetBy_unoffsetBy_of_le h₁, Slice.Pos.le_iff.1 h₂, pos.isValidForSlice])
2355+
2356+ /-- Given a position in `s` that is between `p₀` and `p₁`, obtain the corresponding position in
2357+ `s.slice p₀ p₁ h`. -/
2358+ @[inline]
2359+ def Pos.slice {s : String} (pos : s.Pos) (p₀ p₁ : s.Pos) (h₁ : p₀ ≤ pos) (h₂ : pos ≤ p₁) :
2360+ (s.slice p₀ p₁ (Pos.le_trans h₁ h₂)).Pos :=
2361+ Slice.Pos.slice pos.toSlice _ _ h₁ h₂
2362+
2363+ @[simp]
2364+ theorem Pos.offset_slice {s : String} {p₀ p₁ pos : s.Pos} {h₁ : p₀ ≤ pos} {h₂ : pos ≤ p₁} :
2365+ (pos.slice p₀ p₁ h₁ h₂).offset = pos.offset.unoffsetBy p₀.offset := (rfl)
2366+
2367+ /--
2368+ Given a position in `s`, obtain the corresponding position in `s.slice p₀ p₁ h`, or panic if `pos`
2369+ is not between `p₀` and `p₁`.
2370+ -/
2371+ @[inline]
2372+ def Slice.Pos.sliceOrPanic {s : Slice} (pos : s.Pos) (p₀ p₁ : s.Pos) {h} :
2373+ (s.slice p₀ p₁ h).Pos :=
2374+ if h : p₀ ≤ pos ∧ pos ≤ p₁ then
2375+ pos.slice p₀ p₁ h.1 h.2
2376+ else
2377+ panic! "Position is outside of the bounds of the slice."
2378+
2379+ /--
2380+ Given a position in `s`, obtain the corresponding position in `s.slice p₀ p₁ h`, or panic if `pos`
2381+ is not between `p₀` and `p₁`.
2382+ -/
2383+ @[inline]
2384+ def Pos.sliceOrPanic {s : String} (pos : s.Pos) (p₀ p₁ : s.Pos) {h} :
2385+ (s.slice p₀ p₁ h).Pos :=
2386+ Slice.Pos.sliceOrPanic pos.toSlice _ _
2387+
2388+ theorem Slice.slice_eq_slice! {s : Slice} {p₀ p₁ h} : s.slice p₀ p₁ h = s.slice! p₀ p₁ := by
2389+ simp [slice!, h]
2390+
2391+ theorem slice_eq_slice! {s : String} {p₀ p₁ h} : s.slice p₀ p₁ h = s.slice! p₀ p₁ := by
2392+ simp [slice!, slice, Slice.slice_eq_slice!]
2393+
2394+ /-- Given a position in `s.slice! p₀ p₁`, obtain the corresponding position in `s`, or panic if
2395+ taking `s.slice! p₀ p₁` already panicked. -/
2396+ @[inline]
2397+ def Slice.Pos.ofSlice! {s : Slice} {p₀ p₁ : s.Pos} (pos : (s.slice! p₀ p₁).Pos) : s.Pos :=
2398+ if h : p₀ ≤ p₁ then
2399+ ofSlice (h := h) (pos.cast slice_eq_slice!.symm)
2400+ else
2401+ panic! "Starting position must be less than or equal to end position."
2402+
2403+ /-- Given a position in `s.slice! p₀ p₁`, obtain the corresponding position in `s`, or panic if
2404+ taking `s.slice! p₀ p₁` already panicked. -/
2405+ @[inline]
2406+ def Pos.ofSlice! {s : String} {p₀ p₁ : s.Pos} (pos : (s.slice! p₀ p₁).Pos) : s.Pos :=
2407+ ofToSlice (Slice.Pos.ofSlice! pos)
2408+
2409+ /--
2410+ Given a position in `s`, obtain the corresponding position in `s.slice! p₀ p₁ h`, or panic if
2411+ taking `s.slice! p₀ p₁` already panicked or if the position is not between `p₀` and `p₁`.
2412+ -/
2413+ @[inline]
2414+ def Slice.Pos.slice! {s : Slice} (pos : s.Pos) (p₀ p₁ : s.Pos) :
2415+ (s.slice! p₀ p₁).Pos :=
2416+ if h : p₀ ≤ pos ∧ pos ≤ p₁ then
2417+ (pos.slice _ _ h.1 h.2 ).cast slice_eq_slice!
2418+ else
2419+ panic! "Starting position must be less than or equal to end position and position must be between starting position and end position."
2420+
2421+ /--
2422+ Given a position in `s`, obtain the corresponding position in `s.slice! p₀ p₁ h`, or panic if
2423+ taking `s.slice! p₀ p₁` already panicked or if the position is not between `p₀` and `p₁`.
2424+ -/
2425+ @[inline]
2426+ def Pos.slice! {s : String} (pos : s.Pos) (p₀ p₁ : s.Pos) :
2427+ (s.slice! p₀ p₁).Pos :=
2428+ Slice.Pos.slice! pos.toSlice _ _
2429+
23142430/--
23152431Advances the position `p` `n` times.
23162432
@@ -2346,7 +2462,7 @@ If this would move `p` past the end of `s`, the result is `s.endPos`.
23462462-/
23472463@[inline]
23482464def Pos.nextn {s : String} (p : s.Pos) (n : Nat) : s.Pos :=
2349- (p.toSlice.nextn n).ofSlice
2465+ ofToSlice (p.toSlice.nextn n)
23502466
23512467/--
23522468Iterates `p.prev` `n` times.
@@ -2355,7 +2471,7 @@ If this would move `p` past the start of `s`, the result is `s.startPos`.
23552471-/
23562472@[inline]
23572473def Pos.prevn {s : String} (p : s.Pos) (n : Nat) : s.Pos :=
2358- (p.toSlice.prevn n).ofSlice
2474+ ofToSlice (p.toSlice.prevn n)
23592475
23602476theorem Slice.Pos.le_nextn {s : Slice} {p : s.Pos} {n : Nat} : p ≤ p.nextn n := by
23612477 fun_induction nextn with
0 commit comments