Zulip Chat Archive
Stream: mathlib4
Topic: Lean-based "changed names" script?
Yury G. Kudryashov (Mar 15 2025 at 19:35):
WDYT about running something like
import Lean.Environment
open Lean
def main (_ : List String) : IO Unit := do
initSearchPath (← findSysroot)
unsafe withImportModules #[{module := `Mathlib}] {} (trustLevel := 1024) fun env => do
for (c, _) in env.constants do
if !c.hasMacroScopes && !c.isInternal then
IO.println c
(TODO: sort alphabetically), upload these files for master
somewhere, then diff
ing master
to HEAD
in the CI?
Yury G. Kudryashov (Mar 15 2025 at 19:35):
(instead of the current text search in git diff
)
Yury G. Kudryashov (Mar 15 2025 at 19:37):
This will catch stuff like "simps
gnerates different set of lemmas now" or "to_additive
chose a different name for the additive version".
Ruben Van de Velde (Mar 15 2025 at 19:37):
Or " I accidentally changed namespaces"
Yury G. Kudryashov (Mar 15 2025 at 19:38):
BTW, what's the right way to sort it in Lean?
Yury G. Kudryashov (Mar 15 2025 at 19:41):
For #22461, I used lake exe print_decls | sort
Yury G. Kudryashov (Mar 15 2025 at 19:42):
See also #lean4 > What's the right way to print lots of lines? for a thread where I asked why my script was slow (answer: because I was running it inside #eval
).
Michael Rothgang (Mar 15 2025 at 20:29):
@Damiano Testa is working on a rewrite of the "declarations diff" script in Lean - and if I understood correctly, this would also catch such versions, right?
Damiano Testa (Mar 15 2025 at 20:32):
The relevant PR is #22464, but I have not checked how different that is from what Yury wants.
Damiano Testa (Mar 15 2025 at 20:33):
The file is not actually persisted: the script creates one for master and one for the PR, sorts them and then lets diff
do the rest.
Damiano Testa (Mar 15 2025 at 20:35):
By the way, the script that I use in that PR is indeed slow: if there is anything in there that is useful to you, feel free to take it or push over it!
Yury G. Kudryashov (Mar 15 2025 at 21:11):
I'll try to speed it up tonight.
Yury G. Kudryashov (Mar 16 2025 at 02:19):
This executable runs in 4-5s:
import Lean
open Lean
/-- A copy of `isAutoDecl` from Batteries that takes `env` as an argument
instead of using `getEnv`.
TODO: upstream. -/
def isAutoDecl (env : Environment) (decl : Name) : Bool := Id.run do
if decl.hasMacroScopes then return true
if decl.isInternal then return true
if isReservedName env decl then return true
if let Name.str n s := decl then
if s.startsWith "proof_" || s.startsWith "match_" || s.startsWith "unsafe_" then return true
if env.isConstructor n && ["injEq", "inj", "sizeOf_spec"].any (· == s) then
return true
if let ConstantInfo.inductInfo _ := env.find? n then
if s.startsWith "brecOn_" || s.startsWith "below_" || s.startsWith "binductionOn_"
|| s.startsWith "ibelow_" then return true
if [casesOnSuffix, recOnSuffix, brecOnSuffix, binductionOnSuffix, belowSuffix, "ibelow",
"ndrec", "ndrecOn", "noConfusionType", "noConfusion", "ofNat", "toCtorIdx"
].any (· == s) then
return true
if let some _ := isSubobjectField? env n (.mkSimple s) then
return true
pure false
unsafe def main (_ : List String) : IO Unit := do
initSearchPath (← findSysroot)
withImportModules #[{module := `Mathlib}] {} (trustLevel := 1024) fun env => do
let names : Array String := (env.constants.fold · #[]) fun ar c _ ↦
if isAutoDecl env c then ar else ar.push c.toString
for name in names.qsortOrd do
IO.println name
Yury G. Kudryashov (Mar 16 2025 at 02:21):
I'm tired after the flight (it got delayed for ~2h30m), so I can't test if it speeds up your bash
script (git checkout + getting cache takes time too) tonight.
Yury G. Kudryashov (Mar 16 2025 at 03:49):
Your Lean script takes ~50s on my laptop, probably because of the insertion sort.
Yury G. Kudryashov (Mar 16 2025 at 03:57):
@Mario Carneiro WDYT about adding a version of isAutoDecl
that takes an environment as an argument instead of relying on getEnv
?
Mario Carneiro (Mar 16 2025 at 03:59):
what's the motivation? Can't you just pass in a monad reader state containing the env
of your choice?
Yury G. Kudryashov (Mar 16 2025 at 04:05):
My motivation is "I don't know how to do it". Probably, it's a wrong motivation.
Yury G. Kudryashov (Mar 16 2025 at 04:14):
Another solution (for me) would be adding instructions on how to run a chunk of code in a context with ← getEnv
returning a given env
to the docstring of getEnv
.
Yury G. Kudryashov (Mar 16 2025 at 04:19):
Is it docs#Lean.withEnv ?
Mario Carneiro (Mar 16 2025 at 04:20):
yes, that will do it
Yury G. Kudryashov (Mar 16 2025 at 04:23):
One more question: how do run CoreM
code from inside a pure function?
Yury G. Kudryashov (Mar 16 2025 at 04:26):
Found docs#Lean.Core.CoreM.toIO and docs#CoreM.withImportModules
Yury G. Kudryashov (Mar 16 2025 at 04:39):
This prints nothing :(
import Mathlib.Lean.CoreM
import Batteries.Tactic.Lint.Basic
open Lean
unsafe def main (_ : List String) : IO Unit := do
initSearchPath (← findSysroot)
let names : Array String ← CoreM.withImportModules #[`Mathlib] (trustLevel := 1024) do
flip (← getEnv).constants.foldM #[] fun ar name _ ↦ do
if !(← Batteries.Tactic.Lint.isAutoDecl name) then
return ar.push name.toString
else
return ar
for name in names.qsortOrd do
IO.println name
... and I don't know how to debug meta code.
Christian Merten (Mar 16 2025 at 10:07):
I think the reason is in the docstring of docs#Lean.withImportModules: "No live references to the environment object or imported objects may exist after act
finishes." In your case, the reference to the environment object is in ar.push name.toString
. Replacing that with ar.push name.toString.toName.toString
makes it work, I am guessing that s.toName.toString
is implemented sufficiently not-in-place, that it creates a new memory reference.
Yury G. Kudryashov (Mar 16 2025 at 14:13):
(note: I still don't understand why making a pure version of isAutoDecl
is a bad idea; e.g., this will make it clear that the function doesn't depend on other parts of the context, only on env
)
Last updated: May 02 2025 at 03:31 UTC