Open digama0 opened 1 year ago
I have a workaround for this issue (see commits above), but I think we should not merge them into master. It silently ignores the protected
annotation and treats it as a private
one if isPrivateName name
is true.
The test
command above also looks fishy. For example, suppose we write
namespace Bla.Boo
inductive Foo : Type
test Foo
end Bla.Boo
It will generate the declaration
Bla.Boo.Bla.Boo.Foo.ext
We can avoid the issue by writing test
as follows
import Lean
open Lean
macro "test" x:ident : command => do
let [(name, _)] ← Macro.resolveGlobalName x.getId | Macro.throwUnsupported
let name := privateToUserName? name |>.getD name
`(protected theorem $(mkIdent (`_root_ ++ (name.mkStr "ext"))):ident : True := trivial)
inductive A : Type
test A
#print A.ext
private inductive B : Type
test B
#print B.ext
namespace Ns
private inductive C : Type
test C
#print C.ext
end Ns
namespace Bla.Boo
inductive Foo : Type
test Foo
#print Foo.ext
Note that in the example above B.ext
is not a private declaration, but a protected
one. If we want to force B.ext
to be private when B
is private, then we can write test
as follows.
import Lean
open Lean
macro "test" x:ident : command => do
let [(name, _)] ← Macro.resolveGlobalName x.getId | Macro.throwUnsupported
if let some name := privateToUserName? name then
`(private theorem $(mkIdent (`_root_ ++ (name.mkStr "ext"))):ident : True := trivial)
else
`(protected theorem $(mkIdent (`_root_ ++ (name.mkStr "ext"))):ident : True := trivial)
inductive A : Type
test A
#print A.ext
private inductive B : Type
set_option trace.Elab.definition true in
test B
#print B.ext
namespace Ns
private inductive C : Type
set_option trace.Elab.definition true in
test C
#print Ns.C.ext
end Ns
namespace Bla.Boo
inductive Foo : Type
test Foo
#print Foo.ext
@digama0 I am planning to close this issue because the solutions above look satisfactory to me.
Dev meeting summary: use macro scopes for encoding private names. We will need to adapt the name resolution.
This is a simplified version of an issue with the
ext
attribute from mathlib, which attempts to create a protected declaration in the same namespace as the input type name. (It would also be nice to implement this as a macro; I think I know how to work around this as anelab
.) When the type is private, this essentially amounts to elaborating a command like:and the declaration parser gets very confused by this identifier. Ideally, this would just work and create a private declaration which is also protected, in the sense that you can refer to it by the name
B.ext
but notext
. I believe the knock-on error aboutinvalid scope
is because the declaration elaborator expanded to anamespace 0
which isn't valid.