Zulip Chat Archive
Stream: Type theory
Topic: kernel is_def_eq confusion
Leonard Wigman (Aug 16 2023 at 15:18):
1) i was looking through lean's kernel code and was surprised to find that, apparently, is_def_eq
(which is mostly just a wrapper for is_def_eq_core
) doesn't seem to unfold definitions.
near the bottom of the function, a comment claims "At this point, t_n and s_n are in weak head normal form (modulo metavariables and proof irrelevance)", even though there are only calls to whnf_core
, which doesn't unfold definitions.
(i don't quite understand that comment about proof irrelevance either, as is_def_eq_proof_irrel(t_n, s_n)
was checked above.)
does the front-end unfold definitions before passing terms to the kernel, or am i missing something? (that would be odd, given that not all definitions need to be unfolded.)
it seems, without unfolding, is_def_eq("a.succ", "a + 1")
would return false.
2) the code, that handles def-eq of constants, only returns true, if the terms are the same constant and the levels are def-eq. why can't this return false
, if the terms are the same constants, but the levels are not def-eq (ie if same_constants(a, b) { return levels_eq(a.levels, b.levels) }
)?
(3: is this actually the right channel for this question? :D)
for context: i stumbled upon this, cause i was trying to figure out what @[reducible]
meant. i remembered something like "that's used by the elaborator, the kernel can unfold all definitions".
Mario Carneiro (Aug 16 2023 at 16:26):
@Leonard Wigman
(1) although I'm not entirely sure by looking at the code, I am certain that is_def_eq_core
does in fact unfold definitions, and actually unfold_definition
it is reachable in several places from that function. I would have to test it with a basic example like a.succ =?= a + 1
to be sure.
(2) No that would not be correct, because you could have def Foo.{u} : Type := Unit
and then Foo.{1}
and Foo.{2}
are defeq.
(3) I don't think it is, #lean4 or #lean4 dev seems like a better place to get authoritative answers about this from devs.
Leonard Wigman (Aug 16 2023 at 16:58):
@Mario Carneiro, thanks!
1) oh, i completely missed r = lazy_delta_reduction(t_n, s_n);
, that would explain it :^)
2) i'm not sure i understand. for Foo.{1}
and Foo.{2}
, the const Foo
would be the same. then returning is_def_eq(const_levels(t_n), const_levels(s_n))
would return false
, because level 1
is not equivalent to 2
:thinking:
to be clear, i'm proposing:
// old
if (is_constant(t_n) && is_constant(s_n) && const_name(t_n) == const_name(s_n) &&
is_def_eq(const_levels(t_n), const_levels(s_n)))
return true;
// new
if (is_constant(t_n) && is_constant(s_n) && const_name(t_n) == const_name(s_n))
return is_def_eq(const_levels(t_n), const_levels(s_n));
3) okay, i'll use #lean4 next time :ok:
Mario Carneiro (Aug 16 2023 at 17:50):
2) i'm not sure i understand. for Foo.{1} and Foo.{2}, the const Foo would be the same. then returning is_def_eq(const_levels(t_n), const_levels(s_n)) would return false, because level 1 is not equivalent to 2
Right, I'm saying that false
is the wrong answer, because Foo.{1}
and Foo.{2}
are defeq
Mario Carneiro (Aug 16 2023 at 17:51):
we need to proceed to the rest of the function to do the unfolding work, because the answer could be true
, and is in this case
Leonard Wigman (Aug 16 2023 at 20:21):
because
Foo.{1}
andFoo.{2}
are defeq
oh interesting!
i just assumed definitions were injective, which they of course aren't.
which means, i also have a bug in my c1 args1 =?= c2 args2
code, whoops :D
i should probably go over the typing rules again. i think i assumed, if i fail to show the premises of a rule, the terms are not def-eq. but it's more like the rules "induce" the def-eq terms, so all rules have to fail.
Last updated: Dec 20 2023 at 11:08 UTC