Problem
I have a simple coinductive record with a single field of a sum type. Unit gives us a simple type to play with.
open import Data.Maybe
open import Data.Sum
data Unit : Set where
unit : Unit
record Stream : Set where
coinductive
field
step : Unit ⊎ Stream
open Stream
Works
valid passes the termination checker:
valid : Maybe Unit → Stream
step (valid x) = inj₂ (valid x)
Breaks
But say I want to eliminate the Maybe Unit member and only recurse when I have a just.
invalid₀ : Maybe Unit → Stream
step (invalid₀ x) = maybe (λ _ → inj₂ (invalid₀ x)) (inj₁ unit) x
Now the termination checker is unhappy!
Termination checking failed for the following functions:
invalid₀
Problematic calls:
invalid₀ x
Why does this not satisfy the termination checker? Is there a way around this or is my conceptual understanding incorrect?
Background
agda --version yields Agda version 2.6.0-7ae3882. I am compiling only with the default options.
The output of -v term:100 is here: https://gist.github.com/emilyhorsman/f6562489b82624a5644ed78b21366239
Attempted Solutions
- Use
Agda version 2.5.4.2. Does not fix. - Use
--termination-depth=10. Does not fix.
You could make use of sized types here.
Being more explicit about the
Sizearguments in the definition ofinvalid₀:where
jhas typeSize< i, so the recursive call toinvalid₀is on a “smaller”Size.Notice that
valid, which didn't need any “help” to pass termination checking, doesn't need to reason aboutSize's at all.