[Agda] Non-termination help!

Martín martin at dcc.fceia.unr.edu.ar
Thu Dec 7 20:10:28 CET 2017


Hello Gallais,

Exactly! I have to postulate functional extensionality in order to prove 
equality between these functions.

The good thing is that I just use it when proving that every Signature 
defines an endofunctor in Set.

ΣEndo : Signature -> Endofunctor (Sets lzero)
ΣEndo Sig = record { F₀ = Σ Sig
                    ; F₁ = λ { x (C , as) → C , λ x₁ → x (as x₁)}
                    ; homomorphism = ≣-refl
                    ; F-resp-≡ = λ{ x {C , as} → ≣-cong (λ y → C , y) 
(ext λ a → x {as a})} -- <- here it is!
                    ; identity = ≣-refl
             }

Thank you for your answer!

Cheers,
Martín

On 12/07/2017 03:56 PM, Guillaume Allais wrote:
> Hi Martín,
>
> This representation works because the subterm relationship between
> `as` and `as x` is self-evident from Agda's point of view. However,
> when you have a vector of subterms and you step through it via `map`,
> you add one level of indirection which hides from Agda the fact that
> the recursive calls are performed on direct subterms.
>
> As Andreas said, the old-school solution to this issue is to write
> a mutually defined `mapSize`, an inlined and specialised version of
> `map` partially applied to `size`. And the modern approach to this
> problem is to use sized types so that the *type* is explicit about
> the fact that `map` doesn't do anything funky with the induction
> hypothesis it is handed down.
>
> You have demonstrated a third way which is to use the duality between
> a finite data structure and its lookup function (or dually: between a
> function with a finite domain and its tabulation). However this will
> probably create some trouble whenever you want to prove things equal
> (unless you're willing to postulate functional extensionality) because
> vectors are much more permissive than functions when it comes to proving
> them propositionally equal.
>
> Cheers,
> --
> gallais
>
> On 07/12/17 19:21, Martín wrote:
>> Hello Andreas,
>>
>> Thank you very much for the quick response. As I told you I wanted to
>> avoid sized types and after a bit we came up with another solution.
>>
>> We use *Fin* datatype to represent N-Ary product instead of Vec.
>>
>>      open import Data.Fin
>>
>>      record Signature : Set (lsuc lzero) where
>>        constructor sig
>>        field
>>          σ : Set
>>          arity : σ -> ℕ
>>
>>      record Σ (Sig : Signature) (X : Set) : Set where
>>        constructor _,_
>>        field
>>          C  : Signature.σ Sig
>>          as : Fin (Signature.arity Sig C) -> X
>>
>>      data µM (S : Signature) : Set where
>>        In : Σ S (µM S) -> µM S
>>
>>      sumUp : {n : ℕ} -> (Fin n -> ℕ) -> ℕ
>>      sumUp {zero} f = zero
>>      sumUp {suc n} f =  f zero + sumUp λ x → f (suc x)
>>
>>      size : {Sig : Signature} -> µM Sig -> ℕ
>>      size {Sig} (In (C , as)) = suc (sumUp λ x → size (as x))
>>
>> Sadly I am a bit confused now. Why does this representation work? I
>> know that *FIn* is an indexed type, but my guess is that I also have
>> more power from the higher order function *as*. Basically the
>> termination checker now sees that I am calling *size (as x)* with *as*
>> being smaller than *In (C, as)*, am I correct?
>>
>> Thank you again for your time!
>>
>> Cheers,
>>
>> Martín.
>>
>> -- 
>>
>> On 12/07/2017 05:29 AM, Andreas Abel wrote:
>>> Martín,
>>>
>>> a bit ironically, to define "size" you need "sized types". ;-)
>>>
>>> The termination checker per se does not see that in the call
>>>
>>>    map size as
>>>
>>> function "size" will be only applied to arguments that are
>>> structurally smaller than "In (C , as)"; simply, because it cannot
>>> even "see" an argument to "size".
>>>
>>> To help the termination checker, you need to index type \mu with a
>>> Size (built-in notion for an upper bound on the height).
>>>
>>>    open import Size
>>>
>>>    data µ (S : Signature) (i : Size) : Set where
>>>      In : {j : Size< i} → Σ S (µ S j) -> µ S i
>>>
>>>    size : ∀{i} {S : Signature} -> µ S i -> ℕ
>>>    size (In (C , as)) = suc (sum (map size as))
>>>
>>> Now "size" has an additional argument "i" which decreases in
>>> recursive calls.
>>>
>>> Alternatively, you can define "size" mutually with a function
>>> "mapSize" which is an inling of the code for "map size".
>>>
>>> Cheers,
>>> Andreas
>>>
>>> On 06.12.2017 14:56, Martín wrote:
>>>> Hello everyone. I am struggling with Agda's termination checker.
>>>>
>>>> The idea is to define a recursive function like *size* over terms µ
>>>> S for some signature S (definitions are bellow). I can destruct (t :
>>>> µ S) to obtain some symbol and its 'arguments', such arguments
>>>> should be smaller since µ S is strictly positive. Therefore, I
>>>> should be able to recursively call size, right?.
>>>>
>>>> Here is an example where I leave the holes to be filled. I have
>>>> tried different approaches to help the termination checker such as
>>>> views and sized types. Sized types fix these simple functions, but
>>>> it complicates matters in further proofs.
>>>>
>>>> Cheers,
>>>>
>>>> Martín.
>>>>
>>>> ----
>>>>
>>>> module Q where
>>>>
>>>> open import Data.Vec
>>>> open import Data.Nat
>>>>
>>>> open import Level renaming (zero to lzero ; suc to lsuc)
>>>>
>>>> record Signature : Set (lsuc lzero) where
>>>>     constructor sig
>>>>     field
>>>>       σ : Set
>>>>       arity : σ -> ℕ
>>>>
>>>> record Σ (Sig : Signature) (X : Set) : Set where
>>>>     constructor _,_
>>>>     field
>>>>       C : Signature.σ Sig
>>>>       as : Vec X (Signature.arity Sig C)
>>>>
>>>> data µ (S : Signature) : Set where
>>>>     In : Σ S (µ S) -> µ S
>>>>
>>>> size : {S : Signature} -> µ S -> ℕ
>>>> size (In (C , as)) = suc (sum (map {!size!} as))
>>>>
>>>> size' : {S : Signature} -> µ S -> ℕ
>>>> size' {sig σ arity} (In (C , as)) with arity C
>>>> size' {sig σ arity} (In (C , [])) | zero = 0
>>>> size' {sig σ arity} (In (C , (x ∷ as))) | suc arC = suc (sum (map
>>>> {!size'!} (x ∷ as) ))
>>>>
>>>> _______________________________________________
>>>> 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
>
> _______________________________________________
> Agda mailing list
> Agda at lists.chalmers.se
> https://lists.chalmers.se/mailman/listinfo/agda



More information about the Agda mailing list