Zulip Chat Archive
Stream: new members
Topic: Function not equal to itself
𝚠𝚘𝚓𝚌𝚒𝚎𝚌𝚑 𝚗𝚊𝚠𝚛𝚘𝚌𝚔𝚒 (Nov 07 2024 at 22:31):
I am once again confused by definitional equality. The following function is not equal to its own definition by Eq.refl. What is going on? This is with Lean v4.14.0-rc1.
@[reducible] def g : Nat → Nat
  | 0 => 0
  | n+1 => g n
set_option pp.explicit true in
#print g
example :
    g =
    -- output of #print above
    (fun x ↦
      @Nat.brecOn (fun x ↦ Nat) x fun x f ↦
        g.match_1 (fun x ↦ @Nat.below (fun x ↦ Nat) x → Nat) x (fun a x ↦ @OfNat.ofNat Nat 0 (instOfNatNat 0))
          (fun n x ↦ x.1) f) :=
  Eq.refl _ -- type mismatch
Kyle Miller (Nov 07 2024 at 22:34):
Hmm, using delta to unfold g with its definition works:
example :
    g =
    -- output of #print above
    (fun x ↦
      @Nat.brecOn (fun x ↦ Nat) x fun x f ↦
        g.match_1 (fun x ↦ @Nat.below (fun x ↦ Nat) x → Nat) x (fun a x ↦ @OfNat.ofNat Nat 0 (instOfNatNat 0))
          (fun n x ↦ x.1) f) := by
  delta g
  rfl
Kyle Miller (Nov 07 2024 at 22:36):
It seems that smart unfolding is getting in the way. This works:
set_option smartUnfolding false
example :
    g =
    -- output of #print above
    (fun x ↦
      @Nat.brecOn (fun x ↦ Nat) x fun x f ↦
        g.match_1 (fun x ↦ @Nat.below (fun x ↦ Nat) x → Nat) x (fun a x ↦ @OfNat.ofNat Nat 0 (instOfNatNat 0))
          (fun n x ↦ x.1) f) :=
  rfl
𝚠𝚘𝚓𝚌𝚒𝚎𝚌𝚑 𝚗𝚊𝚠𝚛𝚘𝚌𝚔𝚒 (Nov 07 2024 at 22:38):
Oh, I thought if I write := Eq.refl _ that would get sent straight to the C++ kernel rather than the user-space typechecker. smartUnfolding does not affect the C++ kernel, right?
Kyle Miller (Nov 07 2024 at 22:43):
That still gets checked by the elaborator first. To skip, that, you'd have to write some term elaborator that doesn't do any checking.
Kyle Miller (Nov 07 2024 at 22:46):
Here's skipping the elaborator's type checking:
open Lean Meta
elab "rfl!" : term <= expectedType => do
  let some (_, lhs, _) := (← instantiateMVars expectedType).eq? | throwError "not eq"
  let pf ← Lean.Meta.mkEqRefl lhs
  mkExpectedTypeHint pf expectedType
example :
    g =
    (fun x ↦
      @Nat.brecOn (fun x ↦ Nat) x fun x f ↦
        g.match_1 (fun x ↦ @Nat.below (fun x ↦ Nat) x → Nat) x (fun a x ↦ @OfNat.ofNat Nat 0 (instOfNatNat 0))
          (fun n x ↦ x.1) f) :=
  rfl!
Kyle Miller (Nov 07 2024 at 22:47):
Apparently there's a rfl' tactic for doing rfl with smart unfolding turned off and allowing everything to be reduced
𝚠𝚘𝚓𝚌𝚒𝚎𝚌𝚑 𝚗𝚊𝚠𝚛𝚘𝚌𝚔𝚒 (Nov 07 2024 at 22:47):
Thanks! I know that cases where the elaborator-typechecker accepts something that the kernel rejects are considered bugs. Is the converse also?
Sebastian Ullrich (Nov 08 2024 at 07:22):
No, this is as intended
Last updated: May 02 2025 at 03:31 UTC