The following code is perfectly ok in Haskell:
dh :: Int -> Int -> (Int, Int)
dh d q = (2^d, q^d)
a = dh 2 (fst b)
b = dh 3 (fst a)
Similiar code in Agda wouldn't compile (termination check fails):
infixl 9 _^_
_^_ : ℕ → ℕ → ℕ
x ^ zero = 1
x ^ suc n = x * (x ^ n)
dh : ℕ -> ℕ -> ℕ × ℕ
dh d q = 2 ^ d , q ^ d
mutual
a = dh 2 (proj₁ b)
b = dh 3 (proj₁ a)
The definition of a
uses a
which is not structurally smaller, hence the loop. It seems that the termination checker wouldn't look inside the definition of dh
.
I've tried using coinduction, setting option --termination-depth=4
-- doesn't help.
Inserting {-# NO_TERMINATION_CHECK #-}
within the mutual
block helps but it looks like a cheat.
Is there a clean way to make Agda compile the code? Does Agda's termination checker have some fundamental limitations?