Sized Types [Re: [Agda] proving termination trouble again]

Andreas Abel andreas.abel at ifi.lmu.de
Mon Jan 18 12:45:21 CET 2010


That is an issue with universe polymorphism.
I am using stdlib 0.2 without uni poly.

Probably there is just a level argument (to Rel) missing?!

Cheers,
Andreas

On Jan 17, 2010, at 12:24 AM, Ruben Henner Zilibowitz wrote:

> Hi Andreas,
>
> Thanks, but it doesn't work. I'm using agda 2.2.6 with standard lib  
> 0.3 by the way.
>
> ZilibowitzRubenHenner2.agda:26,12-25
> (ℓ : .Level.Level) → Set (.Level._⊔_ .Level.zero (.Level.suc  
> ℓ))
> !=< _18 of type Setω
> when checking that the expression Rel (Nat {∞}) has type _18
>
> Ruben
>
> On 16/01/2010, at 12:07 PM, Andreas Abel wrote:
>
>> Hi Ruben,
>>
>> here is a translation of your code into something very similiar  
>> that uses a sized type of natural numbers.  Unfortunately, sized  
>> types are not well integrated into Agda yet, so a sizes have to be  
>> declared explicitely, and the standard library, which does not use  
>> sized types, is not usable.
>>
>> <ZilibowitzRubenHenner2.agda>
>>
>> A few things you need to know:
>> - Unspecified sizes default to \infty.  For instance, "Nat" is  
>> really "Nat {\infty}"
>> - The successor \uparrow is not a constructor, it cannot be  
>> matched, but it can appear in dot-patterns.
>> - Things are a bit fiddly, so I had to try a bit which sizes I need  
>> to mention explicitly and which can be inferred sensibly.
>> - It is advisable to turn on hidden arguments to see where stuff  
>> fails.
>>
>> If you look at the example where I made sizes more explicit, you  
>> see that the mutual functions j and helper terminate on the first  
>> argument "size".  It is decreasing in the call j-->helper and  
>> unchanged in the call back.
>>
>> j : ∀ {size} → Nat {size} -> Nat
>> j zero = zero
>> j .{↑ size} (suc {size} n) = helper {size} (suc n) (z (suc n)  
>> (s≤s z≤n))
>> where
>> helper : {size : Size} -> (sn : Nat {↑ size}) -> ∃ {Nat {size}}  
>> (λ n → n < sn) -> Nat
>> helper {size} sn (n , _) = j {size} n
>>
>> Hope that helps,
>> Cheers,
>> Andreas
>>
>> On Jan 16, 2010, at 12:25 AM, Ruben Henner Zilibowitz wrote:
>>
>>> Hi Andreas,
>>>
>>> Below is a slightly simpler example. Function j does not  
>>> termination check. Would you be so kind as to demonstrate how to  
>>> use sized types to fix this?
>>> I'm having some trouble figuring out how sized types are supposed  
>>> to work exactly.
>>>
>>> Thanks,
>>> Ruben
>>>
>>> -----------
>>>
>>> module TerminationTwoConstructors where
>>>
>>> open import Data.Nat
>>> open import Relation.Binary
>>> open import Relation.Binary.PropositionalEquality
>>> open import Data.Product
>>>
>>> ≤-refl : _≡_ ⇒ _≤_
>>> ≤-refl = IsPreorder.reflexive (IsPartialOrder.isPreorder  
>>> (IsTotalOrder.isPartialOrder (IsDecTotalOrder.isTotalOrder  
>>> (DecTotalOrder.isDecTotalOrder decTotalOrder))))
>>>
>>> z : (n : ℕ) → (0 < n) → ∃ (λ m → m < n)
>>> z zero ()
>>> z (suc n) _ = n , ≤-refl refl
>>>
>>> j : ℕ -> ℕ
>>> j zero = zero
>>> j (suc n) = helper (suc n) (z (suc n) (s≤s z≤n))
>>> where
>>> helper : (sn : ℕ) -> ∃ (λ n → n < sn) -> ℕ
>>> helper sn (n , _) = j n
>>>
>>> On 12/01/2010, at 8:41 PM, Andreas Abel wrote:
>>>
>>>> Hi Ruben,
>>>>
>>>> from the perspective of the termination checker, there is no  
>>>> difference in g and h.  The proofs of equality/leq are not used  
>>>> by the termination checker, it only honors structural ordering.   
>>>> It "sees" that
>>>>
>>>> sn < suc (suc n)
>>>>
>>>> by composing the calls g --> helper --> g.
>>>>
>>>> For function i to termination check, it would have to evaluate  
>>>> proj_1 whee, but the termination checker does not do any  
>>>> evaluation (since evaluation (1) is safe only after termination  
>>>> checking, and (2) leads to unfeasible termination checking (see  
>>>> the Coq guardedness checker)).
>>>>
>>>> If you want to propagate termination arguments (like sn < ssn)  
>>>> through functions and data structures, you need more informative  
>>>> typing, like sized types.
>>>>
>>>> Cheers,
>>>> Andreas
>>>>
>>>> On Jan 11, 2010, at 2:24 PM, Ruben Henner Zilibowitz wrote:
>>>>
>>>>> In relation to issue 59:
>>>>>
>>>>> http://code.google.com/p/agda/issues/detail?id=59&can=1&q=termination
>>>>>
>>>>> Here is another problem I've encountered along similar lines. In  
>>>>> the code below, the functions f, g, h, and i all are in  
>>>>> principal the same. However, only g and h pass the termination  
>>>>> checker. Function f suffers from the problem in issue 59.  
>>>>> Function g solves it with the same workaround suggested in issue  
>>>>> 59. Function h solves it in a similar way. The problem is  
>>>>> function i. It is very similar to function h but the argument  
>>>>> (sn < ssn) in the helper function is concealed inside a product  
>>>>> type and needs to be extracted using proj₂ which breaks this  
>>>>> example. Is this a bug? Sorry for the hard to read code and  
>>>>> function names..
>>>>>
>>>>> The code below is based on Andreas Abel's earlier example..
>>>>>
>>>>> Ruben
>>>>>
>>>>> ----------
>>>>>
>>>>> module TerminationTwoConstructors where
>>>>>
>>>>> open import Data.Nat
>>>>> open import Relation.Binary
>>>>> open import Relation.Binary.PropositionalEquality
>>>>> open import Data.Product
>>>>>
>>>>> bla : ℕ -> ℕ
>>>>> bla m = m
>>>>>
>>>>> f : ℕ -> ℕ
>>>>> f zero = zero
>>>>> f (suc zero) = zero
>>>>> f (suc (suc n)) with bla (suc (suc n))
>>>>> ... | m = f (suc n)
>>>>>
>>>>> g : ℕ -> ℕ
>>>>> g zero = zero
>>>>> g (suc zero) = zero
>>>>> g (suc (suc n)) = helper (suc (suc n)) (suc n) refl (bla (suc  
>>>>> (suc n)))
>>>>> where
>>>>> helper : (ssn : ℕ) -> (sn : ℕ) -> (suc sn ≡ ssn) -> (m :  
>>>>> ℕ) -> ℕ
>>>>> helper ssn sn _ m = g sn
>>>>>
>>>>> ≤-refl : _≡_ ⇒ _≤_
>>>>> ≤-refl = IsPreorder.reflexive (IsPartialOrder.isPreorder  
>>>>> (IsTotalOrder.isPartialOrder (IsDecTotalOrder.isTotalOrder  
>>>>> (DecTotalOrder.isDecTotalOrder decTotalOrder))))
>>>>>
>>>>> h : ℕ -> ℕ
>>>>> h zero = zero
>>>>> h (suc zero) = zero
>>>>> h (suc (suc n)) = helper (suc (suc n)) (suc n) (≤-refl refl)  
>>>>> (bla (suc (suc n)))
>>>>> where
>>>>> helper : (ssn : ℕ) -> (sn : ℕ) -> (sn < ssn) -> (m : ℕ) ->  
>>>>>>>>>> helper ssn sn _ m = h sn
>>>>>
>>>>> zog : (n : ℕ) -> (ℕ × n < suc n)
>>>>> zog n = n , ≤-refl refl
>>>>>
>>>>> i : ℕ -> ℕ
>>>>> i zero = zero
>>>>> i (suc zero) = zero
>>>>> i (suc (suc n)) = let whee = zog (suc n) in helper (suc (suc n))  
>>>>> (proj₁ whee) (proj₂ whee) (bla (suc (suc n)))
>>>>> where
>>>>> helper : (ssn : ℕ) -> (sn : ℕ) -> (sn < ssn) -> (m : ℕ) ->  
>>>>>>>>>> helper ssn sn _ m = i sn
>>>>
>>>> Andreas ABEL
>>>> INRIA, Projet Pi.R2
>>>> 23, avenue d'Italie
>>>> F-75013 Paris
>>>> Tel: +33.1.39.63.59.41
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>
>> Andreas ABEL
>> INRIA, Projet Pi.R2
>> 23, avenue d'Italie
>> F-75013 Paris
>> Tel: +33.1.39.63.59.41
>>
>>
>>
>
>
>

Andreas ABEL
INRIA, Projet Pi.R2
23, avenue d'Italie
F-75013 Paris
Tel: +33.1.39.63.59.41





More information about the Agda mailing list