Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Function Clojure-函数表达式相等性测试?_Function_Clojure_Expression_Equality - Fatal编程技术网

Function Clojure-函数表达式相等性测试?

Function Clojure-函数表达式相等性测试?,function,clojure,expression,equality,Function,Clojure,Expression,Equality,假设我有以下clojure函数: (defn a [x] (* x x)) (def b (fn [x] (* x x))) (def c (eval (read-string "(defn d [x] (* x x))"))) 是否有一种方法来测试函数表达式的相等性-某种等效的函数表达式 (eqls a b) 返回true?这取决于“函数表达式相等”的确切含义 这些函数最终将成为字节码,因此我可以将每个函数对应的字节码转储到一个字节[],然后比较两个字节码数组 然而,有许多不同的方法可

假设我有以下clojure函数:

(defn a [x] (* x x))

(def b (fn [x] (* x x)))

(def c (eval (read-string "(defn d [x] (* x x))")))
是否有一种方法来测试函数表达式的相等性-某种等效的函数表达式

(eqls a b)

返回true?

这取决于“函数表达式相等”的确切含义

这些函数最终将成为字节码,因此我可以将每个函数对应的字节码转储到一个字节[],然后比较两个字节码数组

然而,有许多不同的方法可以编写语义等价的方法,它们在字节码中没有相同的表示形式

一般来说,如果不运行一段代码,就不可能知道它是做什么的。因此,如果不在所有可能的输入上同时运行两位代码,就无法判断两位代码是否相等

从计算上讲,这至少和停顿问题一样糟糕,甚至可能更糟


停止问题是不可判定的,因此这里的一般情况答案肯定是否定的(不仅对于Clojure,而且对于每种编程语言).

我同意上述关于Clojure不具备确定两个函数等价性的内置能力的回答,并且已经证明,由于停止问题(除非输入集是有限的和定义的),您无法从功能上测试程序(也称为黑盒测试)以确定相等性

我想指出,即使两个函数有不同的形式(不同的字节码),也可以用代数方法确定它们的等价性


代数证明等价性的方法是由Alonzo Church在20世纪30年代提出的,在Lambda微积分中称为beta约化。这种方法当然适用于问题中的简单形式(也会产生相同的字节码),也适用于产生不同字节码的更复杂形式

我无法补充其他人的优秀答案,但我想提供另一个帮助我的观点。例如,如果您正在测试是否从您自己的函数返回了正确的函数,而不是比较函数对象,那么您可能只需将函数作为
符号返回即可


我知道这可能不是作者要求的,但对于简单的情况,它可能会这样做。

不可能——函数的等价性是不可判定的。哎呀,对赏金注释格式很抱歉——没有意识到格式的工作方式不一样。嗨,Omri。如果您看到我下面的答案,您将看到我谈论的两个函数,它们的主体具有相同的JVM字节码。这实际上是内涵平等。我还指出,内涵相等意味着外延相等(但反之则不成立)。如果字节码最终是不同的(对于您给出的一些示例来说可能是不同的),那么我们又回到了尝试实现扩展相等的阶段——我们知道这是不确定的。希望这能让事情变得更清楚一点——内涵平等(加上一些特殊情况)可能是我们所能期望的最好结果。@kittylyst谢谢你的回答,我觉得你的回答很周到。我开始相信,特殊情况的数量(正如你所说)实际上相当大,以至于我们可以有意义地测试函数等价性。例如,我认为
(*x x)
等同于
(*x x 1)
的情况可以通过注意
*
函数的标识值是
1
来解决。更一般地说,我们可以通过得到
(f)
的结果来测试标识值。如果给定的
f
确实有一个标识值,那么在进行等价性测试时,我们可以忽略某些
(f…
中的所有此类值。@kittylyst另外:如果您知道一种获取函数体的JVM字节码的方法,我很想知道如何获取,这听起来很酷。