2012-02-22 2 views
13

가정하자 나는이 다음과 같은 Clojure의 기능 :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를 반환

의 일부 동등한?

+1

불가능 - 함수의 동등성은 결정할 수 없습니다. –

+0

현상금 주석 형식에 대해 유감스럽게 생각합니다. 서식이 동일한 방식으로 작동하지 않는다는 것을 알지 못했습니다. –

+1

안녕 Omri. 아래에서 내 대답을 보면, JVM 바이트 코드가 같은 두 가지 함수에 대해 이야기 할 것입니다. 그것은 사실상 내적인 평등입니다. 나는 또한 내적인 평등이 내적인 평등을 의미한다는 점을 강조한다. (그러나 그 반대는 사실이 아니다.) 바이트 코드가 다른 것으로 끝나면 (예를 들어 여러분이 제공 한 몇 가지 예와 같이), 우리는 확장 성 평등을 달성하려고 노력하고 있습니다.희망은 물건을 조금 더 분명하게 해줍니다. - 의도적 인 평등 (특별한 경우를 더한 것)이 아마도 우리가 희망할만한 최선일 것입니다. – kittylyst

답변

3

Clojure는 두 기능의 동등성을 판단 할 수있는 기능이 없으며 프로그램을 기능적으로 테스트 할 수 없다는 것을 증명했습니다 (블랙 박스 테스트라고도 함). (input set이 유한하고 정의되어 있지 않으면) 정지 문제로 인해 동등 함.

서로 다른 형식 (다른 바이트 코드)을 가지고 있어도 대수적으로 두 함수의 동등성을 결정할 수 있음을 지적하고자합니다.

대수적으로 등가성을 증명하는 방법은 1930 년대에 Alonzo Church에서 개발되었으며 람다 미적분학에서 베타 감소로 알려져 있습니다. 이 방법은 질문의 단순한 형식 (동일한 바이트 코드도 생성 됨)과 다른 바이트 코드를 생성하는보다 복잡한 형식에도 확실히 적용 할 수 있습니다.

11

"함수 표현식의 동일성"이 무엇을 의미하는지에 따라 달라집니다.

이러한 함수는 바이트 코드로 끝날 것이므로, 예를 들어 각 함수에 해당하는 바이트 코드를 byte []로 덤프 한 다음 두 바이트 코드 배열을 비교할 수 있습니다.

그러나, 의미 상 동등한 메소드를 작성하는 데에는 바이트 코드에서 동일한 표현을 사용하지 않는 많은 다른 방법이 있습니다.

일반적으로 코드를 실행하지 않고 코드의 기능을 파악하는 것은 불가능합니다. 따라서 가능한 모든 입력에 대해 두 비트를 모두 실행하지 않으면 두 비트의 코드가 동등한 지 여부를 알 수 없습니다.

이것은 적어도 계산적으로 말하면서 문제가 될 수도 있고, 악화 될 수도 있습니다.

중단 문제는 그대로 결정할 수 없으므로 여기서 일반적인 경우는 Clojure가 아니라 모든 프로그래밍 언어에 대한 대답입니다.

0

나는 다른 사람들의 훌륭한 답변에 덧붙일 수는 없지만 나를 도왔던 또 다른 의견을 제시하고자합니다. 예 : 올바른 함수가 자신의 함수에서 반환되는지 테스트합니다. 함수 객체를 비교하는 대신에 함수를 'symbol으로 반환하는 것만으로도 얻을 수 있습니다.

나는 이것이 저자가 요구 한 것이 아니지만 단순한 경우에 할 수 있음을 알고 있습니다.