Zulip Chat Archive
Stream: new members
Topic: Inductive decls
Keeley Hoek (May 31 2019 at 08:00):
Why is it illegal to declare
inductive foo | mk (f : foo → ℕ)
Keeley Hoek (May 31 2019 at 08:01):
whereas
inductive foo' | mk (f : ℕ → foo')
is fine?
Keeley Hoek (May 31 2019 at 08:01):
Is there an (easy?) proof of false?
Edward Ayers (May 31 2019 at 08:23):
I think the first problem is that it's not clear what the recursor should be.
Kenny Lau (May 31 2019 at 08:24):
yeah I was thinking about that.
Edward Ayers (May 31 2019 at 08:25):
And then all of the sensible definitions of rec
let you make infinite descending terms. edit: or derive false or something.
Edward Ayers (May 31 2019 at 08:27):
The thing to look up is called "strict positivity"
Rob Lewis (May 31 2019 at 08:32):
It's easy enough to adapt examples like this one: https://cstheory.stackexchange.com/questions/14415/guarded-negative-occurrences-in-definition-of-inductive-types-always-bad
constant foo : Type constant mk {α} (f : foo → α) : foo constant inj {α} : Π x : foo, {f : foo → α // x = mk f} noncomputable def self_app {α} (a : foo) : α := let ⟨f, hf⟩ := inj a in f a noncomputable def ta {α} (nf : α → α) : α := self_app $ mk $ λ a, nf $ self_app a example : false := ta id
Keeley Hoek (May 31 2019 at 08:42):
Awesome! Thanks for the demo.
If I make mk
increase universe level by one the demo fails;
universe u constant foo : Type u constant mk {α} (f : foo.{u} → α) : foo.{u + 1} constant inj {α} : Π x : foo, {f : foo → α // x = mk f} noncomputable def self_app {α} (a : foo) : α := let ⟨f, hf⟩ := inj a in f a noncomputable def ta {α} (nf : α → α) : α := self_app $ mk $ λ a, nf $ self_app a example : false := ta id
Am I safe now? If so, is there any way to make lean build this?
Rob Lewis (May 31 2019 at 08:58):
universe u constant foo : Type u constant mk {α} (f : foo.{u} → α) : foo.{u + 1} constant inj {α} : Π x : foo, {f : foo → α // x = mk f} noncomputable def self_app {α} (a : foo) : α := let ⟨f, hf⟩ := inj (mk $ λ _, trivial) in f a noncomputable def ta {α} (nf : α → α) : α := self_app $ mk $ λ a, nf $ self_app a example : false := ta id
Keeley Hoek (May 31 2019 at 09:27):
Actually, I'm not quite sure I understand---why is \alpha
free to vary in those axioms? If I force \alpha
to be \nat
, can it work?
Mario Carneiro (May 31 2019 at 09:30):
the short answer is "no, this type violates cantor's theorem"
Mario Carneiro (May 31 2019 at 09:35):
I agree that something is funny in Rob's example. We don't need ta
, it's already a contradiction in self_app
if we instantiate alpha
as false
Mario Carneiro (May 31 2019 at 09:36):
and also self_app
isn't diagonalizing in the second version
Rob Lewis (May 31 2019 at 09:37):
Yeah, I just copied it from the StackOverflow answer, I'm sure there are shorter ways.
Mario Carneiro (May 31 2019 at 09:38):
I would guess that you are actually safe if mk
bumps the universe, but this is not the sort of definition lean can handle. It's recursive in a weird way - foo.{n+1}
is defined in terms of foo.{n}
Mario Carneiro (May 31 2019 at 09:41):
Rob, I think that inj
is not a reasonable axiom - if you just look at inj
it says foo -> foo -> A
for all A
Rob Lewis (May 31 2019 at 09:41):
Oh, wait, I see what you're saying.
Rob Lewis (May 31 2019 at 09:41):
Heh, we just had our coffee break and it's kicking in now.
Rob Lewis (May 31 2019 at 09:43):
You're right, that's too strong. But I'm not convinced that bumping the universe saves you, could you explain?
Mario Carneiro (May 31 2019 at 09:44):
you have to have a fixed alpha, like Keeley says
Mario Carneiro (May 31 2019 at 09:44):
right now you can use mk
with one alpha
and inj
with another - and that's actually what you are doing in the proof, you use mk
with true
and inj
with false
Mario Carneiro (May 31 2019 at 09:45):
Imagine you could just define foo.{u+1} := foo.{u} -> nat
, that would satisfy all the axioms
Mario Carneiro (May 31 2019 at 09:46):
it's not really recursive, since for each fixed u it's a finite number of arrows
Mario Carneiro (May 31 2019 at 09:47):
in fact such a type probably even exists, since Set.{u}
grows faster than foo.{u}
Mario Carneiro (May 31 2019 at 09:54):
Thinking about it more carefully, I think this is not definable. If it was, then we could define level.{u} : nat
which is equal to u
as a nat
Mario Carneiro (May 31 2019 at 09:56):
Set.{u}
almost lets you define level
, but you can only guarantee u
or more inaccessible cardinals in it. There is a sort of cardinal collapsing property here - the theory can't tell if you just take one of the Type u
universes out and shift the indexes of everything else down
Keeley Hoek (May 31 2019 at 09:57):
Looking at Set
more than I have before, it seems like the way to get around having a foo -> Prop
is choosing an indexing type \alpha
and looking at maps \alpha -> foo
instead. Since you can choose the indexing type as large as you want, isn't there some sort of bijection between these two pieces of data?
Mario Carneiro (May 31 2019 at 09:58):
that's why Set
lives in a higher universe
Keeley Hoek (May 31 2019 at 09:58):
(modulo a quotient of such maps by permutations of the indexing type and change of indexing type)
Mario Carneiro (May 31 2019 at 09:58):
you can't instantiate Set.{u}
with Set.{u}
as the index type
Keeley Hoek (May 31 2019 at 10:00):
For sure
Mario Carneiro (May 31 2019 at 10:01):
so you don't get a cantor contradiction, instead you just end up proving that Set.{u}
is (a lot) smaller than Set.{u+1}
Keeley Hoek (May 31 2019 at 12:21):
Regarding your comments on level
, why would it be bad if level.{u} : nat
existed?
Keeley Hoek (May 31 2019 at 12:21):
(Sorry for using you to learn about type theory)
Floris van Doorn (May 31 2019 at 19:05):
(deleted)
Mario Carneiro (May 31 2019 at 19:09):
@Keeley Hoek It wouldn't necessarily be bad if level.{u}
existed, but I'm pretty sure it's independent
Floris van Doorn (May 31 2019 at 19:10):
(oops, I replied to the wrong thread)
Last updated: Dec 20 2023 at 11:08 UTC