lean4-htt/tests/lean/run/rflReducibility.lean
Joachim Breitner a3ca15d2b2
refactor: back rfl tactic primarily via apply_rfl (#3718)
building upon #3714, this (almost) implements the second half of #3302.

The main effect is that we now get a better error message when `rfl`
fails. For
```lean
example : n+1+m = n + (1+m) := by rfl
```
instead of the wall of text
```
The rfl tactic failed. Possible reasons:
- The goal is not a reflexive relation (neither `=` nor a relation with a @[refl] lemma).
- The arguments of the relation are not equal.
Try using the reflexivity lemma for your relation explicitly, e.g. `exact Eq.refl _` or
`exact HEq.rfl` etc.
n m : Nat
⊢ n + 1 + m = n + (1 + m)
```
we now get
```
error: tactic 'rfl' failed, the left-hand side
  n + 1 + m
is not definitionally equal to the right-hand side
  n + (1 + m)
n m : Nat
⊢ n + 1 + m = n + (1 + m)
```

Unfortunately, because of very subtle differences in semantics (which
transparency setting is used when reducing the goal and whether the
“implicit lambda” feature applies) I could not make this simply the only
`rfl` implementation. So `rfl` remains a macro and is still expanded to
`eq_refl` (difference transparency setting) and `exact Iff.rfl` and
`exact HEq.rfl` (implicit lambda) to not break existing code. This can
be revised later, so this still closes: #3302.

A user might still be puzzled *why* to terms are not defeq. Explaining
that better (“reduced to… and reduces to… etc.”) would also be great,
but that’s not specific to `rfl`, so better left for some other time.
2024-09-25 10:34:42 +00:00

25 lines
566 B
Text

/-!
The (attribute-extensible) `rfl` tactic only unfolds the goal with reducible transparency to look
for a relation which may have a `refl` lemma associated with it. But historically, `rfl` also
invoked `eq_refl`, which more aggressively unfolds. This checks that this still works.
-/
def Foo (a b : Nat) : Prop := a = b
/--
error: tactic 'rfl' failed, no @[refl] lemma registered for relation
Foo
⊢ Foo 1 1
-/
#guard_msgs in
example : Foo 1 1 := by
apply_rfl
#guard_msgs in
example : Foo 1 1 := by
eq_refl
#guard_msgs in
example : Foo 1 1 := by
rfl