Zulip Chat Archive

Stream: mathlib4

Topic: multiple files


Reid Barton (May 31 2023 at 15:00):

How do I work on two files added to mathlib A.lean and B.lean, where A uses sorry, and B imports A?
lake build errors on the sorry and doesn't build an olean file for A

Reid Barton (May 31 2023 at 15:01):

And when I have B open it tries to build A and fails.

Alex J. Best (May 31 2023 at 15:06):

Does replacing sorry with admit help?

Reid Barton (May 31 2023 at 15:06):

I replaced with an axiom :upside_down:

Reid Barton (May 31 2023 at 15:07):

I used it in term mode a lot.

Reid Barton (May 31 2023 at 15:07):

OMG error: unused variable `h` [linter.unusedVariables]

Reid Barton (May 31 2023 at 15:08):

Yeah no kidding, it will be used in the proof.

Reid Barton (May 31 2023 at 15:08):

Am I in uncharted territory?

Jon Eugster (May 31 2023 at 15:11):

If you remove that setting fron the lakefile, does that work or would that invalidate all the cache?

Jon Eugster (May 31 2023 at 15:12):

That is DwarningsAsErrors

Reid Barton (May 31 2023 at 15:12):

It started rebuilding everything

Reid Barton (May 31 2023 at 15:14):

The good news is when I put it back, it only rebuilt the 5 files it got to before I stopped it!

Reid Barton (May 31 2023 at 15:27):

Maybe it's better for now to work in a project with mathlib as a dependency?

Adam Topaz (May 31 2023 at 15:33):

This same issue came up for me yesterday. Is using axioms really the only way?

Reid Barton (May 31 2023 at 16:01):

Certainly we're going to need some way to work on multiple files at once without being stopped by linter nonsense

Patrick Massot (May 31 2023 at 16:03):

I think we need a way to enable this DwarningsAsErrors only in CI, not when editing files.

Yaël Dillies (May 31 2023 at 16:07):

Also surely the unused variables linter should just shut up whenever a declaration uses sorry, no?

Reid Barton (May 31 2023 at 16:09):

That also sounds extremely reasonable

Sophie Morel (May 31 2023 at 16:19):

Adam Topaz said:

This same issue came up for me yesterday. Is using axioms really the only way?

I had the same issue too. My solution was to fill in all the sorry's in the imported file, which is suboptimal in general.

Adam Topaz (May 31 2023 at 16:46):

Ah I see now. It's all because of these lines in the lakefile?

-- These settings only apply during `lake build`, but not in VSCode editor.
def moreLeanArgs := #[
  "-DwarningAsError=true"
] ++ moreServerArgs

Maybe we can arrange for the CI to just add that flag as part of the build, and remove this from mathlib4's lakefile?

Adam Topaz (May 31 2023 at 16:48):

There must be a way to pass this flag directly in the lake build command in the CI itself, no?

Ruben Van de Velde (May 31 2023 at 16:54):

As long as we can still reuse the cache from ci

Mario Carneiro (May 31 2023 at 20:00):

The much simpler way to shut up the unused variables linter is to (1) use _ before the variable or (2) turn off the unused variables linter in the file or section

Adam Topaz (May 31 2023 at 20:01):

But the sorries causing errors is a bigger problem. It essentially means you cannot work with multiple files at the same time.

Mario Carneiro (May 31 2023 at 20:01):

Yaël Dillies said:

Also surely the unused variables linter should just shut up whenever a declaration uses sorry, no?

I don't think this is a good idea, because it's easy to cause that old issue where def foo (x : Nat) : Nat := sorry creates a constant function and theorems are suddenly really easy to prove by rfl

Mario Carneiro (May 31 2023 at 20:02):

using an axiom is a decent workaround, I use that in test files too sometimes

Mario Carneiro (May 31 2023 at 20:02):

but it's definitely more dangerous since it would also pass CI

Adam Topaz (May 31 2023 at 20:03):

That (using axioms) doesn't scale. If I'm working on some file with deeply nested structures with various obvious proof obligations that I'm too lazy to fulfill right now, I don't want to have to introduce 37 axioms just to be able to use this file in a second file I'm working on.

Mario Carneiro (May 31 2023 at 20:04):

I think moving CI to use -DwarningsAsErrors makes sense

Mario Carneiro (May 31 2023 at 20:04):

that's usually what I do in other languages

Mario Carneiro (May 31 2023 at 20:04):

It's not 37 axioms, it's 1 axiom mySorry {A : Sort _} : A

Mario Carneiro (May 31 2023 at 20:05):

and then you use mySorry instead of sorry

Adam Topaz (May 31 2023 at 20:05):

oh I see okay.

Adam Topaz (May 31 2023 at 20:05):

yeah that's fine then :)

Adam Topaz (May 31 2023 at 20:06):

But then I have to remember to remove 37 mySorries at some point

Mario Carneiro (May 31 2023 at 20:06):

