Подтвердить что ты не робот

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?

4b9b3361

Ответ 1

Я согласен с вышеприведенными ответами в отношении Clojure, не имеющим встроенной способности определять эквивалентность двух функций и что было доказано, что вы не можете тестировать программы функционально (также известный как тестирование черного ящика) на определить равенство из-за проблемы с остановкой (если только входное множество не определено и не определено).

Я хотел бы указать, что алгебраически можно определить эквивалентность двух функций, даже если они имеют разные формы (разные байтовые коды).

Метод доказательства алгебраичности эквивалентности был разработан в 1930 году церковью Алонсо и известен как бета-сокращение в исчислении лямбда. Этот метод, безусловно, применим к простым формам в вашем вопросе (который также даст один и тот же байтовый код), а также для более сложных форм, которые будут давать разные байтовые коды.

Ответ 2

Это зависит от того, что вы подразумеваете под "равенством выражения функции".

Эти функции будут заканчиваться как байт-код, поэтому я мог бы, например, сбросить байт-код, соответствующий каждой функции, в байт [], а затем сравнить два байт-кода.

Однако существует много разных способов написания семантически эквивалентных методов, которые не будут иметь одинакового представления в байт-коде.

В общем, невозможно сказать, что делает код без его запуска. Таким образом, невозможно определить, эквивалентны ли два бита кода, не запуская оба из них, на всех возможных входах.

Это, по крайней мере, так же плохо, как вычислительная работа, как проблема с остановкой и, возможно, хуже.

Проблема с остановкой неразрешима, так как в общем случае ответ здесь определенно нет (и не только для Clojure, но и для каждого языка программирования).

Ответ 3

Я не могу добавить отличные ответы других, но хотел бы предложить другую точку зрения, которая помогла мне. Если вы, например, что правильная функция возвращается из вашей собственной функции, вместо сравнения объекта функции, с которым вы могли бы уйти, просто вернув функцию как 'symbol.

Я знаю, что это, вероятно, не то, о чем просил автор, а о простых случаях, которые он мог бы сделать.