2009-07-15 26 views
28

Không thể biết hai hàm có tương đương không? Ví dụ, một trình soạn thảo trình biên dịch muốn xác định xem hai hàm mà nhà phát triển đã viết có thực hiện cùng một hoạt động hay không, những phương thức nào mà anh ta có thể sử dụng để tìm ra một hàm nào đó? Hoặc chúng ta có thể làm gì để tìm ra rằng hai TM là giống hệt nhau? Có cách nào để bình thường hóa máy không?Tìm thấy sự tương đương của hai chức năng không thể xác định?

Chỉnh sửa: Nếu trường hợp chung là không thể xác định, bạn cần bao nhiêu thông tin trước khi bạn có thể nói chính xác hai hàm tương đương?

Trả lời

41

Với một chức năng tùy ý, f, chúng ta định nghĩa một hàm f' trả về trên đầu vào n nếu f tạm dừng trên đầu vào n. Bây giờ, đối với một số số x chúng ta định nghĩa một hàm g đó, trên đầu vào n, trả nếu n = x, và nếu không gọi f '(n).

Nếu tương đương chức năng đã decidable, sau đó quyết định có g giống hệt f' quyết định liệu f tạm dừng trên đầu vào x. Điều đó sẽ giải quyết được Halting problem. Liên quan đến cuộc thảo luận này là Rice's theorem.

Kết luận: chức năng tương đương là không thể xác định.


Có một số thảo luận dưới đây về tính hợp lệ của bằng chứng này. Vì vậy, hãy để tôi xây dựng trên những gì các bằng chứng hiện, và cung cấp cho một số mã ví dụ trong Python.

  1. Các giấy tờ chứng minh tạo ra một hàm f' mà trên đầu vào n bắt đầu để tính toán f (n). Khi tính toán này kết thúc, f' trả về 1. Như vậy, f '(n) = 1 khi và chỉ khi f tạm dừng trên đầu vào n, và f' không ngừng trên n iff f doesn 't. Python:

    def create_f_prime(f): 
        def f_prime(n): 
         f(n) 
         return 1 
        return f_prime 
    
  2. Sau đó chúng ta tạo một hàm g mà mất n như đầu vào, và so sánh nó với một số giá trị x. Nếu n = x, thì g (n) = g (x) = 1, khác g (n) = f '(n). Python:

    def create_g(f_prime, x): 
        def g(n): 
         return 1 if n == x else f_prime(n) 
        return g 
    
  3. Bây giờ Bí quyết là, mà cho tất cả n = x chúng tôi có mà g (n) = f '(n)!. Hơn nữa, chúng tôi biết rằng g (x) = 1. Vì vậy, nếu g = f ', thì f' (x) = 1 và do đó f (x) tạm dừng. Tương tự, nếu g! = F ' thì nhất thiết phải f' (x)! = 1, có nghĩa là f (x) không dừng lại. Vì vậy, hãy quyết định xem g = f ' có tương đương với việc quyết định xem f tạm dừng trên đầu vào x hay không. Sử dụng một ký hiệu hơi khác nhau cho hai chức năng trên, chúng ta có thể tóm tắt tất cả điều này như sau:

    def halts(f, x): 
        def f_prime(n): f(n); return 1 
        def g(n): return 1 if n == x else f_prime(n) 
        return equiv(f_prime, g) # If only equiv would actually exist... 
    

Tôi cũng sẽ quăng trong một minh chứng bằng chứng trong Haskell (GHC thực hiện một số phát hiện vòng lặp, và tôi không thực sự chắc chắn cho dù việc sử dụng các seq là đánh lừa bằng chứng trong trường hợp này, nhưng dù sao):

-- Tells whether two functions f and g are equivalent. 
equiv :: (Integer -> Integer) -> (Integer -> Integer) -> Bool 
equiv f g = undefined -- If only this could be implemented :) 

-- Tells whether f halts on input x 
halts :: (Integer -> Integer) -> Integer -> Bool 
halts f x = equiv f' g 
    where 
    f' n = f n `seq` 1 
    g n = if n == x then 1 else f' n 
+6

+1 để đồng ý với tôi nhưng với tính toán gợi cảm. – chaos

+7

