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 #aligned

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 nths 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 nths at all. We're replacing it with get?.

I'm not entirely sure about this decision. Maybe leave the nthLes 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):

mathlib4#1118

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 #aligns 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 #aligns 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 #aligns 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 and List.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

  1. remove the @[simp] and do nothing else
  2. remove the @[simp] and create a new simp-lemma with a simplified LHS as instructed by the linter
  3. 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 FIXMEs 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):

:merge: 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