Zulip Chat Archive
Stream: lean4
Topic: can an attribute access the Syntax of a decl?
David Renshaw (Sep 15 2023 at 03:09):
Attributes can see their own syntax: https://github.com/leanprover/lean4/blob/be977579821440a5529dc1c216fab58f854b2db8/src/Lean/Attributes.lean#L50-L51
Is there a way for attributes to see the syntax of the declarations that they decorate?
@[my_attribute]
def foo := 11
Like, I want my implementation of my_attribute
to have access to the Syntax
of def foo := 11
.
David Renshaw (Sep 15 2023 at 12:32):
The approach I've landed on is: I'm going to define my own attribute-like thing using slightly different syntax:
#[my_pseudoattribute]
def foo := 11
Then I can do anything I want in the elaboration of my_pseudoattribute
, including stashing the syntax of the decl that it adorns.
Henrik Böving (Sep 15 2023 at 15:18):
What do you want to do with the syntax? You can easily get access to the elaborated version through meta programming.
David Renshaw (Sep 15 2023 at 15:29):
This is for https://github.com/dwrensha/math-puzzles-in-lean4
I want the checked-in code for a problem to contain the full solution code, and I want to be able to extract problem-only versions of the code from that.
So I want to replace the bodies of certain definitions with sorry
.
David Renshaw (Sep 15 2023 at 15:32):
My pseudoattribute approach looks promising: I'll store source code spans for the code that I want to end up in the extracted file.
Eric Wieser (Sep 15 2023 at 15:33):
Note that MIL solves this via text processing and --SOLUTION
/--BOTH
markers
Joachim Breitner (Sep 15 2023 at 15:34):
Instead of an attribute, I'd probably implement this using a custom tactic and/or term elaborator, which stores the source code spans of it's argument. This way you could even hide only parts of a definition/proof.
(Not that I know how to do it, I'd just hope I would find out :-))
Eric Wieser (Sep 15 2023 at 15:34):
I would imagine that the #Lean for teaching stream has other solutions to this problem
David Renshaw (Sep 15 2023 at 15:35):
text processing sounds imprecise :)
Joachim Breitner (Sep 15 2023 at 15:35):
But yes, comments and regexes may be the better solution :sweat_smile:
David Renshaw (Sep 15 2023 at 15:35):
besides, I can't resist the opportunity to abuse Lean's metaprogramming facilities (and to learn more about them in the process)
Patrick Massot (Sep 15 2023 at 15:47):
The comments and python processing approach is clearly a hack and I would love to get rid of it in MIL.
David Renshaw (Sep 15 2023 at 19:55):
I got a basic version of my pseudo-attributes to work: https://github.com/dwrensha/math-puzzles-in-lean4/commit/86b0f57678c3e1e8790908b1319ec5aea458c739
David Renshaw (Sep 15 2023 at 19:56):
this dashboard is the result: https://dwrensha.github.io/math-puzzles-in-lean4/
David Renshaw (Sep 15 2023 at 19:56):
click on a problem name to get an extracted solution-less version of it
David Renshaw (Sep 15 2023 at 19:57):
click on the check or x-mark next to it to go to the source code, possibly containing a full solution
Mac Malone (Sep 16 2023 at 07:00):
@David Renshaw I would be worried about the fact that #[...]
clashes with the #[...]
used for Array
literals. I would suggest using @@[...]
or @[[...]]
instead.
David Renshaw (Sep 16 2023 at 11:41):
Fair point. @@[...]
looks good to me, though I am a bit sad about needing one extra keystroke
David Renshaw (Sep 16 2023 at 11:48):
alternative: %[...]
, where the percent sign stands for pseudo-attribute
Mac Malone (Sep 16 2023 at 17:57):
@David Renshaw Yeah, I considered %[...[
, my concern there is that if Lean, Std, etc. needs and other List/Array style literal in the future it may use %[...]
and the pseudo-attribute would then clash with it. Whereas, t is very unlikely add a @@[...]
/ @[[...]]
except for a similar purpose (and attribute variant).
Thomas Murrills (Sep 16 2023 at 20:09):
I might suggest @%[...]
, because %
usually connotes something to do with elaboration, and suggests that the @
tribute works “on the same level” as elaboration/has access to syntax
Mario Carneiro (Sep 16 2023 at 21:32):
I'd rather just use @[...]
and pass along the syntax
Mac Malone (Sep 16 2023 at 22:07):
@Mario Carneiro That cannot work in general. Attributes may (and are) applied in places where the syntax of the target is unavailable (e.g., attribute [foo] bar
).
Mac Malone (Sep 16 2023 at 22:13):
Though, looking into it more, in @David Renshaw's case, since the token he is using is the complete attribute (e.g., #[problem_statement]
), any of @[]
, #[]
, %[]
, etc. would work without clashing since that token will always take precedence.
Mario Carneiro (Sep 16 2023 at 22:44):
Mac Malone said:
Mario Carneiro That cannot work in general. Attributes may (and are) applied in places where the syntax of the target is unavailable (e.g.,
attribute [foo] bar
).
That seems fine, you would just pass the syntax of the command, whatever it is
Thomas Murrills (Sep 16 2023 at 23:00):
You could pass an Option Syntax
to make handling those “nonlocal” attribute applications easier on the person writing the attribute (so attribute [foo] bar
would pass none
, and you could easily throw an error)
David Renshaw (Sep 17 2023 at 13:04):
I got rid of my #[problem_statement]
pseudo-attribute and now instead have declared problem
to be a synonym of theorem
(similar to how Mathlib does this for lemma
): https://github.com/dwrensha/math-puzzles-in-lean4/commit/4115c93f3c03645420bc5dd84fccc160606416b2
David Renshaw (Sep 17 2023 at 13:06):
I intend to do something similar with #[solution_data]
, but it's less clear what to do with #[problem_setup]
, which can adorn any command (e.g. infix
, open
, ...).
James Gallicchio (Sep 17 2023 at 18:35):
is there a way you can use section
s?
David Renshaw (Sep 17 2023 at 19:01):
Maybe! That was in fact going to be my next line of investigation.
David Renshaw (Sep 17 2023 at 19:02):
something like problem_setup_section
gets included in an extracted problem, while everything else gets excluded by default
Last updated: Dec 20 2023 at 11:08 UTC