4

问题

我有一个简单的共归纳记录,其中包含一个 sum 类型的单个字段。Unit给了我们一个简单的类型来玩。

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

作品

valid通过终止检查:

valid : Maybe Unit → Stream
step (valid x) = inj₂ (valid x)

休息

但是假设我想消除该Maybe Unit成员,并且只有在我有just.

invalid₀ : Maybe Unit → Stream
step (invalid₀ x) = maybe (λ _ → inj₂ (invalid₀ x)) (inj₁ unit) x

现在终止检查器很不高兴!

Termination checking failed for the following functions:
  invalid₀
Problematic calls:
  invalid₀ x

为什么这不满足终止检查器?有没有办法解决这个问题,还是我的概念理解不正确?

背景

agda --version产量Agda version 2.6.0-7ae3882。我只使用默认选项进行编译。

的输出在-v term:100这里:https ://gist.github.com/emilyhorsman/f6562489b82624a5644ed78b21366239

尝试的解决方案

  1. 使用Agda version 2.5.4.2. 不修复。
  2. 使用--termination-depth=10. 不修复。
4

2 回答 2

6

You could make use of sized types here.

open import Data.Maybe
open import Data.Sum
open import Size

data Unit : Set where
  unit : Unit

record Stream {i : Size} : Set where
  coinductive
  field
    step : {j : Size< i} → Unit ⊎ Stream {j}

open Stream

valid : Maybe Unit → Stream
step (valid x) = inj₂ (valid x)

invalid₀ : {i : Size} → Maybe Unit → Stream {i}
step (invalid₀ x) = maybe (λ _ → inj₂ (invalid₀ x)) (inj₁ unit) x

_ : step (invalid₀ (nothing)) ≡ inj₁ unit
_ = refl

_ : step (invalid₀ (just unit)) ≡ inj₂ (invalid₀ (just unit))
_ = refl

Being more explicit about the Size arguments in the definition of invalid₀:

step (invalid₀ {i} x) {j} = maybe (λ _ → inj₂ (invalid₀ {j} x)) (inj₁ unit) x

where j has type Size< i, so the recursive call to invalid₀ is on a “smaller” Size.

Notice that valid, which didn't need any “help” to pass termination checking, doesn't need to reason about Size's at all.

于 2019-04-03T18:04:33.417 回答
4
于 2019-04-03T16:26:50.440 回答