2012-02-22 34 views
13

Giả sử tôi có các chức năng clojure sau:Clojure - kiểm tra tính bình đẳng của biểu thức hàm?

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

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

(def c (eval (read-string "(defn d [x] (* x x))"))) 

Có cách nào để kiểm tra sự bình đẳng của các biểu hiện chức năng - một số tương đương với

(eqls a b) 

trả về true?

+1

Không thể - tương đương với các chức năng là không thể xác định. –

+0

Rất tiếc, xin lỗi về định dạng nhận xét tiền thưởng - đã không nhận ra định dạng sẽ không hoạt động theo cùng một cách. –

+1

Xin chào Omri. Nếu bạn nhìn thấy câu trả lời của tôi dưới đây, bạn sẽ thấy rằng tôi nói về hai hàm có cùng bytecode JVM làm cơ thể của chúng. Đó là sự bình đẳng về mặt hiệu quả. Tôi cũng làm cho điểm rằng bình đẳng gia tăng hàm ý sự bình đẳng mở rộng (nhưng ngược lại là không đúng). Nếu bytecode kết thúc là khác nhau (vì nó có thể cho một số ví dụ mà bạn đưa ra), thì chúng ta quay trở lại cố gắng để đạt được bình đẳng mở rộng - mà như chúng ta biết là không thể xác định được.Hy vọng rằng làm cho mọi thứ một chút rõ ràng hơn - bình đẳng (cộng với một số trường hợp đặc biệt) có lẽ là tốt nhất chúng ta có thể hy vọng. – kittylyst

Trả lời

3

Tôi đồng ý với các câu trả lời ở trên liên quan đến Clojure không có khả năng xác định tính tương đương của hai chức năng và đã chứng minh rằng bạn không thể kiểm tra các chương trình chức năng (còn được gọi là kiểm tra hộp đen) bình đẳng do vấn đề dừng (trừ khi bộ đầu vào là hữu hạn và được xác định).

Tôi muốn chỉ ra rằng có thể xác định tương đương đại số của hai hàm, ngay cả khi chúng có các dạng khác nhau (mã byte khác nhau).

Phương pháp chứng minh đại số tương đương đã được phát triển vào những năm 1930 bởi Giáo hội Alonzo và được biết là giảm beta trong Calculus Lambda. Phương pháp này chắc chắn áp dụng cho các biểu mẫu đơn giản trong câu hỏi của bạn (cũng sẽ mang lại cùng một mã byte) và cũng cho các biểu mẫu phức tạp hơn có thể mang lại các mã byte khác nhau.

11

Nó phụ thuộc vào chính xác ý bạn là "bình đẳng của biểu thức hàm".

Các chức năng này sẽ kết thúc dưới dạng mã byte, vì vậy tôi có thể ví dụ đổ bytecode tương ứng với từng hàm thành một byte [] và sau đó so sánh hai mảng bytecode.

Tuy nhiên, có nhiều cách khác nhau để viết các phương thức tương đương ngữ nghĩa, sẽ không có cùng biểu diễn trong bytecode.

Nói chung, không thể nói được một đoạn mã nào không hoạt động. Vì vậy, nó không thể nói cho dù hai bit mã tương đương mà không cần chạy cả hai mã, trên tất cả các đầu vào có thể.

Điều này ít nhất là xấu, tính toán, là sự cố tạm dừng và có thể tệ hơn.

Sự cố tạm dừng là không thể giải quyết được, vì vậy câu trả lời chung ở đây chắc chắn là không (và không chỉ cho Clojure mà là cho mọi ngôn ngữ lập trình).

0

Tôi không thể thêm vào câu trả lời tuyệt vời của người khác, nhưng muốn cung cấp một quan điểm khác đã giúp tôi. Nếu bạn là kiểm tra xem hàm chính xác có được trả về từ hàm của riêng bạn hay không, thay vì so sánh đối tượng hàm bạn có thể lấy đi chỉ bằng cách trả về hàm là 'symbol.

Tôi biết điều này có lẽ không phải là tác giả yêu cầu nhưng đối với những trường hợp đơn giản, nó có thể làm.

Các vấn đề liên quan