[编辑]
一般问题似乎难以解决。以下是此问题的显着限制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;
}
显然是平等的。这些都是微不足道的例子,但你可以想象更复杂的函数是相等的但不是源相等的。
您可以认为f
和g
没有我们关心的副作用。
[编辑]
正如@Pointy所说,最好限制域名。而不是使用相等函数尝试并猜测域,相等函数的用户应该提供域。
在没有在某处定义域名的情况下,询问两个函数是否相等是没有意义的。
简单地说,我们可以假设域的问题是所有整数的集合或者它的子集,所以我们需要一个函数:
function equal (f, g, domain) {
}
域的结构是无关紧要的,可以使问题尽可能简单。您还可以假设f
和g
在整数域上表现良好,不会崩溃和烧毁。
您可以假设f
和g
停止了!
再次@Pointy指出非确定性函数的一个很好的例子
如果我们限制f
& g
是确定性的。
答案 0 :(得分:14)
在可计算性理论中,赖斯的 定理说,对于任何 部分的非平凡属性 功能,没有一般和 有效的方法来决定是否 算法计算部分函数 有这个属性。
如果将函数的域限制为有限,那么您可以使用强力来验证是否fx:f(x)= g(x),但对于无限域,这是不可能的。
答案 1 :(得分:8)
创建一种机制是不可能的,给定两个函数,总是可以确定它们是否总是返回相同的值。
这源于您尝试解决的问题等同于Halting problem。(source;第4页)
当然,您可以通过启发式方法来执行此操作,但总会出现无法确定的情况。
假设您将其缩小到停止在有限域上的功能,那么快速确定仍然不是一件容易的事。如果我们假设输入位于{1,...,n}并且输出位于{1,...,m},则有m n 可能的函数(对于每个输入,有n可能的输出)。如果您对k点进行采样,则将其缩小,并使它们的概率相等,但仍然存在m (n-k)不同的函数。因此,您可以确定它是否可能它们相当快,但是要确定,您必须检查所有n个可能的输入值。
如果你想以另一种方式而不是通过抽样来做,我相信你必须对函数的源代码做一些static analysis,这几乎是微不足道的。
此外,如果域不是有限的,Rice's theorem会阻止此类算法存在。
答案 2 :(得分: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; }
如果您真的在谈论实际软件来执行这样的分析,并且如果您真的无法控制要测试的功能的细节,那么这似乎是不可能的。也许你可以构造一组函数必须遵循的“规则”,但即便如此,在不测试域中每个值的情况下确定相等性的前景似乎也很遥远。
编辑 - 我只想到了一件事:如果你的两个函数返回函数怎么办?现在,要确定 f == g ,首先必须弄清楚 f(n)为所有返回的函数> n 等于 g(n)为所有 n 返回的函数。嗯......
答案 3 :(得分:2)
一般情况下无法做到这一点。您可以为随机的输入样本测试这两个函数,并检查它们在这些特定值上的相等性,但通常不可能测试每个可能的输入。
答案 4 :(得分:1)