Zulip Chat Archive
Stream: mathlib4
Topic: Porting Data.String.Basic
Richard Osborn (Dec 01 2022 at 01:55):
I had a quick look at Data.String.Basic, and it seems that Data.String.Defs was only partially ported. Is the plan to finish porting the missing definitions in that file? I have also noticed that Control.Monad.Writer was partially ported as Control.Writer. Should Control.Monad.Writer now import Control.Writer?
Scott Morrison (Dec 01 2022 at 02:02):
When Control.Monad.Writer
is fully ported, we should just delete Control.Writer
(I'm presuming there is no control.writer
in mathlib3).
Arien Malec (Dec 01 2022 at 02:05):
I suspect that a good chunk of Data.String.Basic
is going to be #align
d away to Std
Jakob von Raumer (Dec 05 2022 at 09:54):
I've started to work on Data.String.Basic
. There's the issue that the new implementation of Iterator
looks completely different under the hood and it seems harder to prove anything about it
Jakob von Raumer (Dec 05 2022 at 10:15):
Also, I'm not really sure why the file adds an additional instance of LT String
Jakob von Raumer (Dec 05 2022 at 11:35):
The same goes for properties of evyerthing that's built on top of String.extract
which now uses an external function and UTF8 byte indices. So to prove anything meaningful about these String operations would require a whole stack of helper lemmas
Mario Carneiro (Dec 05 2022 at 15:22):
Those helper lemmas sound like something to be added to std
Jakob von Raumer (Dec 05 2022 at 16:42):
The only place where the stuff in Data.String.Basic
is needed, is Data.Buffer.Parser.Basic
of which I'm not sure if it's well-portable either
Arien Malec (Dec 05 2022 at 21:37):
Scott Morrison said:
When
Control.Monad.Writer
is fully ported, we should just deleteControl.Writer
(I'm presuming there is nocontrol.writer
in mathlib3).
I'm looking at Control.Monad.Writer
-- do I want to move code from Control.Writer
here?
Arien Malec (Dec 05 2022 at 21:38):
i.e., as part of the single PR?
Scott Morrison (Dec 05 2022 at 23:34):
I think that would be fine.
Jakob von Raumer (Dec 15 2022 at 16:09):
Made a new PR for this: mathlib4#1054
Jakob von Raumer (Dec 15 2022 at 16:09):
Some stuff involving Iterator
, String.popn
and String.head
still missing
Arien Malec (Dec 15 2022 at 16:55):
This reminds me that I keep going back to the proofs in Control.Monad.Writer
and getting stuck.
Happy to unwind the PR here.
Jakob von Raumer (Dec 16 2022 at 09:45):
So the one thing I'm stuck at is to prove that Iterator.hasNext { s := { data := hd :: tl }, i := 0 }
holds
Bulhwi Cha (Mar 18 2023 at 03:20):
I'm trying to rewrite the proof of String.lt_iff_toList_lt
from the beginning, but I'm stuck on the following goal:
case cons.cons.inl
c₁ : Char
cs₁ : List Char
ih : ∀ (l₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := l₂ }, i := 0 } = true ↔ cs₁ < l₂
cs₂ : List Char
⊢ ltb { s := { data := c₁ :: cs₁ }, i := { byteIdx := csize c₁ } }
{ s := { data := c₁ :: cs₂ }, i := { byteIdx := csize c₁ } } =
ltb { s := { data := cs₁ }, i := 0 } { s := { data := cs₂ }, i := 0 }
The above goal is the tactic state of the sorry
in my proof:
String.lt_iff_toList_lt
Jakob von Raumer said:
The same goes for properties of evyerthing that's built on top of
String.extract
which now uses an external function and UTF8 byte indices. So to prove anything meaningful about these String operations would require a whole stack of helper lemmas
I don't know whether I should create a new git branch because I'm attempting not to use these helper lemmas to prove String.lt_iff_toList_lt
.
Bulhwi Cha (Mar 20 2023 at 11:52):
I've managed to prove String.lt_iff_toList_lt
. This theorem took me over 30 hours to prove. I'll soon push my commit to the git branch.
It's my first time porting a Mathlib file, and I think I picked the wrong one for a novice. :smiling_face_with_tear:
String.lt_iff_toList_lt
Eric Wieser (Mar 20 2023 at 15:40):
Why did you choose to rewrite it from scratch?
Bulhwi Cha (Mar 20 2023 at 22:02):
The previous proof didn't work, and its comment said, "TODO This proof probably has to be completely redone."
Bulhwi Cha (Mar 20 2023 at 22:15):
Jakob von Raumer said:
I've started to work on
Data.String.Basic
. There's the issue that the new implementation ofIterator
looks completely different under the hood and it seems harder to prove anything about it
I had to prove several new theorems and lemmas because the definition of String.Iterator
in Mathlib4 was different from that of Mathlib3.
Eric Wieser (Mar 20 2023 at 22:24):
docs4#String.Iterator, docs#string.iterator
Eric Wieser (Mar 20 2023 at 22:34):
Does it help to define String.Iterator.fst
as it.extract it.toEnd
and String.Iterator.snd
as it.string.iter.extract it
, and then use those two properties as before?
Bulhwi Cha (Mar 21 2023 at 01:01):
I'm not sure, but I assume it'll help only when you change the definition of String.Iterator
back into the Mathlib3 one.
Bulhwi Cha (Mar 21 2023 at 01:18):
Richard Osborn said:
I had a quick look at Data.String.Basic, and it seems that Data.String.Defs was only partially ported. Is the plan to finish porting the missing definitions in that file?
I'll port data.string.defs
before I push my commit to the port-data-string-basic-2
branch.
I first pushed my commits to the port-data-string-basic-2
branch, since porting data.string.defs
would take more time than I expected.
Bulhwi Cha (Mar 27 2023 at 14:07):
I think !4#1054 is now ready to merge. :smile:
Jakob von Raumer (Mar 30 2023 at 11:21):
That's really cool! I felt bad about letting it sit for so long
Bulhwi Cha (Apr 05 2023 at 13:47):
instance : LinearOrder String where
le_refl a := le_iff_toList_le.mpr le_rfl
le_trans a b c := by
simp only [le_iff_toList_le]
apply le_trans
lt_iff_le_not_le a b := by
simp only [le_iff_toList_le, lt_iff_toList_lt, lt_iff_le_not_le]
le_antisymm a b := by
simp only [le_iff_toList_le, ← toList_inj]
apply le_antisymm
le_total a b := by
simp only [le_iff_toList_le]
apply le_total
decidable_le := String.decidableLE
The above code has the following error, which didn't occur before. Can anyone tell me how to solve this goal?
unsolved goals
case mk.mk
data✝¹ data✝: List Char
⊢ compare { data := data✝¹ } { data := data✝ } = compareOfLessAndEq { data := data✝¹ } { data := data✝ }
GitHub PR discussion: https://github.com/leanprover-community/mathlib4/pull/1054#discussion_r1158533762
Ruben Van de Velde (Apr 05 2023 at 13:53):
Maybe related to !4#2858
Bulhwi Cha (Apr 05 2023 at 14:27):
Solution: add the line compare a b := compareOfLessAndEq a b
to the instance declaration.
Notification Bot (Apr 05 2023 at 14:28):
Jeremy Tan has marked this topic as resolved.
Eric Wieser (Apr 07 2023 at 07:42):
That's the wrong solution
Eric Wieser (Apr 07 2023 at 07:42):
It discards the optimized string comparison function and replaces it with the naive one
Yaël Dillies (Apr 07 2023 at 08:46):
@Jeremy Tan, please don't resolve topics you're not involved in.
Yaël Dillies (Apr 07 2023 at 08:46):
Or simply don't resolve topics. It's noisy and broken.
Eric Wieser (Apr 07 2023 at 10:18):
(re "broken": if you resolve a topic, anyone who shared a link to that topic will find that the link they shared no longer works)
Notification Bot (Apr 07 2023 at 11:16):
Jeremy Tan has marked this topic as unresolved.
Bulhwi Cha (Apr 07 2023 at 14:29):
Eric Wieser said:
It discards the optimized string comparison function and replaces it with the naive one
Hmm, I'm not sure what I should do to solve the error correctly. Can you help me?
Eric Wieser (Apr 07 2023 at 14:48):
You need to provide a manual compare_eq
field, I think
Eric Wieser (Apr 07 2023 at 14:48):
The error is coming from the default value for a proof field which no longer works; you need to provide that proof field explicitly, rather than replacing the data field with something that creates a diamond.
Eric Wieser (Apr 07 2023 at 14:49):
I'm afraid I don't know the name of the field; does the error message not tell you?
Bulhwi Cha (Apr 07 2023 at 15:01):
Eric Wieser said:
I'm afraid I don't know the name of the field; does the error message not tell you?
No, I don't think it does:
unsolved goals
case mk.mk
data✝¹ data✝: List Char
⊢ compare { data := data✝¹ } { data := data✝ } = compareOfLessAndEq { data := data✝¹ } { data := data✝ }
Is the field you mentioned compare_eq_compareOfLessAndEq
?
Ruben Van de Velde (Apr 07 2023 at 15:03):
instance : LinearOrder String where
le_refl a := le_iff_toList_le.mpr le_rfl
le_trans a b c := by
simp only [le_iff_toList_le]
apply le_trans
lt_iff_le_not_le a b := by
simp only [le_iff_toList_le, lt_iff_toList_lt, lt_iff_le_not_le]
le_antisymm a b := by
simp only [le_iff_toList_le, ← toList_inj]
apply le_antisymm
le_total a b := by
simp only [le_iff_toList_le]
apply le_total
decidable_le := String.decidableLE
compare_eq_compareOfLessAndEq := sorry
Bulhwi Cha (Apr 07 2023 at 15:41):
Eric Wieser said:
The error is coming from the default value for a proof field which no longer works; you need to provide that proof field explicitly, rather than replacing the data field with something that creates a diamond.
Right now, I'm clueless about how to prove compare_eq_compareOfLessAndEq
. I'll try it again later.
Ruben Van de Velde (Apr 07 2023 at 15:44):
I'm confused - the PR seems to be closed already?
Bulhwi Cha (Apr 07 2023 at 15:47):
Yes. :worried:
Bulhwi Cha (Apr 07 2023 at 16:47):
Eric Wieser said:
It discards the optimized string comparison function and replaces it with the naive one
Can you elaborate on "the optimized string comparison function"?
Bulhwi Cha (Apr 07 2023 at 16:49):
Here is my attempt to prove compare_eq_compareOfLessAndEq
:
import Mathlib.Data.String.Basic
namespace String
instance : LinearOrder String where
le_refl a := le_iff_toList_le.mpr le_rfl
le_trans a b c := by
simp only [le_iff_toList_le]
apply le_trans
lt_iff_le_not_le a b := by
simp only [le_iff_toList_le, lt_iff_toList_lt, lt_iff_le_not_le]
le_antisymm a b := by
simp only [le_iff_toList_le, ← toList_inj]
apply le_antisymm
le_total a b := by
simp only [le_iff_toList_le]
apply le_total
decidable_le := String.decidableLE
compare_eq_compareOfLessAndEq a b := by
simp [compare, compareOfLessAndEq]
split_ifs <;>
rw [← lt_iff_toList_lt] at * <;>
sorry
end String
Ruben Van de Velde (Apr 07 2023 at 16:52):
So where is the code that doesn't work? Or can you make a #mwe including imports?
Bulhwi Cha (Apr 07 2023 at 16:55):
I edited the above message.
Bulhwi Cha (Apr 07 2023 at 17:03):
Data.String.Basic
has the instance String.LT'
, which overrides the default instance of LT String
.
Bulhwi Cha (Apr 07 2023 at 17:12):
So, how do you close the following goal?
a b : String
h1: @LT.lt String instLTString a b
h2: ¬ @LT.lt String LT' a b
h3: ¬ a = b
⊢ False
Bulhwi Cha (Apr 07 2023 at 17:17):
Bulhwi Cha said:
Solution: add the line
compare a b := compareOfLessAndEq a b
to the instance declaration.
I don't know. Perhaps my naive solution isn't wrong?
Eric Wieser (Apr 07 2023 at 18:02):
It is wrong, because there is already a docs4#instOrdString and your fix creates a second instance that is not defeq
Bulhwi Cha (Apr 07 2023 at 18:04):
"404 Not Found"
Eric Wieser (Apr 07 2023 at 18:04):
The sorry
you're stuck on is proving that the instance you wanted to provide is defeq to the existing one. The proof is probably not completely trivial.
Eric Wieser (Apr 07 2023 at 18:06):
Although now I'm questioning whether it's actually not already defeq
Eric Wieser (Apr 07 2023 at 18:07):
Although now I'm questioning whether it's actually not already defeq
Eric Wieser (Apr 07 2023 at 18:07):
@thorimur can probably advise here, I'm not at lean so can't really help.
Bulhwi Cha (Apr 07 2023 at 18:12):
This might be relevant: https://github.com/leanprover-community/mathlib4/blob/a897757abcb0bffa1dc96f46017f1d65e0fd1f9b/Mathlib/Data/List/Lex.lean#L178-L181
It's 3:12 a.m. here in KR, so I'll get into bed now. :in_bed:
Eric Wieser (Apr 07 2023 at 18:22):
I don't think it's urgent to fix this
Eric Wieser (Apr 07 2023 at 18:23):
Feel free to open an issue, assign it to me/ thorimur, and abandon it entirely if you're not that interested in this.
Bulhwi Cha (Apr 08 2023 at 10:52):
import Mathlib.Data.String.Basic
open String
theorem List.lt_iff_lex_char_lt (l l' : List Char) : List.lt l l' ↔ List.Lex Char.lt l l' := by
constructor
· intro h
induction h with
| nil b bs => exact Lex.nil
| @head a as b bs hab => apply Lex.rel; assumption
| @tail a as b bs hab hba _ ih =>
have heq : a = b := _root_.le_antisymm (le_of_not_lt hba) (le_of_not_lt hab)
subst b; apply Lex.cons; assumption
· intro h
induction h with
| @nil a as => apply List.lt.nil
| @cons a as bs _ ih => apply List.lt.tail <;> simp [ih]
| @rel a as b bs h => apply List.lt.head; assumption
namespace String
instance : LinearOrder String where
le_refl a := le_iff_toList_le.mpr le_rfl
le_trans a b c := by
simp only [le_iff_toList_le]
apply le_trans
lt_iff_le_not_le a b := by
simp only [le_iff_toList_le, lt_iff_toList_lt, lt_iff_le_not_le]
le_antisymm a b := by
simp only [le_iff_toList_le, ← toList_inj]
apply le_antisymm
le_total a b := by
simp only [le_iff_toList_le]
apply le_total
decidable_le := String.decidableLE
compare_eq_compareOfLessAndEq a b := by
simp [compare, compareOfLessAndEq, toList, instLTString, List.instLTList, List.LT']
split_ifs <;>
simp [List.lt_iff_lex_char_lt] at * <;>
contradiction
end String
Eric Wieser said:
The
sorry
you're stuck on is proving that the instance you wanted to provide is defeq to the existing one. The proof is probably not completely trivial.
It took me over an hour to prove compare_eq_compareOfLessAndEq
. Thank you so much for your guidance!
Bulhwi Cha (Apr 08 2023 at 11:47):
GitHub PR: !4#3339
Alex J. Best (Apr 08 2023 at 15:32):
Eric Wieser said:
(re "broken": if you resolve a topic, anyone who shared a link to that topic will find that the link they shared no longer works)
Is that still true? I thought zulip fixed that long ago https://github.com/zulip/zulip/issues/19651. If not we should report it of course
Last updated: Dec 20 2023 at 11:08 UTC