+1, nhưng điều này đặt ra một câu hỏi khác: Bộ giới hạn tối thiểu cần thiết để đưa ra quyết định này là gì?Rõ ràng, nếu tập hợp đầu vào được xác định là đủ nhỏ, và giới hạn được giới thiệu đến thời gian thực hiện, cả hai hàm đều có thể bị ép buộc. – l0b0

+0

"Khi nào một điều tương đương với một số điều khác" - www.math.harvard.edu/~mazur/preprints/when_is_one.pdf – nlucaroni

0

Bạn có thể kiểm tra trình biên dịch xem chúng có chính xác giống hệt nhau hay không, nhưng xác định xem chúng có trả về các giá trị giống nhau không khó và tốn thời gian. Bạn sẽ phải về cơ bản gọi phương thức đó và thực hiện thường trình của nó qua một số lượng vô hạn các cuộc gọi có thể và so sánh giá trị với nó từ một thói quen khác.

Thậm chí nếu bạn có thể thực hiện ở trên, bạn sẽ phải tính toán giá trị toàn cục thay đổi trong hàm, đối tượng nào bị hủy/thay đổi trong hàm không ảnh hưởng đến kết quả.

Bạn thực sự chỉ có thể so sánh mã được biên dịch. Vì vậy, biên dịch mã biên dịch để refactor?

Hãy tưởng tượng thời gian chạy khi cố gắng biên dịch mã bằng trình biên dịch "đó". Bạn có thể dành rất nhiều thời gian ở đây trả lời các câu hỏi nói rằng: "biên soạn bận rộn ..." :)

+0

Các giải pháp khả thi duy nhất sẽ là một hộp kính có liên quan đến các nhà lý thuyết định lý và tương tự. Một giải pháp bạo lực sẽ dễ dàng bị cản trở bởi một cặp chức năng mà không dừng lại trong một số trường hợp. – BCS

2

Trong trường hợp chung, không thể xác định được liệu hai máy xử lý có luôn luôn là đầu ra tương tự cho đầu vào giống nhau hay không. Vì bạn thậm chí không thể quyết định liệu một tm sẽ dừng lại trên đầu vào, tôi không thấy làm thế nào nó có thể quyết định liệu cả hai đều dừng và xuất kết quả tương tự ...

+1

Điều này là không đủ. Cũng có thể cho thấy rằng 2 chức năng sẽ dẫn đến hiệu ứng tương tự (bao gồm ngắt hoặc không) mà không hiển thị bất cứ điều gì về những gì chúng làm (cho người trả lời như "cả hai sẽ trả lại kết quả tương tự hoặc không dừng lại, nhưng tôi không biết cái nào ") – BCS

7

Có, nó là không thể xác định. Đây là một hình thức của halting problem.

Lưu ý rằng tôi có nghĩa là nó không thể giải quyết cho trường hợp chung. Cũng như bạn có thể xác định tạm dừng cho các chương trình đủ đơn giản, bạn có thể xác định tính tương đương cho các hàm đủ đơn giản và không thể tưởng tượng được rằng điều này có thể là một số ứng dụng cho một ứng dụng. Nhưng bạn không thể đưa ra một phương pháp chung để xác định sự tương đương của hai hàm có thể có.

0

tôi nghĩ rằng nếu bạn cho phép tác dụng phụ, bạn có thể thấy rằng vấn đề có thể được biến thành các Post correspondence problem nên bạn không thể, nói chung, hiển thị nếu hai hàm thậm chí là có khả năng có cùng tác dụng phụ.

4

Trường hợp chung là không thể xác định theo định lý của gạo, như những người khác đã nói (Định lý của Rice về cơ bản nói rằng bất kỳ tài sản phi thường nào của một hình thức hoàn chỉnh Turing là không thể xác định).

Có những trường hợp đặc biệt mà sự tương đương là có thể giải mã được, ví dụ nổi tiếng nhất có lẽ là tương đương với tự động hóa trạng thái hữu hạn. Nếu tôi nhớ chính xác tương đương của tự động đẩy xuống là đã không thể giải quyết được bằng cách giảm xuống bài viết của Correspondence Problem.

Để chứng minh rằng hai hàm nhất định là tương đương, bạn sẽ yêu cầu nhập vào bằng chứng về sự tương đương trong một số hình thức, sau đó bạn có thể kiểm tra tính chính xác. Các phần thiết yếu của chứng minh này là các bất biến vòng lặp, vì chúng không thể được bắt nguồn tự động.

