coq-club AT inria.fr
Subject: The Coq mailing list
List archive
- From: Gaëtan Gilbert <gaetan.gilbert AT skyskimmer.net>
- To: coq-club AT inria.fr
- Subject: Re: [Coq-Club] Universe Polymorphism
- Date: Fri, 9 Dec 2022 13:31:03 +0100
- Authentication-results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=gaetan.gilbert AT skyskimmer.net; spf=Pass smtp.mailfrom=gaetan.gilbert AT skyskimmer.net; spf=None smtp.helo=postmaster AT relay10.mail.gandi.net
- Ironport-data: A9a23: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
- Ironport-hdrordr: A9a23:LSkez6PYte2q28BcTsyjsMiBIKoaSvp037BZ7TETdfUzSL3+qy nOpoV+6faaslsssR0b6LK90ey7MBbhHP1OjbX5X43JYOCOggLBR72Kr7GD/9SKIUPDH4BmtJ uIP5IQNOHN
- Ironport-phdr: A9a23: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
- Ironport-sdr: 63932a88_luYZyJ05hpCPQT1XrcRQxG9rHlJfhe3O9m1Ssp+sbmYws1a L5R/Q3iYefw8ykMmtwixkHsFvlkMZkZAtELswuw==
>In order to get an inhabitant you would need a function which constructs
from an inhabitant of any type ‘A’ an inhabitant of ‘Ens’
There is a subtlety here: a constructor like "C : forall x, ..." inhabits the inductive
when there exists an "x", so the universal quantification turns into an existential
quantification.
So you do not need to inhabit for all A, but only for some A. Then as you
noted this can be started using A := False.
Gaëtan Gilbert
On 08/12/2022 22:06, Helmut Brandl wrote:
Thanks Amin,
I was looking for such an example. I have checked it with my installation of
coq and it is rejected without the ’type-in-type’ option and accepted with
the option. Excellent, thanks.
As opposed to the other examples which I have seen up to now, your example
has a size that one has a chance to understand it mentally.
However I am struggling in mentally understanding the example. The type ‘Ens’
seems to be uninhabited. In order to get an inhabitant you would need a
function which constructs from an inhabitant of any type ‘A’ an inhabitant of
‘Ens’ without having an inhabitant in the first place. For me this seems to
be possible only for uninhabited types like ‘False’ but nor for all types.
Could you explain a little bit the basic idea of your construction and the
helper functions you have used.
Regards
Helmut
On 8 Dec 2022, at 18:44, Amin Timany <amintimany AT gmail.com> wrote:
Dear Helmut,
Perhaps the following counterexample can be helpful which directly constructs
"the set of all sets that are not elements of themselves” as in Russel’s
paradox. (I checked this example with Coq version 8.15.2 with the “-type-in-type”
option.)
Inductive Ens@{i} : Type@{i} :=
ens_intro : forall A : Type@{i+1}, (A -> Ens) -> Ens.
Definition idx (A : Ens) : Type := match A with ens_intro T _ => T end.
Definition elem (A : Ens) (i : idx A) : Ens :=
match A as u return idx u -> Ens with ens_intro B f => fun j => f j end i.
Definition elem_of (x A : Ens) := exists a, elem A a = x.
Definition Union {T} (f : T -> Ens) :=
ens_intro {x : T & idx (f x)} (fun u => elem (f (projT1 u)) (projT2 u)).
Lemma elem_of_union {T} (f : T -> Ens) A : elem_of A (Union f) <-> exists t,
elem_of A (f t).
Proof.
split.
- intros [[z idx] Hzidx]; exists z, idx; assumption.
- intros [z [idx Hzidx]]; exists (existT _ z idx); assumption.
Qed.
Definition singleton_if (a : Ens) (P : Prop) : Ens := ens_intro {x : unit | P}
(fun _ => a).
Lemma elem_of_singleton_if a b P : (P /\ a = b) <-> elem_of b (singleton_if a
P).
Proof.
split.
- intros [HP ->].
exists (exist _ tt HP); reflexivity.
- intros [[z Hz1] Hz2]; tauto.
Qed.
Definition Russel : Ens := Union (fun A : Ens => singleton_if A (not (elem_of
A A))).
Theorem Russel's_Paradox : elem_of Russel Russel <-> not (elem_of Russel
Russel).
Proof.
split.
- intros Helem.
apply elem_of_union in Helem as [t Ht].
apply elem_of_singleton_if in Ht as [? ->].
assumption.
- intros Hnelem.
apply elem_of_union.
exists Russel.
apply elem_of_singleton_if; split; [assumption|reflexivity].
Qed.
Regards,
Amin
On 17 Nov 2022, at 12.05, Helmut Brandl <helmut.brandl AT gmx.net> wrote:
Thanks Gaëtan for your effort and your patience with my questions.
However the situation remains somehow unsatisfactory. By reading and
rereading the documentation I cannot find a clear rule which states what is
allowed and what is not allowed with respect to universes. As opposed to
that, the positivity condition is stated very clearly and to my surprise, the
justification of the positivity rule is explained with some examples which
are short and to the point.
My intuitive explanation with the “hiding” of a higher universe type within a
lower universe inductive definition might be correct. But it is not very
precise and does not give a justification. Furthermore the example of the
existential quantification does give a constraint on the universes without
explaining the general rule.
Sorry for me insisting on this topic. Maybe it cannot be resolved easily.
Anyhow thanks for your efforts.
Helmut
On 17 Nov 2022, at 11:12, Gaëtan Gilbert <gaetan.gilbert AT skyskimmer.net>
wrote:
Unfortunately I have not found the rule that every argument of a constructor
must be at a smaller or equal universe to the output universe
I can't find it either although it's mentioned, eg
One can remark that there is a constraint between the sort of the arity of
the inductive type and the sort of the type of its constructors which will
always be satisfied for the impredicative sorts SProp and Prop but may fail
to define inductive type on sort Set and generate constraints between
universes for inductive types in the Type hierarchy.
Probably a doc bug.
The reason for the rule is basically what you said earlier
I suspect that if it were well typed, then I could ‘hide’ an object from the
universe ‘u+1’ in the list which resides in the universe ‘u’.
which leads to inconsistency. See also
https://coq.inria.fr/distrib/current/stdlib/Coq.Logic.Hurkens.html and
mentioned references.
Gaëtan Gilbert
On 17/11/2022 10:45, Helmut Brandl wrote:
On 16 Nov 2022, at 23:35, Gaëtan Gilbert <gaetan.gilbert AT skyskimmer.netThanks for the explanation. I have tried to read the description in the link.
<mailto:gaetan.gilbert AT skyskimmer.net>> wrote:
The rules for inductives
https://coq.github.io/doc/master/refman/language/core/inductive.html#theory-of-inductive-definitions
<https://coq.github.io/doc/master/refman/language/core/inductive.html#theory-of-inductive-definitions>
basically every argument of a constructor must be at a smaller or equal
universe to the output universe of the inductive. The first argument of cons
fails this.
Unfortunately I have not found the rule that every argument of a constructor
must be at a smaller or equal universe to the output universe. Could you
point to the specific paragraph which states that rule. Since the rules are
very technical I might have overlooked it.
My intention is to understand not only the “what” of the rules, but also the
“why” of the rules. What is the justification of such a rule? E.g. first I
didn’t understand the necessity of the positivity rule of the constructor
types. Then I have found an example which makes the necessity of the
positivity rule clear. If the following inductive type were allowed
Inductive T: Type :=
| co: (T -> T) -> T.
I could define a fixpoint with infinite recursion
Fixpoint run (t: T): T :=
match t with
| co f => run (f (co f))
end.
Is there a similar justification for the rule you have mentioned? Does the
rule inhibit an inconsistency like infinite recursion?
— Helmut
Gaëtan Gilbert
On 16/11/2022 22:32, Helmut Brandl wrote:
On 16 Nov 2022, at 22:06, Helmut Brandl <helmut.brandl AT gmx.netAccording to coq the type ’Type@{u+1} -> Type@{u}’ can have inhabitants. E.g.
<mailto:helmut.brandl AT gmx.net> <mailto:helmut.brandl AT gmx.net
<mailto:helmut.brandl AT gmx.net>>> wrote:
On 16 Nov 2022, at 21:23, Gaëtan Gilbert <gaetan.gilbert AT skyskimmer.net
<mailto:gaetan.gilbert AT skyskimmer.net> <mailto:gaetan.gilbert AT skyskimmer.net
<mailto:gaetan.gilbert AT skyskimmer.net>>> wrote:
I.e. the argument type of a function type can live in a higher universe than
the result type.
Yes, but "lst" is an _inhabitant_ of the function type, it's not the function
type itself.
Similarly "(fun A:Type@{u+1} => A) : Type@{u+1} -> Type@{u}" is rejected
In that case the rejection is clear to me. The term ‘A’ has type
’Type@{u+1}’. Therefore the function returns a result of type ’Type@{u+1}’
and not ’Type@{u}’ as required by the type annotation. I.e. the function on
the left hand side of the colon is not an inhabitant of the type on the right
hand side of the colon. The compiler must reject it.
Are you saying that the type ’Type@{u+1} -> Type@{u}’ is not allowed to be
inhabited? Is there such a typing rule? If there is such a typing rule, I would
like to understand why it is there. Does the violation of such a typing rule
create any inconsistencies like an inhabitant of the type ‘forall A: Type, A’?
the following is accepted by coq:
Check (fun A: Type@{u+1} => nat): Type@{u+1} -> Type@{u}.
However my construction of the inductive type ‘lst’ which is an inhabitant of
exactly that type is rejected. Why is it possible to construct a function of
that type but not an inductive definition?
— Helmut
On 16/11/2022 21:02, Helmut Brandl wrote:
I’d like to understand universes and universe polymorphism better. Therefore
I have some questions:
The following term is well typed in coq:
Universe u.
Check forall A:Type@{u+1}, Type@{u}.
I.e. the argument type of a function type can live in a higher universe than
the result type. If I try the same with an inductive type, I get an error.
Inductive lst (A: Type@{u+1}): Type@{u} :=
| nil: lst A
| cons: A -> lst A -> lst A.
*Error:*Universe inconsistency. Cannot enforce u = max(Set, u+1).
What is the theoretical background of this consistency error. The type of
‘lst’ is exactly the type I have checked above as well typed. I suspect that
if it were well typed, then I could ‘hide’ an object from the universe ‘u+1’
in the list which resides in the universe ‘u’. Can anybody help to give a
more precise explanation.
Regards
Helmut
- Re: [Coq-Club] Universe Polymorphism, Amin Timany, 12/08/2022
- Re: [Coq-Club] Universe Polymorphism, Helmut Brandl, 12/08/2022
- Re: [Coq-Club] Universe Polymorphism, Sylvain Boulmé, 12/09/2022
- Re: [Coq-Club] Universe Polymorphism, Gaëtan Gilbert, 12/09/2022
- Re: [Coq-Club] Universe Polymorphism, Helmut Brandl, 12/08/2022
Archive powered by MHonArc 2.6.19+.