我在理解SML中的变体以及如何确定递归函数的变体时遇到了一些麻烦。我得到了解释:
“(递归)函数的变体是函数参数上的任何表达式,它接受某些集合A中的值,以便
但这并没有真正帮助我。一个更具体的例子会很棒!
答案 0 :(得分:1)
假设您的递归函数生成一个长度为n
的列表,其中所有元素都为零。
这看起来像这样:
fun foo 0 = []
| foo n = 0::(foo (n - 1))
在这种情况下,变量是函数的参数n
n
是一个自然数,自然数是完全有序的,没有无限下行链,因为没有链可以低于零。
此外,n
严格按每次递归调用减少。
另一个例子:假设你的函数接受两个参数x
和y
,如果x > y
则返回true,否则返回false。
fun bar 0 y = false
| bar x 0 = true
| bar x y = bar (x - 1) (y - 1)
在这种情况下,变体有几种选择。您可以将其视为x
或y
,如上例所示,或者为x + y
。在任何一种情况下,它都会采用自然数值并严格降低。
现在,举例来说,参数是非整数 - 查找列表的总和。
fun sum [] = 0
| sum (x::xs) = x + (sum xs)
在这种情况下,变量可以被视为列表的长度(同样是自然数),或者是列表本身,其中列表按如下顺序排列:
l1 < l2
iff有一些有限的元素序列x1,x2,...,xn
x1::x2::...::xn::l1 = l2
。
在这种比较下,很容易证明列表集是部分排序的,没有无限下行链,特别是,从某些列表开始的递归调用生成的列表集是完全有序的。 / p>
此外,在任何递归调用中,xs < (x::xs)
根据定义,因此列表正在减少。
变体的一点是,它是一个可以被引导来证明函数行为的数量。由于没有无限减少的链,必须有一个最小元素,可以作为归纳的基本情况,然后总顺序提供了一种从一个元素到一个元素直接大于它的方法。
这也可以通过没有无限递减链的部分顺序来完成,这保证了存在最小元素,如果不是必需的最小元素。然后可以将这些作为基本案例,并使用类似的归纳论证,尽管可能有多种方法来构建更大的元素。