0

Không thể biết hai hàm có tương đương không?

Không. Có thể biết rằng hai hàm tương đương nhau. Nếu bạn có f (x), bạn biết f (x) tương đương với f (x).

Nếu câu hỏi là "có thể xác định nếu f (x) và g (x) tương đương với f và g là bất kỳ hàm nào và cho tất cả các hàm g và f", thì câu trả lời là không. Tuy nhiên, nếu câu hỏi là "một trình biên dịch có thể xác định rằng nếu f (x) và g (x) tương đương với chúng tương đương không?", Thì câu trả lời là có nếu chúng tương đương ở cả đầu ra lẫn tác dụng phụ và thứ tự của các tác dụng phụ. Nói cách khác, nếu người ta là một sự biến đổi của người khác bảo tồn hành vi, thì trình biên dịch đủ phức tạp sẽ có thể phát hiện nó. Nó cũng có nghĩa là trình biên dịch có thể chuyển đổi một hàm f thành một hàm tối ưu và tương đương hơn g cho một định nghĩa cụ thể về tương đương. Sẽ thú vị hơn nếu f bao gồm hành vi không xác định, vì sau đó g cũng có thể bao gồm hành vi không xác định (nhưng khác)!

+0

Tôi nghĩ xác nhận thứ 3 của bạn là sai. Tôi nghĩ rằng không có giải pháp chung tồn tại cho việc chứng minh hai chức năng là tương đương vì có các đối số thuyết phục (xem câu trả lời của Stephan202) rằng điều này có thể yêu cầu giải quyết vấn đề dừng. – BCS

+0

Tôi đã không nói điều đó, nhưng stackoverflow ăn phản ứng lâu hơn của tôi. Tôi hạn chế vấn đề để chứng minh rằng hai hàm tương đương có thể được phát hiện là tương đương. Các COMDAT gấp được sử dụng bởi các liên kết MSVC làm điều đó. – MSN

2

Tùy thuộc vào ý nghĩa của "chức năng".

Nếu các chức năng bạn đang nói đến được đảm bảo chấm dứt - ví dụ, vì chúng được viết bằng ngôn ngữ mà tất cả các chức năng chấm dứt - và hoạt động trên các miền hữu hạn, nó "dễ" (mặc dù nó vẫn có thể một thời gian rất dài): hai hàm tương đương nếu và chỉ khi chúng có cùng giá trị tại mọi điểm trong miền chia sẻ của chúng.

Điều này được gọi là tương đương "mở rộng" để phân biệt nó với cú pháp hoặc "tương đương". Hai hàm tương đương với nhau nếu chúng tương đương về mặt trực tiếp, nhưng ngược lại không giữ.

(Tất cả những người khác trên lưu ý rằng nó là undecidable trong trường hợp nói chung là khá đúng, tất nhiên, đây là một cách khá phổ biến - và thường không thú vị trong thực tế -. Trường hợp đặc biệt)

+0

Vì vậy, nếu chúng ta muốn so sánh hai hàm 'total' (những cái dừng trên mọi đầu vào) và trả về yes nếu chúng khớp với mọi đầu vào, không có cách nào khác. Làm thế nào để chứng minh rằng vấn đề này là không thể giải quyết (là nó)? – mercury0114

+0

Nếu có nhiều đầu vào trong miền và cả hai chức năng đều dừng lại cho tất cả chúng, và bạn có kiểm tra bình đẳng có thể giải mã cho tên miền, thì bạn chỉ cần thử cả hai hàm trên tất cả các đầu vào và so sánh kết quả đầu ra. –

+0

Điều gì xảy ra nếu có quá nhiều đầu vào? – mercury0114

2

Lưu ý rằng vấn đề dừng là decidable cho automata bounded tuyến tính. Các máy tính thực luôn bị ràng buộc và các chương trình cho chúng sẽ luôn quay trở lại cấu hình trước đó sau nhiều bước. Nếu bạn đang sử dụng một máy tính không bị chặn (tưởng tượng) để theo dõi các cấu hình, bạn có thể phát hiện vòng lặp đó và tính đến nó.

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