This PR makes the equational theorems of non-exposed defs private. If the author of a module chose not to expose the body of their function, then they likely don't want that implementation to leak through equational theorems. Helps with #8419. There is some amount of incidential complexity due to how `private` works in lean, by mangling the name: lots of code paths that need now do the right thing™ about private and non-private names, including the whole reserved name machinery. So this includes a number of refactorings: * The logic for calculating an equational theorem name (or similar) is now done by a single function, `mkEqLikeNameFor`, rather than all over the place. * Since the name of the equational theorem now depends on the current context (in particular whether it’s a proper module, or a non-module file), the forward map from declaration to equational theorem doesn’t quite work anymore. This map is deleted; the list of equational theorems are now always found by looking for declaration of the expected names (`alreadyGenerated). If users define such theorems themselves (and make it past the “do not allow reserved names to be declared”) they get to keep both pieces. * Because this map was deleted, mathlib’s `eqns` command can no longer easily warn if equational lemmas have already been generated too early (adaption branch exists). But in general I think lean could provide a more principled way of supporting custom unfold lemmas, and ideally the whole equational theorem machinery is just using that. * The ReservedNamePredicate is used by `resolveExact`, so we need to make sure that it returns the right name, including privateness. It is not ok to just reserve both the private and non-private name but then later in the ReservedNameAction produce just one of the two. * We create `foo.def_eq` eagerly for well-founded recursion. This is needed because we need feed in the proof of the rewriting done by `wf_preprocess`. But if `foo.def_eq` is private in a module, then a non-module importing it will still expect a non-private `foo.def_eq` to exist. To patch that, we install a `copyPrivateUnfoldTheorem : GetUnfoldEqnFn` that declares a theorem aliasing the private one. Seems to work.
27 lines
1,022 B
Text
27 lines
1,022 B
Text
import Lean
|
|
import Module.Basic
|
|
import Module.Imported
|
|
import Module.ImportedAll
|
|
import Module.ImportedPrivateImported
|
|
import Module.PrivateImported
|
|
import Module.ImportedAllPrivateImported
|
|
import Module.NonModule
|
|
|
|
/-! # Module system basic tests -/
|
|
|
|
open Lean
|
|
|
|
/-! Non-essential metadata should only be accessible at level >= .server -/
|
|
|
|
#eval show IO Unit from do
|
|
let env ← importModules (level := .exported) #[`Module.Basic] {}
|
|
assert! env.header.isModule
|
|
let _ ← Core.CoreM.toIO (ctx := { fileName := "module.lean", fileMap := default }) (s := { env }) do
|
|
assert! (← findDeclarationRanges? ``f).isNone
|
|
assert! (getModuleDoc? (← getEnv) `Module.Basic).any (·.size == 0)
|
|
|
|
#eval show IO Unit from do
|
|
let env ← importModules (level := .server) #[`Module.Basic] {}
|
|
let _ ← Core.CoreM.toIO (ctx := { fileName := "module.lean", fileMap := default }) (s := { env }) do
|
|
assert! (← findDeclarationRanges? ``f).isSome
|
|
assert! (getModuleDoc? (← getEnv) `Module.Basic).any (·.size >= 1)
|