[Agda] Type and termination checking around with clauses
Peter Berry
pwberry at gmail.com
Wed Apr 30 03:24:41 CEST 2008
module MergeNonterm where
{- Booleans. -}
data Bool : Set where
false : Bool
true : Bool
{- Natural numbers. -}
data ℕ : Set where
Z : ℕ
S : ℕ -> ℕ
{- Ordering of natural numbers. -}
_<=_ : ℕ -> ℕ -> Bool
Z <= n = true
S _ <= Z = false
S n <= S m = n <= m
{- Lists. -}
data List (A : Set) : Set where
[] : List A
_::_ : A -> List A -> List A
infixr 30 _::_
merge : List ℕ -> List ℕ -> List ℕ
merge xs [] = xs
merge [] ys = ys
merge (x :: xs) (y :: ys) with x <= y -- should be l@(x :: xs) but for the bug
... | true = x :: merge xs (y :: ys)
... | false = y :: merge (x :: xs) ys
These last two lines trip the termination checker. Clearly the
arguments are (as a whole) strictly smaller, but a new list is made,
which presumably makes the termination checker think they're getting
bigger. With at-patterns in with clauses working properly (i.e. bug 56
fixed, see http://code.google.com/p/agda/issues/detail?id=56) and
using l instead of x :: xs, would it pass? Or are there plans to make
the checker spot this kind of 'reconstructing patterns'? Is that even
feasible?
Possibly related: suppose I have a 'with' clause, say
contrived (dprod l p) with l
... | [] = ?0
... | x :: xs = ?1
where p : P l for some function P : List ℕ -> Set, say a property
which p is a proof of, and somewhere in ?1 I need something of type P
(x :: xs) (like a proof of the same property). Clearly x :: xs = l so
p will do, but somehow the type checker misses this - it won't unify P
l = P (x :: xs). (If you want a concrete example I can provide one.)
--
Peter Berry <pwberry at gmail.com>
Please avoid sending me Word or PowerPoint attachments.
See http://www.gnu.org/philosophy/no-word-attachments.html
More information about the Agda
mailing list