Recursion Idris:尝试为Nat重新实现fromInteger时,总体检查失败
我有以下代码:Recursion Idris:尝试为Nat重新实现fromInteger时,总体检查失败,recursion,static-analysis,idris,totality,Recursion,Static Analysis,Idris,Totality,我有以下代码: module Test data Nat' = S' Nat' | Z' Num Nat' where x * y = ?hole x + y = ?hole fromInteger x = if x < 1 then Z' else S' (fromInteger (x - 1)) 函数应该总是给出一个结果,因为fromInteger的参数最终会变小,足以选择第一种情况。但伊德里斯似乎并不理解这一点。此函数有什么问题,如何修复此错误?n-
module Test
data Nat' = S' Nat' | Z'
Num Nat' where
x * y = ?hole
x + y = ?hole
fromInteger x = if x < 1 then Z' else S' (fromInteger (x - 1))
函数应该总是给出一个结果,因为fromInteger的参数最终会变小,足以选择第一种情况。但伊德里斯似乎并不理解这一点。此函数有什么问题,如何修复此错误?n-1
在结构上不小于n
,要了解这一点,请注意整数
不是归纳类型。因此,您需要使用assert\u minger
(请参阅Idris)之类的技巧使总体检查器确信您的函数实际上是完整的:
其定义如下:
它只计算第二个参数,但也向总体检查器断言y
在结构上小于x
这是Idris在其标准库(请参阅)中针对您的问题所使用的:
Test.idr:6:5:
Prelude.Interfaces.Test.Nat' implementation of Prelude.Interfaces.Num, method fromInteger is
possibly not total due to recursive path Prelude.Interfaces.Test.Nat' implementation of
Prelude.Interfaces.Num, method fromInteger --> Prelude.Interfaces.Test.Nat' implementation of
Prelude.Interfaces.Num, method fromInteger
assert_smaller : (x : a) -> (y : b) -> b
assert_smaller x y = y
fromIntegerNat : Integer -> Nat
fromIntegerNat 0 = Z
fromIntegerNat n =
if (n > 0) then
S (fromIntegerNat (assert_smaller n (n - 1)))
else
Z