well you should remove mySorry itself before it hits the PR

Adam Topaz (May 31 2023 at 20:06):

Well, I guess just removing the axiom will give all the errors.

Mario Carneiro (May 31 2023 at 20:07):

IIRC the roadmap directory also had a mySorry in it

Reid Barton (May 31 2023 at 20:26):

Mario Carneiro said:

(2) turn off the unused variables linter in the file or section

How do I do this?

Reid Barton (May 31 2023 at 20:27):

Mario Carneiro said:

Yaël Dillies said:

Also surely the unused variables linter should just shut up whenever a declaration uses sorry, no?

I don't think this is a good idea, because it's easy to cause that old issue where def foo (x : Nat) : Nat := sorry creates a constant function and theorems are suddenly really easy to prove by rfl

Renaming x to _x will not help with that. And meanwhile it adds a bunch of busy work that also needs to be undone later when/if you fill in the sorry.

Reid Barton (May 31 2023 at 20:31):

What would be cool is if sorry could generate something like sorryAx x, for each unused variable x in scope (or maybe just every variable in scope?)

Reid Barton (May 31 2023 at 20:34):

Unfortunately just writing mySorry x doesn't work (Lean doesn't seem to want to infer the type of mySorry as a function)

Mario Carneiro (May 31 2023 at 20:43):

Reid Barton said:

Mario Carneiro said:

(2) turn off the unused variables linter in the file or section

How do I do this?

The reason linter warnings mention the linter name is because it's an option that you can set

Mario Carneiro (May 31 2023 at 20:43):

set_option linter.unusedVariables false

Mario Carneiro (May 31 2023 at 20:45):

Reid Barton said:

What would be cool is if sorry could generate something like sorryAx x, for each unused variable x in scope (or maybe just every variable in scope?)

It should be every variable in scope, except possibly the implDetail variables like the theorem name itself since this can cause a weird interaction with the termination checker

Mario Carneiro (May 31 2023 at 20:46):

this sounds like a proposal for a sorry! tactic

Reid Barton (May 31 2023 at 20:47):

Doesn't sorry already behave as some special elaborator?

Mario Carneiro (May 31 2023 at 20:47):

it has an elaborator, not sure how special it is

Mario Carneiro (May 31 2023 at 20:47):

it elaborates to sorryAx _ IIRC

Reid Barton (May 31 2023 at 20:48):

Fair enough

@[builtin_term_elab «sorry»] def elabSorry : TermElab := fun stx expectedType? => do
  let stxNew  `(sorryAx _ false)
  withMacroExpansion stx stxNew <| elabTerm stxNew expectedType?

Mario Carneiro (May 31 2023 at 20:48):

note that tactic sorry has a separate implementation, also in terms of sorryAx

macro "sorry" : tactic => `(tactic| exact @sorryAx _ false)

Reid Barton (May 31 2023 at 20:50):

I guess it could be ... exact sorry right?

Reid Barton (May 31 2023 at 20:51):

If possible, I'd prefer to avoid adding yet another thing that you have to know and remember about to opt in to the correct behavior rather than the wrong one

Reid Barton (May 31 2023 at 20:52):

I guess that when the type of the sorry is a Prop, there's no need to make a term that depends on all the variables

Mario Carneiro (May 31 2023 at 20:53):

Sure, make an issue ig

Reid Barton (May 31 2023 at 20:54):

Anyways, I think the more urgent question is how we can get -DwarningAsError=true used only by CI, while still having it produce usable oleans. I guess Lean needs to be told that this flag doesn't olean compatibility?

Mario Carneiro (May 31 2023 at 20:55):

I'm pretty sure something like lake build --lean-args="-DwarningAsError=true" works, I need to look up the syntax

Mario Carneiro (May 31 2023 at 20:55):

the olean compatibility problem is solved as long as the user lakefile.lean is byte for byte equal to the one used by CI

Reid Barton (May 31 2023 at 20:56):

Oh wild

Reid Barton (May 31 2023 at 20:56):

I assumed it would be based on the actual flags used

Reid Barton (May 31 2023 at 20:58):

It seems like adding irrelevant whitespace to the lakefile doesn't invalidate my oleans

Mario Carneiro (May 31 2023 at 20:59):

It invalidates the cache key

Reid Barton (May 31 2023 at 21:00):

Oh I see, I'm not using any cache.

Mario Carneiro (May 31 2023 at 21:01):

looking at the code now, lake lets you set -K options which are accessible via get_config? to the lakefile, so we could put some code in meta if get_config? CI = true then ... and set -KCI=true on the CI command line

Reid Barton (May 31 2023 at 21:06):

In general I would expect that running lake build with different -K flags would cause recompilation, especially if this involves invoking Lean with different options.

Mario Carneiro (May 31 2023 at 21:07):

the oleans don't have the lake invocation that produced them written in their binary, so I don't see why?

