[Agda] slightly wrong sized datatype definition leads to proof of False

Frédéric Blanqui frederic.blanqui at inria.fr
Tue Oct 20 12:15:23 CEST 2020


Hi.

Where can I find the definitions of Size and Size<? 
https://github.com/agda/agda-stdlib/blob/master/src/Size.agda imports 
Agda.Builtin.Size but I don't know where to find this module. (Sorry, I 
am not familiar with Agda.)

A comment in this page says that: SizeUniv is a sort, Size:SizeUniv and 
Size<:Size->SizeUniv. Is SizeUniv typable, and what is the type of 
Size->SizeUniv? In other words, what are the PTS axioms and rules for 
the sort SizeUniv?

However, 
https://agda.readthedocs.io/en/v2.6.1.1/language/built-ins.html#sized-types 
says that SizeUniv:SizeUniv, which doesn't seem like a good idea in a 
type system, and Size<:..Size->SizeUniv. I don't know what is ..Size.

Thanks for your help.

Frédéric.

Le 20/10/2020 à 11:09, vlad a écrit :
> Thanks again for the answer. All this is very informative. It does IMO 
> deserve to be properly documented, in papers and in the tool, since it 
> contradicts the usual discourse that  inductive types should be 
> defined using data, coinductive types should be defined using records, 
> and sizes are just a way to ensure termination/productivity. Hopefully 
> all this will be clarified (and the corresponding soundness bugs will 
> be fixed) in a future release. When this happens I'll be happy to use 
> Agda again.
>
> On 20/10/2020 10:37, Andrea Vezzosi wrote:
>> Using sizes as freely as Agda allows, the distinction between data and
>> codata gets quite blurred, but that does not necessarily lead to an
>> unsound system.
>>
>> The fact that _<_ is not well-founded on sizes is what is unsound, and
>> I argue also agda refuting cycles in your  ℕ {∞}.
>>
>> Regarding Acc,  It's true that for any specific size "Acc s"
>> corresponds to "s" being accessible. But then  well-foundedness of _<_
>> implies `Acc s` is equivalent to the unit type for any `s`, so any two
>> elements you define in it are going to be equal.
>>
>> Regarding how your `ℕ` can be the (sized) conatural numbers, my point
>> is that for the functor F
>>
>>   F : (Size -> Set) -> Size -> Set
>>   F X i = Maybe ((j : Size< i) -> X j)
>>
>> the least and greatest fixed points coincide, so whether you construct
>> it with "data" or a coinductive record it does not make a difference.
>> You'll get a `ℕ : Size -> Set` which can be shown to be antitone in
>> the size.
>>
>> I would agree that it's a bit of an obscure interaction though, and
>> might deserve a warning.
>>
>> On Mon, Oct 19, 2020 at 6:22 PM vlad <Vlad.Rusu at inria.fr> wrote:
>>> Thank you for the reply. Hmm, there are some things I don't understand.
>>>
>>> On 19/10/2020 17:05, Andrea Vezzosi wrote:
>>>> The issue here is only incidentally about sized types. but rather an
>>>> issue with the check for when an absurd pattern (i.e. "()") is
>>>> allowed:
>>>>
>>>> https://github.com/agda/agda/issues/4995
>>> Unlike that issue I do not use a postulate but I am using sized types,
>>> so how can my issue only incidentally be about sized types?
>>>> Btw, the type you defined is more like co-natural numbers, i.e. with
>>>> an extra point at infinity, so it's quite natural to have a fix-point
>>>> for `suc`.
>>> Ok, perhaps the notation is confusing. If I syntactically rewrite the
>>> definition
>>>
>>> data  ℕ {s : Size} :  Set where
>>>     zero :  ℕ
>>>     suc : ({s' : Size< s} → ℕ {s'}) → ℕ {s}
>>>
>>> as follows, with Acc instead of ℕ, acc instead of suc, with explicit
>>> instead of implicit sizes, and forgetting the zero constructor, which
>>> was there just to make the above look like a definition of natural
>>> numbers anyway:
>>>
>>> data Acc (s : Size) : Set where
>>>
>>>       acc : ((s' : Size< s)  → Acc s') → Acc s
>>>
>>> then Acc reads as the accessibility predicate for the relation _<_  on
>>> Size such that i < j iff i : Size< j. The issue I raised can of course
>>> be rephrased by proving that the accessible part of the relation _<_
>>> coincides with the whole relation, in particular, Acc ∞, and since _<_
>>> is not well-founded (∞<∞) one gets a proof of False. Or one can use ℕ
>>> instead of Acc for that purpose, they're interchangeable here.
>>>
>>> Now, Acc is an inductive definition, and so is ℕ. I don't see how the
>>> latter can denote co-natural numbers, which AFAIK require a coinductive
>>> definition?
>>>
>>> Mind, I'm not saying that ℕ above is the appropriate way of defining
>>> sized natural numbers. But Agda accepts it - and it shouldn't, because
>>> after a few steps one gets a proof of False in safe mode...
>>>
>>>
>>>> On Mon, Oct 19, 2020 at 1:44 PM vlad <Vlad.Rusu at inria.fr> wrote:
>>>>> Thanks for finding this. I guess this is in a longer tradition of
>>>>> problems with the sized types implementation, see e.g.
>>>>> https://github.com/agda/agda/issues/2820,
>>>>> https://github.com/agda/agda/issues/3026,
>>>>> https://github.com/agda/agda/issues/1428.
>>>>>
>>>>> I don't understand whether it has overlap with existing issues. You
>>>>> don't use the infinity size, nor equality. So maybe it's a new 
>>>>> kind of
>>>>> issue, coming from interaction of sizes with inductive types?
>>>>>
>>>>> It is an elaboration on the bug about well-founded induction and 
>>>>> sized types (https://github.com/agda/agda/issues/3026). The main 
>>>>> difference with the latter is that, instead of importing the 
>>>>> well-founded module of Agda's library, I am using an apparently 
>>>>> innocent definition of a sized inductive type :
>>>>>
>>>>> data ℕ  {s : Size} :  Set where
>>>>>     zero :  ℕ
>>>>>     suc : ({s' : Size< s} → ℕ {s'}) → ℕ {s}
>>>>>
>>>>> as an accessibility predicate for the relation between sized 
>>>>> induced by the construction Size<. By using the "size-elimproved" 
>>>>> construction (also an elaboration of code found here: 
>>>>> https://github.com/agda/agda/issues/2820#issuecomment-339969286) I 
>>>>> can then define a "natural number" for each size, including 
>>>>> infinity (note that sizes are implicit arguments, so infinity does 
>>>>> not show up in the code, but it's there all right). For size = 
>>>>> infinity, the "natural number"
>>>>>
>>>>> foo : ℕ
>>>>> foo = size-elimproved (λ s → ℕ{s}) (λ _ H → suc λ { {j} → H j } ) _
>>>>>
>>>>> is easily shown to be a successor of itself, which the definition 
>>>>> of "natural numbers" forbids, hence the proof of False.
>>>>>
>>>>> Overall, I'm not sure it's worth a new bug report, as it is an 
>>>>> elaboration of existing constructions. My main point in showing 
>>>>> this is that one may easily "believe" that one is defining natural 
>>>>> numbers with sizes e.g. for writing non-structural recursive 
>>>>> functions over them (like integer division), while in effect 
>>>>> writing something else, with unpleasant consequences.
>>>>>
>>>>> _______________________________________________
>>>>> Agda mailing list
>>>>> Agda at lists.chalmers.se
>>>>> https://lists.chalmers.se/mailman/listinfo/agda
> _______________________________________________
> Agda mailing list
> Agda at lists.chalmers.se
> https://lists.chalmers.se/mailman/listinfo/agda
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.chalmers.se/pipermail/agda/attachments/20201020/e8157318/attachment.html>


More information about the Agda mailing list