Zulip Chat Archive
Stream: lean4
Topic: rfl tactic without a macro
Joachim Breitner (Feb 10 2024 at 19:17):
Right now, the rfl
tactic is a macro that tries (once you load std4) exact HEq.rfl
, exact Iff.rfl
and then docs#Lean.MVarId.refl. A consequence of this implementation is that the the error message isn’t beginner friendly (talks about Iff.rfl
or HEq.rfl
), and maybe it is a tad slower than it needs to be when using the general macro/exact
machinery.
Since Iff
and HEq
are both in Core, I wonder whether it would make sense to simply teach docs#Lean.MVarId.refl (or a variant thereof) to support all these three relations directly. This might make it (a bit) faster (not sure how important that is, maybe rfl
is used within other tactics a lot?) and have a better error message when it fails.
Mario Carneiro (Feb 10 2024 at 19:19):
This might be fixed in the near future since lots of std tactics are getting upstreamed to core
Joachim Breitner (Feb 10 2024 at 19:21):
Indeed, seeing the upstreaming PR of Iff.rfl
and the error message regression is what made me ponder this question.
Joachim Breitner (Feb 10 2024 at 19:21):
So assuming all functionality is in core, is the macro_rule
based implementation or the single-MetaM
-function implementation preferrable?
Mario Carneiro (Feb 10 2024 at 19:33):
I would say single MetaM function
Mario Carneiro (Feb 10 2024 at 19:33):
certainly it makes it easier to fix the error messages
Mario Carneiro (Feb 10 2024 at 19:34):
plus the relation rfl tactic (using @[refl]
theorems) already subsumes all of the others
Joachim Breitner (Feb 10 2024 at 19:35):
Is that a separate tactic? (I thought something like this would exist, but didn't find it right away)
Joachim Breitner (Feb 10 2024 at 19:36):
Ah, found it. The macro_rules
line isn’t on the same line as rfl
and escaped my grepping :-).
Looks like the macro and attribute is defined in std4, but almost most attribute assignments are in Mathlib, including those duplicating that macro_rules
with exact Heq.rfl
and Iff.rfl
. Hmm. Maybe I’ll wait for the upstreaming storm to settle before barging into this area :-)
Joachim Breitner (Feb 10 2024 at 19:40):
BTW, the error message for
import Std
example P := by rfl
is
don't know how to synthesize implicit argument
@HEq.rfl (?m.16 P) (?m.17 P)
context:
P: ?m.2
⊢ ?m.16 P
:man_facepalming:
Joachim Breitner (Feb 10 2024 at 19:40):
A bit better with
import Std
example (P : Prop) : P := by rfl
but not much:
type mismatch
HEq.rfl
has type
HEq ?m.10 ?m.10 : Prop
but is expected to have type
P : Prop
Mario Carneiro (Feb 10 2024 at 19:46):
The first one looks like a mistake, presumably you wanted a colon before P
Mario Carneiro (Feb 10 2024 at 19:47):
I think this is one reason not to allow unparenthesized binders, they are much more likely to be typos of either the result type or the theorem name
Joachim Breitner (Feb 10 2024 at 20:12):
Fair enough.
BTW, is there a way to query the registered macro rules? I.e. list all rules that apply to a given syntax term?
Mario Carneiro (Feb 10 2024 at 20:13):
#help tactic
is similar but doesn't cover individual macro rules
Mario Carneiro (Feb 10 2024 at 20:22):
Oh, this is already implemented as
import Mathlib.Tactic.HelpCmd
#help tactic+ trivial
syntax "trivial"... [Lean.Parser.Tactic.tacticTrivial]
`trivial` tries different simple tactics (e.g., `rfl`, `contradiction`, ...)
to close the current goal.
You can use the command `macro_rules` to extend the set of tactics used. Example:
```
macro_rules | `(tactic| trivial) => `(tactic| simp)
```
+ macro Lean.Parser.Tactic._aux_Init_Tactics___macroRules_Lean_Parser_Tactic_tacticTrivial_6
+ macro Lean.Parser.Tactic._aux_Init_Tactics___macroRules_Lean_Parser_Tactic_tacticTrivial_5
+ macro Lean.Parser.Tactic._aux_Init_Tactics___macroRules_Lean_Parser_Tactic_tacticTrivial_4
+ macro Lean.Parser.Tactic._aux_Init_Tactics___macroRules_Lean_Parser_Tactic_tacticTrivial_3
+ macro Lean.Parser.Tactic._aux_Init_Tactics___macroRules_Lean_Parser_Tactic_tacticTrivial_2
+ macro Lean.Parser.Tactic._aux_Init_Tactics___macroRules_Lean_Parser_Tactic_tacticTrivial_1
The constant names are go-to-def-able (unfortunately I couldn't find a less noisy way to do that in the current infoview)
Joachim Breitner (Feb 11 2024 at 21:36):
Mario Carneiro said:
I would say single MetaM function
JFTR: escalated this to an RFC at https://github.com/leanprover/lean4/issues/3302
Last updated: May 02 2025 at 03:31 UTC