【问题标题】:Are two functions equal?两个函数是否相等?
【发布时间】:2011-01-30 16:37:50
【问题描述】:

[编辑]

一般问题似乎很难解决。这是这个问题的一个明显受限的version


如何确定函数的相等性?

假设我们有

function f() {
    // black box code.
}

function g() {
    // black box code.
}

我们对函数进行数学定义。所以

if for all x in domain, f(x) === g(x) then f === g

  • 我们如何处理域?
  • 我们如何才能确定f === g

通过源代码检查是愚蠢的,因为

function f(i) {
     return i % 2;
}

function g(i) {
     var returnVal = i % 2;
     return returnVal;
}

显然是相等的。这些是微不足道的示例,但您可以想象更复杂的函数相等但源不相等。

您可以假设fg 没有我们关心的副作用。


[编辑]

正如@Pointy 提到的,最好限制域。与其让等式函数尝试猜测域,不如让等式函数的用户提供一个域。

如果没有在某个地方定义它们的域,就问两个函数是否相等是没有意义的。

简单来说,我们可以假设域的问题是所有整数的集合或其子集,因此我们需要一个函数:

function equal (f, g, domain) {

}

域的结构无关紧要,可以使问题尽可能简单。您还可以假设 fg 在整数域上表现良好并且不会崩溃和烧毁。

您可以假设fg 停止!

@Pointy 再次指出了非确定性函数的一个很好的例子

如果我们将 fg 限制为确定性会怎样。

【问题讨论】:

  • 好吧,因为 JavaScript 允许副作用,它甚至比检查返回值更复杂。我想您可以根据需要以这种方式约束问题,但我不了解它的实际价值。
  • @Pointy 我希望将无限集建模为函数。然后操纵这些集合并进行某种相等性检查。在这种情况下,您可以假设没有副作用。
  • 哦,好吧。这是一个有趣的问题;解决这个问题的一种方法是看看你是否能拿出证据证明它不可能
  • @Pointy 我宁愿不证明我正在编写的代码行不通。我可能需要在 LISP 而不是 JavaScript 中执行此操作。
  • 我并不是说证明它会很有趣 :-) 这似乎是一种思考问题的有趣方式。函数族的域是否受到任何限制?

标签: javascript function comparison equality


【解决方案1】:

根据Rice's theorem这是不可能的:

在可计算性理论中,Rice 的 定理指出,对于任何 部分的非平凡属性 功能,没有通用和 判断是否存在的有效方法 算法计算偏函数 使用该属性。

如果您将函数的域限制为有限,那么您可以使用蛮力简单地验证 ∀x: f(x) = g(x),但这对于无限域是不可能的。

【讨论】:

  • 如果函数是确定性的,这仍然成立吗?
  • 你能解释一下赖斯定理的相关性吗?
  • @Raynos 假设我们正在检查 f 的以下属性:对于每个 x,它都会返回 g(x)。如果您不假设 g 具有任何特定属性,则此属性并非微不足道,因此“没有通用且有效的方法”来检查函数是否相等。
【解决方案2】:

不可能创建一种机制,给定两个函数,总是可以确定它们是否总是返回相同的值。

这源于您尝试解决的问题等同于 Halting problem(source; 第 4 页)

当然,您可以通过启发式方法来做到这一点,但总会有他们无法确定的情况。

假设您将范围缩小到在有限域上停止功能,那么快速确定仍然不是一件容易的事。如果我们假设输入位于 {1, ..., n} 中,输出位于 {1, ..., m} 中,则有 mn 个可能的函数(对于每个输入,有n 个可能的输出)。如果您对 k 个点进行采样,则将其缩小,并使它们相等的概率更大,但是仍然可能有 m(n-k) 个不同的函数。因此,您可以很快确定它们是否可能相等,但要确定的是,您必须检查所有 n 个可能的输入值。

如果您想通过采样以外的其他方式进行操作,我相信您必须对函数的源代码执行某种static analysis,这几乎是微不足道的。

此外,如果域不是有限的,Rice's theorem 会阻止这样的算法存在。

【讨论】:

  • @SebastianP if f and g halt 停止问题仍然相关吗?
  • 鉴于他们停止,停止问题不应该是一个问题。仍然存在一个问题,即给定足够大的域,我看不出您如何验证它们在所有值上是否对应。我会写一些东西,评论有点长。
  • @Sebastian 会将输出限制为boolean help?
  • @Raynos:那么您将拥有 2^n 个函数。如果你应该限制任何东西,那就是输入域。输入域越小,越容易检查。
  • 不要试图智取停机问题。将输出限制为布尔值根本不重要:函数 1:{蛮力搜索哥德巴赫猜想的反例高达 10^10^10^10^10^10。返回找到/未找到} ;函数 2:{return false}。
【解决方案3】:

假设您谈论的是一系列 JavaScript 函数,它们被限制为一个整数参数,并且没有可见的外部副作用,我仍然认为通常不可能确定相等性。考虑一下:

function a(n) {
  var today = new Date();
  if (today.getFullYear() === 2012 && today.getMonth() === 1 && today.getDate() === 3)
    return 0;
  return n * n;
}

这个函数看起来很像

function b(n) { return n * n; }

除了 2012 年 2 月 3 日,它看起来完全像:

function c(n) { return 0; }

如果您真的是在谈论一个实用的真实软件来执行这样的分析,并且如果您真的对要测试的功能的细节没有太多控制权,那么这似乎是不可能的。也许您可以构建一组函数必须遵循的“规则”,但即便如此,在不测试域中的每个值的情况下确定相等性的前景似乎也很遥远。

edit——我只是想到了一些事情:如果你的两个函数都返回函数怎么办?现在,要判断是否f == g,首先要弄清楚f(n)返回的函数是否对所有n 等于 g(n) 为所有 n 返回的函数。嗯……

【讨论】:

  • 这是一个愚蠢的功能!我看到了这个问题。如果我们使函数具有确定性呢?
  • @Raynos 我试过了,但我想不出更聪明的例子 :-)
  • 是否值得重新发布严格限制fg函数的域、共域和各种属性的问题?
  • 嗯,可能 - 这远远超出了我对范畴理论的了解,对我有很大帮助!!
【解决方案4】:

一般来说没有办法做到这一点。您可以针对输入的随机样本测试这两个函数,并检查它们在这些特定值上是否相等,但通常测试每个可能的输入是不可行的。

【讨论】:

    【解决方案5】:

    CoqAgda 等证明验证系统可能能够满足您的需求。

    【讨论】:

    • 我想自己写函数!
    猜你喜欢
    • 2013-12-02
    • 2015-08-24
    • 1970-01-01
    • 1970-01-01
    • 2020-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多