Zulip Chat Archive
Stream: new members
Topic: Confusion about use of "definitional equality" in FPIL
mars0i (Oct 13 2024 at 18:35):
From FPIL section 8.5:
def Nat.plusR : Nat → Nat → Nat
| n, 0 => n
| n, k + 1 => plusR n k + 1
and
def plusR_zero_left : (k : Nat) → k = Nat.plusR 0 k
| 0 => by rfl
| k + 1 => _
Then the book says:
The second placeholder is a bit trickier. The expression
Nat.plusR 0 k + 1
is definitionally equal toNat.plusR 0 (k + 1)
. This means that the goal could also be writtenk + 1 = Nat.plusR 0 k + 1
:
def plusR_zero_left : (k : Nat) → k = Nat.plusR 0 k
| 0 => by rfl
| k + 1 => (_ : k + 1 = Nat.plusR 0 k + 1)
My question is just about the claim that "Nat.plusR 0 k + 1
is definitionally equal to Nat.plusR 0 (k + 1)
." If these are definitionally equal, why can't we just write by rfl
in the rhs of the last line? I thought that's the kind of case that rfl
is for. But replacing the rhs of the last line with by rfl
produces:
tactic 'rfl' failed, the left-hand side
k + 1
is not definitionally equal to the right-hand side
Nat.plusR 0 (k + 1)
k : Nat
⊢ k + 1 = Nat.plusR 0 (k + 1)
The error message mentions Nat.plusR 0 (k + 1)
rather than Nat.plusR 0 k + 1
. I assume that's because rfl
sees those as definitionally equal, but modulo that, it's saying that the definitional equality claimed in the text doesn't exist, right?
Is there something I don't understand? Or is this a typo in FPIL? (If so I can report it, but I wanted to check first whether there's something I misunderstand--which is likely.)
Henrik Böving (Oct 13 2024 at 18:44):
k + 1 = Nat.plusR 0 k + 1
is provable with induction but not by definitional equality. The definitional equality here can only reduce further if the k
argument is a + 1
or a 0
which it isn't, it's k
. So you are stuck at this point if you only rely on defeq
Kyle Miller (Oct 14 2024 at 02:27):
It's true that Nat.plusR 0 k + 1
is definitionally equal to Nat.plusR 0 (k + 1)
. You can verify that with
example (k : Nat) : Nat.plusR 0 k + 1 = Nat.plusR 0 (k + 1) := rfl
Since rfl
doesn't work for k + 1 = Nat.plusR 0 (k + 1)
, the conclusion you should draw is that k + 1
is not definitionally equal to Nat.plusR 0 (k + 1)
.
Notice that in
def plusR_zero_left : (k : Nat) → k = Nat.plusR 0 k
| 0 => by rfl
| k + 1 => (by rfl : k + 1 = Nat.plusR 0 k + 1)
the error reports Nat.plusR 0 k + 1
. All rfl
does is report the LHS and RHS of what it sees. It won't reduce anything in the report.
mars0i (Oct 14 2024 at 18:01):
Thanks very much @Kyle Miller, @Henrik Böving for the patient explanations. I see now that I was confused, and not paying attention to details that were there in front of me.
I hadn't seen the syntax for adding a type signature to a by
expression. That's very helpful. (I'd also forgotten about example
.)
Kyle Miller (Oct 14 2024 at 18:24):
It turns out to be the same general type ascription syntax. Remember that by blah
is itself a term, so you can put it in place of e
in (e : ty)
.
mars0i (Oct 14 2024 at 18:49):
OK, I see. And in (by rw [Nat.add_comm]; rfl)
, I'd add the colon and type just before the closing parenthesis. I hadn't been sure about how to think about the full implications of the by
syntax.
Last updated: May 02 2025 at 03:31 UTC