idris - 为什么这个 'with' block 会破坏这个函数的完整性?

标签 idris termination totality

我正在尝试在自然数上计算奇偶校验和一半的下限:

data IsEven : Nat -> Nat -> Type where
    Times2 : (n : Nat) -> IsEven (n + n) n

data IsOdd : Nat -> Nat -> Type where
    Times2Plus1 : (n : Nat) -> IsOdd (S (n + n)) n

parity : (n : Nat) -> Either (Exists (IsEven n)) (Exists (IsOdd n))

我尝试使用明显的奇偶校验实现:

parity Z = Left $ Evidence _ $ Times2 0
parity (S Z) = Right $ Evidence _ $ Times2Plus1 0
parity (S (S n)) with (parity n)
  parity (S (S (k + k))) | Left (Evidence _ (Times2 k)) =
      Left $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2 (S k)
  parity (S (S (S ((k + k))))) | Right (Evidence _ (Times2Plus1 k)) =
      Right $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2Plus1 (S k)

此类型检查并按预期工作。但是,如果我尝试将 parity 标记为 total,Idris 就会开始提示:

 parity is possibly not total due to: with block in parity

我在 parity 中看到的唯一 with block 是从 parity (S (S n)) 递归调用到 parity n,但显然这是有充分根据的,因为 n 在结构上小于 S (S n)

如何让 Idris 相信平价是完全的?

最佳答案

对我来说这看起来像是一个错误,因为以下基于 case 的解决方案通过了完整性检查器:

total
parity : (n : Nat) -> Either (Exists (IsEven n)) (Exists (IsOdd n))
parity Z = Left $ Evidence _ $ Times2 0
parity (S Z) = Right $ Evidence _ $ Times2Plus1 0
parity (S (S k)) =
  case (parity k) of
    Left (Evidence k (Times2 k)) =>
      Left $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2 (S k)
    Right (Evidence k (Times2Plus1 k)) =>
      Right $ rewrite plusSuccRightSucc k k in Evidence _ $ Times2Plus1 (S k)

关于idris - 为什么这个 'with' block 会破坏这个函数的完整性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46562066/

相关文章:

idris - Idris 中的简单句法等式

idris - 在 Idris 中定义组

agda - 有限的数字如何运作? (依赖类型)

Kubernetes多容器pod终止流程

python - 程序终止时触发代码

java - 如何以安全的方式关闭我的软件?

coq - 定义产品类型的递归函数

idris - 将 Nat 保持在固定范围内

coq - Coq中的程序定点和功能之间有什么区别?

proof - 如果 idris 认为事情可能是完整的,但事实并非如此, idris 可以用来证明吗?