Skip to content

Commit 9f41f33

Browse files
authored
fix: make Substring.beq reflexive (#10552)
This PR ensures that `Substring.beq` is reflexive, and in particular satisfies the equivalence `ss1 == ss2 <-> ss1.toString = ss2.toString`. Closes #10511. Note: I also fixed a strange line in the `String.extract` documentation which looks like it may have been a copypasta, and added another example to show how invalid UTF8 positions work, but the doc also makes a point of saying that it is unspecified so maybe it would be better not to have the example? 🤷
1 parent 0550609 commit 9f41f33

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

src/Init/Data/String/Basic.lean

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2343,7 +2343,8 @@ Examples:
23432343
* `"red green blue".extract ⟨3⟩ ⟨0⟩ = ""`
23442344
* `"red green blue".extract ⟨0⟩ ⟨100⟩ = "red green blue"`
23452345
* `"red green blue".extract ⟨4⟩ ⟨100⟩ = "green blue"`
2346-
* `"L∃∀N".extract ⟨2⟩ ⟨100⟩ = "green blue"`
2346+
* `"L∃∀N".extract ⟨1⟩ ⟨2⟩ = "∃∀N"`
2347+
* `"L∃∀N".extract ⟨2⟩ ⟨100⟩ = ""`
23472348
-/
23482349
@[extern "lean_string_utf8_extract", expose]
23492350
def extract : (@& String) → (@& Pos) → (@& Pos) → String
@@ -3410,13 +3411,23 @@ def toNat? (s : Substring) : Option Nat :=
34103411
else
34113412
none
34123413

3414+
/--
3415+
Given a `Substring`, returns another one which has valid endpoints
3416+
and represents the same substring according to `Substring.toString`.
3417+
(Note, the substring may still be inverted, i.e. beginning greater than end.)
3418+
-/
3419+
def repair : Substring → Substring
3420+
| ⟨s, b, e⟩ => ⟨s, if b.isValid s then b else s.endPos, if e.isValid s then e else s.endPos⟩
3421+
34133422
/--
34143423
Checks whether two substrings represent equal strings. Usually accessed via the `==` operator.
34153424
34163425
Two substrings do not need to have the same underlying string or the same start and end positions;
34173426
instead, they are equal if they contain the same sequence of characters.
34183427
-/
34193428
def beq (ss1 ss2 : Substring) : Bool :=
3429+
let ss1 := ss1.repair
3430+
let ss2 := ss2.repair
34203431
ss1.bsize == ss2.bsize && ss1.str.substrEq ss1.startPos ss2.str ss2.startPos ss1.bsize
34213432

34223433
@[export lean_substring_beq]

0 commit comments

Comments
 (0)