Zulip Chat Archive
Stream: mathlib4
Topic: Data.List.Basic
Scott Morrison (Dec 17 2022 at 09:17):
This thread can serve to coordinate work on Data.List.Basic. Please write here if you would like to claim a section of it to work on (and then "unclaim" when you finish work).
Johan Commelin (Dec 17 2022 at 10:07):
I just pushed the mathlib 3 source header
Siddhartha Gadgil (Dec 17 2022 at 10:08):
Trying reverseRecOn
Johan Commelin (Dec 17 2022 at 10:11):
Fixed line 1036
Johan Commelin (Dec 17 2022 at 10:11):
I'll claim 1037 -- 1105
Siddhartha Gadgil (Dec 17 2022 at 10:16):
Siddhartha Gadgil said:
Trying
reverseRecOn
done and pushed
Johan Commelin (Dec 17 2022 at 10:18):
I'm working on bidirectionalRec
Johan Commelin (Dec 17 2022 at 10:29):
done
Johan Commelin (Dec 17 2022 at 10:32):
From std:
/- @[refl] -/ @[simp] theorem Sublist.refl : ∀ l : List α, l <+ l
| [] => .slnil
| a :: l => (Sublist.refl l).cons₂ a
@Mario Carneiro I guess this commented-out @[refl]
is intentional? It breaks a proof in Data.List.Basic
.
Mario Carneiro (Dec 17 2022 at 10:33):
It wasn't legal at the time, in fact it probably still isn't because the refl attribute is in mathlib
Mario Carneiro (Dec 17 2022 at 10:33):
You can add the refl attribute in the corresponding mathlib file
Johan Commelin (Dec 17 2022 at 10:34):
I guess that file is Data.List.Basic
?
Johan Commelin (Dec 17 2022 at 10:40):
I had to manually replace sublist.cons2
with Sublist.cons₂
. Is that something that mathport ought to do?
(This was in the instance decidableSublist
.)
Johan Commelin (Dec 17 2022 at 10:44):
I did a global replace index_of
-> indexOf
.
Johan Commelin (Dec 17 2022 at 10:44):
Oops! That messed up #align
statements. Will fix.
Johan Commelin (Dec 17 2022 at 10:47):
Pushed a better replace
Scott Morrison (Dec 17 2022 at 10:47):
I think we need to add an #align for sublist.cons2. (Because it is defined in Std.)
Siddhartha Gadgil (Dec 17 2022 at 10:57):
Done map_take
. In general I am working from the end and trying termination errors.
Siddhartha Gadgil (Dec 17 2022 at 11:07):
globally replacing erasep
with eraseP
Siddhartha Gadgil (Dec 17 2022 at 11:09):
Sorry that was a mistake which I undid. The first terms of align
should ha erasep
Siddhartha Gadgil (Dec 17 2022 at 11:10):
That said a lot of fixes are this replacement and finding that stuff is already in Std
Mario Carneiro (Dec 17 2022 at 11:38):
I recall doing at least one pass over data.list.basic and porting everything I could to std, so I would expect there to be a lot of #align-only code here
Siddhartha Gadgil (Dec 17 2022 at 12:13):
Yes, most of the work is correcting cases, finding stuff is then in Std
and keeping only the align.
I am also adding attributes where things are marked [simp]
. Is that correct? Some seemed not to be simp in Std
Johan Commelin (Dec 17 2022 at 14:45):
theorem indexOf_cons (a b : α) (l : List α) :
indexOf a (b :: l) = if a = b then 0 else succ (indexOf a l) :=
this used to be rfl
but it no longer is.
Is that a problem?
Mario Carneiro (Dec 17 2022 at 14:48):
let's assume not until proven otherwise
Kevin Buzzard (Dec 17 2022 at 20:50):
In the Data.Fin.Basic thread we see that 0 % b = 0
used to be rfl
and no longer is, and all that happens is that a bunch of proofs break and have to be fixed manually. Does that count as a problem?
Mario Carneiro (Dec 17 2022 at 20:53):
that one is going to be more annoying (it's not that 0 % b = 0
was rfl but rather that the definition of 0 : Fin n
changed from 0
to 0 % n
), but I don't see much of an option without making fin have two different OfNat
instances, which is also a headache
Thomas Murrills (Dec 17 2022 at 23:01):
Cleaning up lines 1300 - 1500 right now (mostly good, a few spread-out errors)
Thomas Murrills (Dec 18 2022 at 00:41):
Moving onto 1500 - 1600
Thomas Murrills (Dec 18 2022 at 00:58):
Do we rename or delete ext
? There's already List.ext
from Std
, but that one uses get?
and this one uses nth
Thomas Murrills (Dec 18 2022 at 01:00):
The get?
version seems to make the subsequent theorems throw errors
Thomas Murrills (Dec 18 2022 at 01:14):
I've temporarily renamed it ext_nth
in keeping with ext_le
below it.
Mario Carneiro (Dec 18 2022 at 01:35):
is get?
different from nth
?
Mario Carneiro (Dec 18 2022 at 01:44):
List.nth
is identical to List.get?
. It should be deleted and #align
ed
Mario Carneiro (Dec 18 2022 at 01:53):
other definitions in Mathlib.Init.Data.List.Basic that are duplicates:
List.map₂
->List.zipWith
List.mapWithIndex
->List.mapIdx
List.findIndex
->List.findIdxₓ
(prop -> bool)List.updateNth
->List.set
List.bor
->List.or
List.band
->List.and
List.repeat
->List.replicateₓ
(argument order)List.init
->List.dropLast
Thomas Murrills (Dec 18 2022 at 02:24):
A lot (100+) of theorems use nth
somewhere in their name; is it better to use nth
as an alias for get?
or to ctrl+F and change all of the theorem names to reference get
? (Likewise for the other ones with significantly different names which might be referenced in theorems, I guess, but it's probably not as big a deal)
Thomas Murrills (Dec 18 2022 at 02:35):
Fixing errors in indexOf
section (~1250 -1300)
Mario Carneiro (Dec 18 2022 at 03:26):
mathport is the new ctrl-F
Thomas Murrills (Dec 18 2022 at 03:39):
the theorems I'm talking about are all in Data.List.Basic
already, not future files
Thomas Murrills (Dec 18 2022 at 03:48):
also I'm just asking a stylistic question, not saying it's difficult...like, do we want lots of theorem names to have _get?_
in the middle? or do we want to use nth
in those names by having an alias
Thomas Murrills (Dec 18 2022 at 06:27):
Ok, ported the indexOf
section—as mentioned, the previous proofs were very short (e.g. rfl), whereas these new ones require diving into findIdx.go
. I reordered a couple so I could use them as components. I tried to keep them more elementary than fancy, e.g. "string of rewrites" instead of simp
—hopefully they can be golfed nonetheless, though. But in the meantime, they work! :)
Scott Morrison (Dec 18 2022 at 09:57):
Ideally there are no more nth
s at all. We're replacing it with get?
.
Thomas Murrills (Dec 18 2022 at 18:42):
Cleaning up nth_injective
and indexOf_cons_ne
Johan Commelin (Dec 19 2022 at 20:38):
I pushed a tiny bit more progress
Chris Hughes (Dec 19 2022 at 21:42):
Scott Morrison said:
Ideally there are no more
nth
s at all. We're replacing it withget?
.
I'm not entirely sure about this decision. Maybe leave the nthLe
s there for now and tidy stuff up after mathlib is ported. It's easier to fix all in one go and minimize design changes while porting?
Scott Morrison (Dec 19 2022 at 21:48):
Sorry, ignore me, that was an completely stupid thing for me to say. Of course we're not changing nth
to get?
.
Scott Morrison (Dec 19 2022 at 21:48):
I thought this was just a rename. :shrug:
Mario Carneiro (Dec 19 2022 at 22:01):
but it is a rename?
Mario Carneiro (Dec 19 2022 at 22:01):
nth
is gone, long live get?
. nthLe
is still around though
Mario Carneiro (Dec 19 2022 at 22:03):
also to address @Thomas Murrills 's naming question re: get?
in the middle of theorem names: yes, it's just treated like any other name. You get names like get?_of_nthLe
and so on
Thomas Murrills (Dec 19 2022 at 22:13):
If we switch every nth
to get?
, why would we not also switch nthLe
to get?Le
? isn’t nthLe
meant to conjure up nth
? And if there is no nth
…
Mario Carneiro (Dec 19 2022 at 22:24):
there isn't an le
in nthLe
either, it's a bad name
Mario Carneiro (Dec 19 2022 at 22:25):
(I think I named it, but I don't know what I was thinking)
Mario Carneiro (Dec 19 2022 at 22:25):
but until we're ready to rename it it should just stay as is
Thomas Murrills (Dec 19 2022 at 22:57):
i'll take'
on the section Take'
(~ 2540 - 2570) right now
Eric Wieser (Dec 19 2022 at 23:04):
Isn't docs#list.nth_le ultimately obsolete in favor of docs4#List.get, but we're delaying the refactor till after the port?
Chris Hughes (Dec 19 2022 at 23:04):
I vote yes
Eric Wieser (Dec 19 2022 at 23:04):
(unless someone wants to backport it to mathlib3 first, but it doesn't seem very important)
Mario Carneiro (Dec 19 2022 at 23:16):
there are some advantages to having them be separate arguments for induction proofs, but it can probably be marginalized to just some specialized situations
Thomas Murrills (Dec 19 2022 at 23:28):
if it won't be used much but is still useful occasionally, get'
? or getLT
?
Thomas Murrills (Dec 19 2022 at 23:36):
also I'm noticing that take'
doesn't actually match with takeD
—the new takeD
allows any element to be specified as a default, whereas take
required [Inhabited α]
. should we:
- correspondingly generalize the theorems by adding that explicit value as an (implicit?) argument to the theorems in
take
- just use
default
and maintain that these theorems require[Inhabited α]
Thomas Murrills (Dec 19 2022 at 23:39):
std
seems to have chosen the first option when it absorbed take'_nil
as takeD_nil
, so I'll do that as well if there aren't any objections.
Thomas Murrills (Dec 19 2022 at 23:43):
Hmm...in general, in cases like this, is it worth putting porting note:
s in /-- ... -/
docstrings so that people who are porting can see that we've e.g. changed the arguments required on mouseover?
Thomas Murrills (Dec 20 2022 at 00:01):
done (without docstrings) (I'll change it back to using [Inhabited α]
if I made the wrong choice)
Mario Carneiro (Dec 20 2022 at 00:01):
The inhabited-taking version should be named takeI
Thomas Murrills (Dec 20 2022 at 00:01):
Do we want to use that instead? Or have both? Currently take'
is aligned with takeD
. Is that a mistake?
Thomas Murrills (Dec 20 2022 at 00:05):
or wait. takeI
doesn't exist yet—you're talking about in the future
Mario Carneiro (Dec 20 2022 at 00:06):
What is the type of take'
?
Thomas Murrills (Dec 20 2022 at 00:09):
Π {α : Type u} [_inst_1 : inhabited α], ℕ → list α → list α
Mario Carneiro (Dec 20 2022 at 00:11):
then it should be renamed to takeI
Mario Carneiro (Dec 20 2022 at 00:11):
and not aligned to takeD
which is a different function
Thomas Murrills (Dec 20 2022 at 00:27):
Alright, that align is in Data.List.Defs
(and the definition of take'
was there too). So...I'll make a PR on a separate branch to fix Data.List.Defs
and define takeI
there?
Thomas Murrills (Dec 20 2022 at 00:28):
Hang on. Mathlib.Data.List.Defs
currently depends on Mathlib.Data.List.Basic
?? Not the other way around?
Thomas Murrills (Dec 20 2022 at 00:33):
I suppose I'll define takeI
in Data.List.Basic
until I figure out what's going on.
Mario Carneiro (Dec 20 2022 at 00:33):
That import is definitely an error
Mario Carneiro (Dec 20 2022 at 00:34):
the import of Data.List.Chain
seems to be the issue
Mario Carneiro (Dec 20 2022 at 00:35):
don't work around an ad hoc port issue by adding more ad hoc port issues
Mario Carneiro (Dec 20 2022 at 00:35):
when in doubt, copy the structure of mathlib3
Thomas Murrills (Dec 20 2022 at 00:43):
the import of Data.List.Chain seems to be the issue
and in turn Data.List.Pairwise
which imports Data.List.Basic
directly
Thomas Murrills (Dec 20 2022 at 00:58):
Ok, here's the current state of things.
Thomas Murrills (Dec 20 2022 at 00:59):
Data.List.Defs
has a Chain
section where it defines decidableChain
, decidableChain'
. This needs chain_cons
and is the only reason Data.List.Chain
is imported.
Thomas Murrills (Dec 20 2022 at 01:00):
However, things were different in mathlib3: chain_cons
was defined in data.list.defs
, not data.list.chain
.
Thomas Murrills (Dec 20 2022 at 01:02):
As far as I can tell, data.list.defs
did not depend on data.list.chain
in mathlib3. This is a new dependency introduced in mathlib4.
Thomas Murrills (Dec 20 2022 at 01:08):
In fact, I think it was the other way around: data.list.chain
depended on data.list.defs
.
Mario Carneiro (Dec 20 2022 at 01:24):
Mario Carneiro said:
when in doubt, copy the structure of mathlib3
Mario Carneiro (Dec 20 2022 at 01:25):
Move everything where it is supposed to be and everything will be resolved
Thomas Murrills (Dec 20 2022 at 02:56):
Alright, I'll try my best—the imports are totally different for lots of things in mathlib3, it's not just that one file. (For example, seems like old data.list.basic
depended on data.list.defs
but doesn't anymore, so that'll be a new import in Data.List.Basic
.)
Arien Malec (Dec 20 2022 at 03:31):
The definition of take'
(through mathlib3port
was
def take' : ∀ n, List α → List α
| 0, l => []
| n + 1, l => l.head :: take' n l.tail
The misalignment was my mistake based on an assumption that D
= Default
(although I got the naming convention right elsewhere)
The import of Data.List.Chain
was required to port the defs for the Chain
section -- as noted, moving that whole section to Data.List.Chain
will remove the dependency (but will also be a divergence from mathlib3)./
Thomas Murrills (Dec 20 2022 at 03:33):
I did the reverse: move chain_cons
to Data.List.Defs. This is how it was in mathlib3
Thomas Murrills (Dec 20 2022 at 03:33):
Thomas Murrills (Dec 20 2022 at 03:34):
All other chain definitions previously in data.list.defs are now in std, so it was the only one that needed to be moved :)
Thomas Murrills (Dec 20 2022 at 03:44):
Still trying to make it build, though. Is there some reason the dependency needs to flow from Data.List.Chain
-> Data.List.Defs
now?
Arien Malec (Dec 20 2022 at 03:47):
No idea... Data.List.Chain
existed before the port of Data.List.Defs
Arien Malec (Dec 20 2022 at 03:49):
Fortunately, the only reference to takeD
is in Data.List.Defs
so removing the align and adding takeI
should be fine.
Arien Malec (Dec 20 2022 at 03:50):
I think it would be better to define takeI
as:
def takeI : ∀ n, List α → List α
List.takeD default
Thomas Murrills (Dec 20 2022 at 04:11):
I think we're on the same page—I defined it in the PR as
def takeI [Inhabited α] (n : Nat) (l : List α) : List α :=
takeD n l default
Thomas Murrills (Dec 20 2022 at 05:32):
Ok, neat; mathlib4#1118 is good to go, and should fix things.
Thomas Murrills (Dec 20 2022 at 06:53):
it worked :) now fixing 2600 - 2620
Thomas Murrills (Dec 20 2022 at 07:45):
Did foldrRecOn
etc.; had to work around the code generator not handling List.rec
for now. I'll double-check the IH
's I manually gave tomorrow; it's late :)
Johan Commelin (Dec 20 2022 at 08:54):
List.mem_cons
is in Std. What is the canonical place to add #align list.mem_cons_iff List.mem_cons
?
Johan Commelin (Dec 20 2022 at 08:56):
The first error in Data.List.Basic is on
theorem nthLe_insertNth_self (l : List α) (x : α) (n : ℕ) (hn : n ≤ l.length)
(hn' : n < (insertNth n x l).length := by rwa [length_insertNth _ _ hn, Nat.lt_succ_iff]) :
with error message
invalid auto tactic, identifier is not allowed
on the length_insertNth
Johan Commelin (Dec 20 2022 at 08:56):
How should we do these auto tactics?
Johan Commelin (Dec 20 2022 at 09:14):
Johan Commelin said:
List.mem_cons
is in Std. What is the canonical place to add#align list.mem_cons_iff List.mem_cons
?
I see, it is already on L21. But it hasn't been used in the rest of the file yet.
Mario Carneiro (Dec 20 2022 at 11:01):
Johan Commelin said:
List.mem_cons
is in Std. What is the canonical place to add#align list.mem_cons_iff List.mem_cons
?
The canonical place to put an #align
is in the same place and ordering as the original mathlib3 definition, regardless of whether the lean 4 definition is in mathlib4 or upstream. If the definition is in mathlib4, it should come immediately before the #align
unless there is a reason it has to be moved elsewhere
Mario Carneiro (Dec 20 2022 at 11:03):
Johan Commelin said:
The first error in Data.List.Basic is on
theorem nthLe_insertNth_self (l : List α) (x : α) (n : ℕ) (hn : n ≤ l.length) (hn' : n < (insertNth n x l).length := by rwa [length_insertNth _ _ hn, Nat.lt_succ_iff]) :
with error message
invalid auto tactic, identifier is not allowed
on the
length_insertNth
How did that happen? Mathport will not generate autoparams like that
Johan Commelin (Dec 20 2022 at 11:13):
No idea... but that's the code I found on the branch
Johan Commelin (Dec 20 2022 at 12:26):
Mario Carneiro said:
The canonical place to put an
#align
is in the same place and ordering as the original mathlib3 definition, regardless of whether the lean 4 definition is in mathlib4 or upstream. If the definition is in mathlib4, it should come immediately before the#align
unless there is a reason it has to be moved elsewhere
But somehow a lot of #align
s are missing, when the definitions ended up in Std.
Johan Commelin (Dec 20 2022 at 12:27):
I think Data.List.Basic is quite a mess. E.g., apparently those autoparams are also garbage that shouldn't roll out of mathport.
Johan Commelin (Dec 20 2022 at 12:27):
And because of all the missing #align
s there are many names that need tweaking and fixing.
Johan Commelin (Dec 20 2022 at 12:28):
@Mario Carneiro Do you think you could take a look? And maybe use some oneshot magic trickery to get this file to behave?
Johan Commelin (Dec 20 2022 at 12:28):
Roughly 2900 lines are now error free. But there's another 2400 lines in that file.
Mario Carneiro (Dec 20 2022 at 12:29):
Was the port botched in some way? Do we need to start over from mathport output?
Johan Commelin (Dec 20 2022 at 12:29):
I dunno. Throwing away 3000 lines of porting effort also feels sad.
Mario Carneiro (Dec 20 2022 at 12:29):
well it's fine if they are good code, I'm not sure exactly what the problem is here
Mario Carneiro (Dec 20 2022 at 12:30):
I'll take a look, data.rat.order needs a review
Mario Carneiro (Dec 20 2022 at 13:40):
For anyone else who is working on this file: I'm currently doing major brain surgery on it, you might want to wait until afterwards and hopefully you already committed any changes you had
Mario Carneiro (Dec 20 2022 at 14:34):
Mario Carneiro said:
Johan Commelin said:
The first error in Data.List.Basic is on
theorem nthLe_insertNth_self (l : List α) (x : α) (n : ℕ) (hn : n ≤ l.length) (hn' : n < (insertNth n x l).length := by rwa [length_insertNth _ _ hn, Nat.lt_succ_iff]) :
with error message
invalid auto tactic, identifier is not allowed
on the
length_insertNth
How did that happen? Mathport will not generate autoparams like that
I ran across this issue while going over mathport's data.list.basic output again. I see what happened now: in lean 3 the proof looked like this:
@[simp] lemma nth_le_insert_nth_self (l : list α) (x : α) (n : ℕ)
(hn : n ≤ l.length) (hn' : n < (insert_nth n x l).length :=
by rwa [length_insert_nth _ _ hn, nat.lt_succ_iff]) :
(insert_nth n x l).nth_le n hn' = x :=
That is, there is an opt param whose value is given by a by
block. In lean 4 this syntax (that is, (x : ty := by tac)
has been reappropriated for auto params (in which := by
is a composite keyword), and if you want an opt param whose value is a by block you have to write (x : ty := (by tac))
instead. Pinging @Sebastian Ullrich since this is another parenthesizer bug that isn't about precedence
Sebastian Ullrich (Dec 20 2022 at 17:13):
Mario Carneiro said:
another parenthesizer bug that isn't about precedence
Yes, and because of that I don't think the general parenthesizer framework should solve this, or at least I don't see any reasonable way short of some crazy grammar analysis. But this specific case (and I already forgot the other one) is easy enough to fix. https://github.com/leanprover/lean4/commit/96ccf192e8a5fe216bbc63c688a06b2032bd14f5
Mario Carneiro (Dec 20 2022 at 17:20):
I don't think we should have crazy grammar analysis, I think we should have special case parenthesizers which handle this stuff
Mario Carneiro (Dec 20 2022 at 17:21):
the other one is (try foo); bar
turning into try foo; bar
Mario Carneiro (Dec 20 2022 at 18:30):
Okay, I'm releasing my hold on Data.List.Basic. I did the first 2900 lines, plus renaming stuff for the part that still hasn't been touched yet.
Thomas Murrills (Dec 20 2022 at 20:00):
fixing 2900-2970
Thomas Murrills (Dec 20 2022 at 20:30):
Hmm, foldrM_cons
was moved to std, but now requires an instance of LawfulMonad
which was not previously assumed for the Data.List.Basic
version of it.
How should we proceed? Make all of the downstream theorems also depend on a LawfulMonad
instance, or use a different name?
Mario Carneiro (Dec 20 2022 at 20:32):
yes, the downstream theorems are almost certainly assuming LawfulMonad
anyway
Mario Carneiro (Dec 20 2022 at 20:32):
it's not true without the assumption anymore
Thomas Murrills (Dec 21 2022 at 03:42):
working on splitAt_eq_take_drop
Thomas Murrills (Dec 21 2022 at 04:29):
splitOnP
now takes a Bool
-valued predicate instead of a Prop
-valued one—we're rewriting everything related to splitOnP
to match, not keeping a separate Prop
-predicate version of splitOnP
, right? just checking.
Scott Morrison (Dec 21 2022 at 05:26):
Seems reasonable. You'll want to #align with an ₓ
.
Chris Hughes (Dec 21 2022 at 13:27):
Having trouble proving things about the new definition of splitOnP
. Can't even seem to prove the equation lemmas for splitOnP.go
Thomas Murrills (Dec 21 2022 at 18:30):
I'll try to work on it rn (~3000 - 3220)
Thomas Murrills (Dec 21 2022 at 19:03):
Can we safely get rid of theorems of the form split_on_p_aux*
? It seems like they're only used to help prove facts about splitOnP
, and it might be easier to prove those from scratch due to the new plumbing in splitOnP
. (I can't find any occurrences for each of them anywhere else in mathlib3.)
Chris Hughes (Dec 21 2022 at 22:45):
I think so
Thomas Murrills (Dec 22 2022 at 01:22):
Ok, I think I’ve broken through the worst of the go
’s—whew! haven’t committed because I’ve got a bunch of false starts lying around, and don’t want to subject anyone else to the mess :) I’ll resume in a couple hours and try to get a clean commit in for this section.
Reid Barton (Dec 22 2022 at 14:27):
Is the general consensus for this file that lemmas about e.g. filter
should take as argument p : α → Bool
and not α → Prop
?
Reid Barton (Dec 22 2022 at 14:28):
It seems to be really hard to apply versions with Prop
in situations where you have Bool
, because the p
in filter p
is not actually the variable like it appears
Mario Carneiro (Dec 22 2022 at 14:29):
I think the lemmas should use A -> Bool
iff the function does
Mario Carneiro (Dec 22 2022 at 14:29):
it doesn't make any sense for them not to match
Reid Barton (Dec 22 2022 at 14:33):
And if the lemma also involves an if
about p x
where p : A -> Bool
, then should it be changed to bif
?
Reid Barton (Dec 22 2022 at 14:57):
Seems like maybe sticking with if
is better, since if
is used in a lot of other places?
Mario Carneiro (Dec 22 2022 at 15:07):
We may or may not want two versions in those cases. I think if
is handled a bit better than bif
, which is really just syntax for cond
and doesn't get special handling by the split
/split_ifs
tactics
Thomas Murrills (Dec 22 2022 at 20:43):
finished splitOnP
! moving onto lookmap
—it seems to be the same sort of go
-wrangling.
Thomas Murrills (Dec 22 2022 at 21:56):
Oh, I wanted to ask: I proved a couple of thorny theorems about modifyLast
that dive into modifyLast.go
, but didn’t wind up needing them. Though, they fit pretty well in Data.List.Basic
and are natural equalities to want (modifyLast f (l ++ [a]) = l ++ [f a]
and modifyLast f (l₁ ++ l₂) = l₁ ++ modifyLast f l₂
given l₂ ≠ []
).
Should I leave them in their own new section as they are now, or save them til after the port/discard them?
Johan Commelin (Dec 22 2022 at 22:09):
Lean complains on L4128 (the first error in the file)
#align list.erasep List.erasePₓ -- prop -> bool
-- list.erasep has already been aligned (to List.erasep)
Johan Commelin (Dec 22 2022 at 22:09):
Can we just erase it?
Johan Commelin (Dec 22 2022 at 22:10):
I guess so. The align is done in Data.List.Defs
.
Johan Commelin (Dec 22 2022 at 22:10):
Pushed a minifix
Thomas Murrills (Dec 22 2022 at 22:10):
I think something else should be done: it's currently aligned to something that doesn't change prop
to Bool
/-- `erasep p l` removes the first element of `l` satisfying the predicate `p`. -/
def erasep (p : α → Prop) [DecidablePred p] : List α → List α
| [] => []
| a :: l => if p a then l else a :: erasep p l
#align list.erasep List.erasep
Thomas Murrills (Dec 22 2022 at 22:11):
Note the name: erasep
vs. eraseP
, the latter of which is in Std and makes the switch from Prop
to Bool
Johan Commelin (Dec 22 2022 at 22:11):
First error is now on L4313. Second error on L4729. Getting close!
Thomas Murrills (Dec 22 2022 at 22:11):
I think erasep
should be deleted from Data.List.Defs
Johan Commelin (Dec 22 2022 at 22:12):
Aha, that sounds sensible!
Johan Commelin (Dec 22 2022 at 22:12):
Feel free to revert my minifix
Thomas Murrills (Dec 22 2022 at 22:15):
I'm not seeing your minifix on github; I'll just fix it as-is and hope it goes through :sweat_smile:
Thomas Murrills (Dec 24 2022 at 04:20):
What's the canonical place for #align
s between Lean 3 core and Std? (Here the relevant aligns were ball_cons
to forall_mem_cons
and ball_nil
to forall_mem_nil
, all in the namespace list
/List
)
Mario Carneiro (Dec 24 2022 at 04:33):
in the relevant mathlib4 file
Mario Carneiro (Dec 24 2022 at 04:35):
ball_cons
is in init.data.list.lemmas
, so the #align ball_cons forall_mem_cons
should go in Mathlib.Init.Data.List.Lemmas
(in the same order as the lean 3 declarations)
Thomas Murrills (Dec 24 2022 at 04:48):
I see, I didn't realize Lean core had that sort of correspondence with mathlib—makes sense now that I do :)
Reid Barton (Dec 24 2022 at 12:37):
I don't want to get anyone too excited but Data.List.Basic now compiles without errors.
Reid Barton (Dec 24 2022 at 12:37):
What now?
Reid Barton (Dec 24 2022 at 14:39):
I read through the whole file and it seems to be in pretty good shape actually. Some remaining questions:
- Should we align
list.repeat
andList.replicate
? - Are we really adding
instance : Monad List
? - We don't want to keep these enormous "dubious translation" comments, do we?
- Do we need to add dozens of xs, e.g. on all the lemmas about
filter
? How?
Reid Barton (Dec 24 2022 at 14:55):
I think the answers to the first and third ones are "no".
Ruben Van de Velde (Dec 24 2022 at 15:15):
Repeat and replicate have the arguments in the opposite order, so I think not
Eric Wieser (Dec 24 2022 at 15:29):
The suggestion elsewhere was to backport the argument reorder
Reid Barton (Dec 24 2022 at 15:40):
Right. So presumably that doesn't require any action in mathlib4 for now
Eric Wieser (Dec 24 2022 at 16:39):
If we backport first then we can align and not have to merge things later
Reid Barton (Dec 24 2022 at 16:55):
Hmm, I'd almost rather not backport/align at all
Mario Carneiro (Dec 24 2022 at 18:00):
We can also not backport and #align
with x. The resulting files will not compile because they will e.g. call List.replicate with arguments in the wrong order, but that might be good enough for manual porting work, since we've probably already seen most of the uses of this function in this file
Reid Barton (Dec 24 2022 at 19:48):
Ad Monad List
, does attribute [local instance]
work in Lean 4?
Reid Barton (Dec 24 2022 at 19:48):
Maybe we can just make a def
and locally make it an instance to state its API lemmas and wherever else the instance is needed in mathlib
Kevin Buzzard (Dec 24 2022 at 19:52):
class foo (α : Type) where
def bar : foo Nat := { }
#synth foo Nat -- fails
attribute [local instance] bar
#synth foo Nat -- works
Looks like it's OK
Mario Carneiro (Dec 24 2022 at 20:04):
We could make Monad List
a scoped instance
Johan Commelin (Dec 26 2022 at 09:39):
I fixed the non simp_nf linting errors
Reid Barton (Dec 26 2022 at 10:08):
Scoped to List
, or to something more specific (ListMonad
?)?
Johan Commelin (Dec 26 2022 at 10:14):
-- somewhere in Std
@[simp] theorem getLast_eq_getLastD (a l h) : @getLast α (a::l) h = getLastD l a := by
cases l <;> rfl
Is this a good simp lemma? Should getLastD
be the snf?
Johan Commelin (Dec 26 2022 at 10:38):
What should we do with lint errors like
#check @List.mem_map_swap /- Left-hand side simplifies from
(y, x) ∈ List.map Prod.swap xs
to
Exists fun a ↦ Exists fun b ↦ (a, b) ∈ xs ∧ b = y ∧ a = x
using
simp only [List.mem_map', Prod.exists, Prod.swap_prod_mk, Prod.mk.injEq]
Try to change the left-hand side to the simplified term!
-/
Johan Commelin (Dec 26 2022 at 10:39):
Should we
- remove the
@[simp]
and do nothing else - remove the
@[simp]
and create a new simp-lemma with a simplified LHS as instructed by the linter - just modify the statement, as instructed
Johan Commelin (Dec 26 2022 at 10:40):
I've fixed all the trivial linting errors. The remaining ones are variations on :up:
Reid Barton (Dec 26 2022 at 10:41):
I guess maybe the first question is what is the situation in mathlib 3? Does the LHS not simplify with mathlib's simp set?
Johan Commelin (Dec 26 2022 at 10:42):
I think Std
introduces a bunch of simp lemmas that diverge from the mathlib3 simpset
Mario Carneiro (Dec 26 2022 at 10:56):
Both of the examples look like reasonable simp lemmas. List.map_mem_swap
less so
Mario Carneiro (Dec 26 2022 at 10:58):
getLastD
has better defeqs than getLast
Jihoon Hyun (Jan 04 2023 at 03:24):
Hello, I'd like to contribute to Data.List.Basic or its successor. I could find that there were intense discussions on linting Data.List.Basic, and the only work left is about linting. As I'm still kind of new here, I'd like to ask if I can start porting the successor like Data.List.TFAE, or it should start after every linting errors are corrected.
Mario Carneiro (Jan 04 2023 at 04:27):
You can always work on a file which is still in PR stage, you just need to make your PR dependent on that one. If it's still giving linting errors then you will most likely see those same errors in CI for your branch, so it won't be able to be merged either until the other one is fixed and your branch merges the fixes in, but otherwise it shouldn't be a blocker to preparing the PR
Johan Commelin (Jan 04 2023 at 20:41):
For the record, this is what's left here:
-- Found 4 errors in 25005 declarations (plus 59456 automatically generated ones) in mathlib with 13 linters
/- The `simpNF` linter reports:
SOME SIMP LEMMAS ARE NOT IN SIMP-NORMAL FORM.
see note [simp-normal form] for tips how to debug this.
https://leanprover-community.github.io/mathlib_docs/notes.html#simp-normal%20form -/
-- Mathlib.Data.List.Basic
#check List.get_insertNth_self.{u} /- Left-hand side does not simplify, when using the simp lemma on itself.
This usually means that it will never apply.
-/
#check List.nthLe_insertNth_self.{u} /- Left-hand side does not simplify, when using the simp lemma on itself.
This usually means that it will never apply.
-/
#check List.init_cons_of_ne_nil.{u_1} /- simp can prove this:
by simp only [_private.Std.Data.List.Init.Lemmas.0.List.dropLast._eq_3]
One of the lemmas above could be a duplicate.
If that's not the case try reordering lemmas or adding @[priority].
-/
#check List.attach_map_coe'.{u, v} /- Left-hand side does not simplify, when using the simp lemma on itself.
This usually means that it will never apply.
-/
Johan Commelin (Jan 04 2023 at 20:42):
These seem to be final end-bosses.
Thomas Murrills (Jan 05 2023 at 02:19):
Does it make sense to delete init_cons_of_ne_nil
and #noalign
it? It seems it can replaced in a simp
call by simp only [dropLast]
now. Or do we align it with the equation for dropLast
, if that's possible?
Mario Carneiro (Jan 05 2023 at 02:19):
if the theorem is still true I don't see any reason to remove it
Thomas Murrills (Jan 05 2023 at 02:20):
ok! so just remove @[simp]
from it?
Mario Carneiro (Jan 05 2023 at 02:22):
is dropLast
marked as simp?
Thomas Murrills (Jan 05 2023 at 02:23):
ah...no, it's not.
Thomas Murrills (Jan 05 2023 at 02:26):
however, example {α : Type _} {x : α} {l : List α} (_ : l ≠ []) : (x :: l).dropLast = x :: l.dropLast := by simp
works and the trace shows that it uses a dropLast
definition lemma (@List.dropLast._eq_3
, as expected)
Thomas Murrills (Jan 05 2023 at 02:30):
(maybe I don't know the appropriate way to check if dropLast
is marked as simp...all I know is @[simp]
doesn't appear above the declaration)
Gabriel Ebner (Jan 05 2023 at 02:42):
There's an attribute [simp] dropLast
in std4.
Thomas Murrills (Jan 05 2023 at 02:45):
(ah, ok, I see how it works now!)
Johan Commelin (Jan 05 2023 at 06:49):
Gabriel Ebner said:
There's an
attribute [simp] dropLast
in std4.
Wait, I thought those weren't global? Am I mistaken?
Reid Barton (Jan 05 2023 at 08:13):
attribute [simp]
is global, but attribute [local simp]
and attribute [-simp]
are not
Johan Commelin (Jan 05 2023 at 08:20):
oooh! I see. That's not what I expected.
Yaël Dillies (Jan 05 2023 at 08:42):
That certainly is a bit confusing. Is there a hover or something else that will teach people this?
Johan Commelin (Jan 05 2023 at 09:31):
This file is now passing the linter! Thanks @Mario Carneiro
Johan Commelin (Jan 05 2023 at 14:16):
What do we do here?
theorem nthLe_reverse' (l : List α) (n : ℕ) (hn : n < l.reverse.length) (hn') :
l.reverse.nthLe n hn = l.nthLe (l.length - 1 - n) hn' := by
rw [eq_comm]
convert nthLe_reverse l.reverse n (by simpa) hn using 1
simp
#align list.nth_le_reverse' List.nthLe_reverse'
theorem get_reverse' (l : List α) (n) (hn') :
l.reverse.get n = l.get ⟨l.length - 1 - n, hn'⟩ := nthLe_reverse' ..
-- FIXME: prove it the other way around
attribute [deprecated get_reverse'] nthLe_reverse'
Johan Commelin (Jan 05 2023 at 14:17):
Note that the types don't line up:
#check nthLe_reverse'
-- List.nthLe_reverse'.{u} {α : Type u} (l : List α) (n : ℕ) (hn : n < length (reverse l))
-- (hn' : length l - 1 - n < length l) : nthLe (reverse l) n hn = nthLe l (length l - 1 - n) hn'
#check get_reverse'
-- List.get_reverse'.{u} {α : Type u} (l : List α) (n : Fin (length (reverse l))) (hn' : length l - 1 - ↑n < length l) :
-- get (reverse l) n = get l { val := length l - 1 - ↑n, isLt := hn' }
Johan Commelin (Jan 05 2023 at 14:17):
So I'm questioning whether the attribute [deprecated]
is even correct.
Johan Commelin (Jan 05 2023 at 14:19):
Ooh, I guess this is just a very general thing about nthLe
vs get
?
Johan Commelin (Jan 05 2023 at 14:20):
I'm not sure we should have deprecated nthLe
in that case. Sounds like something that should better be done after the port.
Johan Commelin (Jan 05 2023 at 14:20):
We're doing too many refactors on the fly.
Johan Commelin (Jan 05 2023 at 14:40):
I fixed two of the FIXME
s in the file. What remains is very non-urgent.
Johan Commelin (Jan 05 2023 at 14:40):
I'm going to kick this on the queue.
Johan Commelin (Jan 05 2023 at 14:40):
Ooh, @Chris Hughes was faster (-;
Henrik Böving (Jan 05 2023 at 15:03):
done :octopus:
Mario Carneiro (Jan 05 2023 at 19:32):
Johan Commelin said:
We're doing too many refactors on the fly.
deprecated
is explicitly not a refactor. It is a marker which is used to prepare the library for a future refactor. Importantly, the original lemmas still exist and still have the types required for downstream stuff.
Mario Carneiro (Jan 05 2023 at 19:33):
the nthLe
refactor cannot proceed until we have at least the majority of code using nthLe
available, which means it will not be removed / reassessed until after the port
Mario Carneiro (Jan 05 2023 at 19:35):
in general deprecated
is being used when the replacement lemma is more than a little different, such that it would be too much to do the refactor on the fly
Johan Commelin (Jan 05 2023 at 20:01):
but the deprecated linter can be an annoying speedbump. Should we be lax about nolinting in that case?
Mario Carneiro (Jan 05 2023 at 21:18):
nolint doesn't work on the deprecated linter, since it's not a real linter but just a warning that is thrown up when you use a deprecated definition directly during elaboration. You have to use set_option linter.deprecated false
to turn it off or else CI will complain
Johan Commelin (Jan 05 2023 at 21:31):
So should we be lax with that option?
Mario Carneiro (Jan 05 2023 at 21:47):
yes
Mario Carneiro (Jan 05 2023 at 21:47):
I mean it's a requirement in any case
Johan Commelin (Jan 05 2023 at 21:53):
Or you rewrite the proof... which can be tedious.
Mario Carneiro (Jan 05 2023 at 21:56):
for a theorem which mentions nthLe
rewriting the proof isn't an option
Johan Commelin (Jan 05 2023 at 21:56):
sure, but I've seen examples where only the proof used deprecated decls.
Johan Commelin (Jan 05 2023 at 21:56):
I vote for allowing those during the port.
Mario Carneiro (Jan 05 2023 at 21:57):
for theorems which use nthLe
internally but not in the statement, I will leave it up to the porter whether they want to try removing it or not
Mario Carneiro (Jan 05 2023 at 21:57):
leaving it alone is totally fine
Last updated: Dec 20 2023 at 11:08 UTC