如何确定SML中递归函数的变量?

时间:2013-12-02 17:24:31

标签: sml variant

我在理解SML中的变体以及如何确定递归函数的变体时遇到了一些麻烦。我得到了解释:

“(递归)函数的变体是函数参数上的任何表达式,它接受某些集合A中的值,以便

  • A是(完全)有序的;此外,没有无限的下行链v0> v1> ... 在一个;和
  • 对于任何递归调用,变量严格减少。“

但这并没有真正帮助我。一个更具体的例子会很棒!

1 个答案:

答案 0 :(得分:1)

假设您的递归函数生成一个长度为n的列表,其中所有元素都为零。

这看起来像这样:

fun foo 0 = []
  | foo n = 0::(foo (n - 1))

在这种情况下,变量是函数的参数n n是一个自然数,自然数是完全有序的,没有无限下行链,因为没有链可以低于零。
此外,n严格按每次递归调用减少。

另一个例子:假设你的函数接受两个参数xy,如果x > y则返回true,否则返回false。

fun bar 0 y = false
  | bar x 0 = true
  | bar x y = bar (x - 1) (y - 1)

在这种情况下,变体有几种选择。您可以将其视为xy,如上例所示,或者为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)根据定义,因此列表正在减少。

变体的一点是,它是一个可以被引导来证明函数行为的数量。由于没有无限减少的链,必须有一个最小元素,可以作为归纳的基本情况,然后总顺序提供了一种从一个元素到一个元素直接大于它的方法。

这也可以通过没有无限递减链的部分顺序来完成,这保证了存在最小元素,如果不是必需的最小元素。然后可以将这些作为基本案例,并使用类似的归纳论证,尽管可能有多种方法来构建更大的元素。