Skip to content

Commit f564598

Browse files
committed
fix: correct String.instLinearOrderString (#3339)
Use the optimized `compare` function and provide a manual `compare_eq_compareOfLessAndEq` field.
1 parent 536275b commit f564598

File tree

1 file changed

+28
-5
lines changed

1 file changed

+28
-5
lines changed

Mathlib/Data/String/Basic.lean

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ open private utf8GetAux from Init.Data.String.Basic
5353

5454
private lemma utf8GetAux.add_right_cancel (i p n : ℕ) (s : List Char) :
5555
utf8GetAux s ⟨i + n⟩ ⟨p + n⟩ = utf8GetAux s ⟨i⟩ ⟨p⟩ := by
56-
apply utf8GetAux.inductionOn s ⟨i⟩ ⟨p⟩ (motive := fun s i p ↦
56+
apply inductionOn s ⟨i⟩ ⟨p⟩ (motive := fun s i p ↦
5757
utf8GetAux s ⟨i.byteIdx + n⟩ ⟨p.byteIdx + n⟩ = utf8GetAux s i p) <;>
5858
simp [utf8GetAux]
5959
· intro c cs ⟨i⟩ ⟨p⟩ h
@@ -120,7 +120,7 @@ def ltb.inductionOn.{u} {motive : Iterator → Iterator → Sort u} (it₁ it₂
120120
lemma ltb.cons_add_csize (c : Char) (cs₁ cs₂ : List Char) (i₁ i₂ : ℕ) :
121121
ltb ⟨⟨c :: cs₁⟩, ⟨i₁ + csize c⟩⟩ ⟨⟨c :: cs₂⟩, ⟨i₂ + csize c⟩⟩ =
122122
ltb ⟨⟨cs₁⟩, ⟨i₁⟩⟩ ⟨⟨cs₂⟩, ⟨i₂⟩⟩ := by
123-
apply ltb.inductionOn ⟨⟨cs₁⟩, ⟨i₁⟩⟩ ⟨⟨cs₂⟩, ⟨i₂⟩⟩ (motive := fun ⟨⟨cs₁⟩, ⟨i₁⟩⟩ ⟨⟨cs₂⟩, ⟨i₂⟩⟩ ↦
123+
apply inductionOn ⟨⟨cs₁⟩, ⟨i₁⟩⟩ ⟨⟨cs₂⟩, ⟨i₂⟩⟩ (motive := fun ⟨⟨cs₁⟩, ⟨i₁⟩⟩ ⟨⟨cs₂⟩, ⟨i₂⟩⟩ ↦
124124
ltb ⟨⟨c :: cs₁⟩, ⟨i₁ + csize c⟩⟩ ⟨⟨c :: cs₂⟩, ⟨i₂ + csize c⟩⟩ =
125125
ltb ⟨⟨cs₁⟩, ⟨i₁⟩⟩ ⟨⟨cs₂⟩, ⟨i₂⟩⟩) <;> simp <;>
126126
intro ⟨cs₁⟩ ⟨cs₂⟩ ⟨i₁⟩ ⟨i₂⟩ <;>
@@ -226,6 +226,25 @@ theorem popn_empty {n : ℕ} : "".popn n = "" := by
226226
simp [popn]
227227
#align string.popn_empty String.popn_empty
228228

229+
end String
230+
231+
theorem List.lt_iff_lex_lt [LinearOrder α] (l l' : List α) :
232+
lt l l' ↔ Lex (· < ·) l l' := by
233+
constructor <;>
234+
intro h
235+
· induction h with
236+
| nil b bs => exact Lex.nil
237+
| @head a as b bs hab => apply Lex.rel; assumption
238+
| @tail a as b bs hab hba _ ih =>
239+
have heq : a = b := _root_.le_antisymm (le_of_not_lt hba) (le_of_not_lt hab)
240+
subst b; apply Lex.cons; assumption
241+
· induction h with
242+
| @nil a as => apply lt.nil
243+
| @cons a as bs _ ih => apply lt.tail <;> simp [ih]
244+
| @rel a as b bs h => apply lt.head; assumption
245+
246+
namespace String
247+
229248
instance : LinearOrder String where
230249
le_refl a := le_iff_toList_le.mpr le_rfl
231250
le_trans a b c := by
@@ -240,7 +259,11 @@ instance : LinearOrder String where
240259
simp only [le_iff_toList_le]
241260
apply le_total
242261
decidable_le := String.decidableLE
243-
compare a b := compareOfLessAndEq a b
262+
compare_eq_compareOfLessAndEq a b := by
263+
simp [compare, compareOfLessAndEq, toList, instLTString, List.instLTList, List.LT']
264+
split_ifs <;>
265+
simp [List.lt_iff_lex_lt] at * <;>
266+
contradiction
244267

245268
end String
246269

@@ -257,7 +280,7 @@ theorem List.length_asString (l : List Char) : l.asString.length = l.length :=
257280

258281
@[simp]
259282
theorem List.asString_inj {l l' : List Char} : l.asString = l'.asString ↔ l = l' :=
260-
fun h ↦ by rw [← List.toList_inv_asString l, ← List.toList_inv_asString l', toList_inj, h],
283+
fun h ↦ by rw [← toList_inv_asString l, ← toList_inv_asString l', toList_inj, h],
261284
fun h ↦ h ▸ rfl⟩
262285
#align list.as_string_inj List.asString_inj
263286

@@ -267,5 +290,5 @@ theorem String.length_toList (s : String) : s.toList.length = s.length := by
267290
#align string.length_to_list String.length_toList
268291

269292
theorem List.asString_eq {l : List Char} {s : String} : l.asString = s ↔ l = s.toList := by
270-
rw [← asString_inv_toList s, List.asString_inj, asString_inv_toList s]
293+
rw [← asString_inv_toList s, asString_inj, asString_inv_toList s]
271294
#align list.as_string_eq List.asString_eq

0 commit comments

Comments
 (0)