Reid Barton (May 31 2023 at 21:08):

The experiment I did was to just comment out the "-DwarningAsError=true" line, and then lake build started rebuilding stuff. So there is some mechanism here we need to evade or disable.

Mario Carneiro (May 31 2023 at 21:08):

if you produce oleans with different configuration then okay, but if it has no effect on the end product I don't think lake is doing any additional caching

Mario Carneiro (May 31 2023 at 21:08):

yeah, changing the lakefile directly won't work

Reid Barton (May 31 2023 at 21:09):

Do you mean that lake is the thing doing the recompilation checking, via its own invalidation mechanism, and not lean?

Mario Carneiro (May 31 2023 at 21:09):

yes, of course

Mario Carneiro (May 31 2023 at 21:09):

lean doesn't do any dependency tracking at all

Mario Carneiro (May 31 2023 at 21:10):

it doesn't have a --make mode anymore, it just compiles what you tell it to

Reid Barton (May 31 2023 at 21:10):

how quaint!

Mario Carneiro (May 31 2023 at 21:11):

the model seems to be based on rustc / cargo interactions, or gcc / make

Mario Carneiro (May 31 2023 at 21:12):

the compiler just takes a bazillion flags telling it what to read and what to write and the build tool does dependency management and recompiles things intelligently

Reid Barton (May 31 2023 at 21:13):

Where is this state stored then? In these .trace files?

Mario Carneiro (May 31 2023 at 21:13):

I was thinking it was in the oleans but that makes more sense

Mario Carneiro (May 31 2023 at 21:14):

yes the .trace file contains a hash of the stuff which would invalidate the artifact if changed

Mario Carneiro (May 31 2023 at 21:15):

although if you use --old it ignores the hashes and uses modification date tracking instead

Reid Barton (May 31 2023 at 21:19):

This seems promising but I'm not sure how to reconcile these statements

  1. Removing "-DwarningAsError=true" from moreLeanArgs causes recompilation
  2. Adding irrelevant whitespace to the file doesn't cause recompilation
  3. Passing lake a -KCI=true command line option doesn't cause recompilation even if the effect is to add something to moreLeanArgs

Reid Barton (May 31 2023 at 21:19):

I tested 1 and 2 but not 3.

Mario Carneiro (May 31 2023 at 21:23):

I am not sure yet what the mechanism is for (2)

Reid Barton (May 31 2023 at 21:24):

I do like these .trace files that are just hashes printed in decimal

Eric Wieser (May 31 2023 at 21:25):

Isn't catching every variable in scope going to do totally the wrong thing for:

variables {X Y : Type*} -- used elsewhere

def foo (a : ) :  := new_sorry

which would make foo take three arguments not one?

Reid Barton (May 31 2023 at 21:25):

Anyone got a shorter one than... (16 bytes) ?

-rw-rw-r-- 1 rwbarton rwbarton 16 May 31 22:57 ./build/lib/Mathlib/Algebra/Module/Opposites.trace

Mario Carneiro (May 31 2023 at 21:27):

looks like the hash of a lean module is the combined hashes of its olean and ilean files. So if you make a modification that doesn't affect either one then it won't be invalidated

Reid Barton (May 31 2023 at 21:28):

Wait what about the source? Is this a different kind of hash? Or do you mean the "hash of an imported lean file"?

Mario Carneiro (May 31 2023 at 21:29):

no the source is not hashed, that was my point actually

Mario Carneiro (May 31 2023 at 21:30):

however the ilean is quite overfit to the source because of things like line/col positions

Reid Barton (May 31 2023 at 21:30):

Doesn't lake rebuild an olean file if I edit the source file?

Reid Barton (May 31 2023 at 21:30):

Or is this handled some other way (like by modification time)?

Mario Carneiro (May 31 2023 at 21:31):

modification time is used, sometimes...

Mario Carneiro (May 31 2023 at 21:32):

this code is really abstract, it's hard to tell why it does anything

Reid Barton (May 31 2023 at 21:33):

I am afraid if I look at it I will get flashbacks to Cabal.

Mario Carneiro (May 31 2023 at 21:33):

it's peak functional programming

Reid Barton (May 31 2023 at 21:33):

(Did you know Cabal supports non-GHC compilers? ...I think?)

Reid Barton (May 31 2023 at 21:34):

Maybe it is easier to just test on a new project

Mario Carneiro (May 31 2023 at 21:34):

did you know lake supports lakefiles that aren't called lakefile.lean? (The server definitely doesn't!)

Floris van Doorn (Jun 01 2023 at 11:38):

Mario Carneiro said:

I don't think this is a good idea, because it's easy to cause that old issue where def foo (x : Nat) : Nat := sorry creates a constant function and theorems are suddenly really easy to prove by rfl

Most of the time we're using sorry for theorems, and it would be nice if the linter didn't flag those.


Last updated: Dec 20 2023 at 11:08 UTC