21

Tôi biết trong Prolog bạn có thể làm một cái gì đó giống nhưngôn ngữ lập trình không xác định

someFunction(List) :- 
    someOtherFunction(X, List) 
    doSomethingWith(X) 
    % and so on 

này sẽ không lặp qua tất cả các phần tử trong Danh mục; thay vào đó, nó sẽ phân nhánh thành các "máy" khác nhau (bằng cách sử dụng nhiều chủ đề, backtracking trên một chủ đề duy nhất, tạo ra các vũ trụ song song hoặc cho bạn), với một thực thi riêng biệt cho mọi giá trị có thể có của X gây ra someOtherFunction(X, List). !
(Tôi không có ý tưởng làm thế nào nó thực hiện điều này, nhưng đó không phải là quan trọng đối với câu hỏi)

Câu hỏi của tôi là: gì ngôn ngữ lập trình phi determistic khác được ra khỏi đó? Dường như khái niệm không xác định là cách đơn giản và hợp lý nhất để thực hiện đa luồng trong một ngôn ngữ với các biến không thay đổi, nhưng tôi chưa từng thấy điều này trước đây - Tại sao kỹ thuật này không phổ biến hơn?

+0

Và có, điều này rất giống với câu hỏi cuối cùng của tôi: http://stackoverflow.com/questions/2174535/multithreading-in-functional-languages-prolog Tôi hỏi một câu hỏi mới bởi vì dường như tôi đã đọc từ cuối cùng kém; mọi người bắt đầu tranh luận về các chi tiết cụ thể của Prolog, nhưng tôi không thực sự về Prolog. –

+0

Google, chủ yếu là trợ giúp. Ví dụ: http://en.wikipedia.org/wiki/Nondeterministic_programming là những gì tôi tìm thấy. cái đó có giúp ích không? – dirkgently

+0

Điều đó đưa ra một vài (3) ví dụ, nhưng không thực sự giải thích tại sao không xác định không được sử dụng, ví dụ, hầu hết các ngôn ngữ chức năng –

Trả lời

15

Prolog thực sự là xác định — thứ tự đánh giá được quy định và sắp xếp các vấn đề.

Tại sao tính không xác định không phổ biến hơn?

Nondeterminism là không được ưa chuộng vì nó làm cho nó khó khăn hơn để suy luận về kết quả của chương trình của bạn, và thật sự không xác định hành (như trái ngược với ngữ nghĩa) rất khó để thực hiện.

Các ngôn ngữ không xác định duy nhất tôi biết là

  • calculus Dijkstra các lệnh canh gác, mà ông muốn không bao giờ được thực hiện

  • đồng thời ML, trong đó thông tin liên lạc có thể được đồng bộ nondeterministically

  • Ngôn ngữ Promela của Gerard Holzmann, là ngôn ngữ của trình kiểm tra mô hình SPIN

SPIN thực sự sử dụng tính không xác định và khám phá toàn bộ không gian trạng thái khi có thể. Và tất nhiên mọi ngôn ngữ đa luồng đều hoạt động không xác định nếu các chủ đề không được đồng bộ hóa, nhưng đó chính xác là điều khó giải thích về — và tại sao nó lại khó thực hiện các cấu trúc dữ liệu không khóa, hiệu quả.

Ngẫu nhiên, nếu bạn muốn đạt được tính song song, bạn có thể đạt được điều tương tự bằng chức năng đơn giản map bằng ngôn ngữ chức năng thuần túy như Haskell. Có một lý do khiến Google MapReduce dựa trên các ngôn ngữ chức năng.

+0

Tôi chắc chắn bạn có thể * đạt được * điều tương tự với 'map', nhưng tôi không chắc nó tầm thường như bạn làm cho nó âm thanh. Ví dụ, mã mà tôi đã cung cấp không có gì để làm với việc lặp lại các phần tử của 'List' -' someOtherFunction() 'có thể là bất kỳ thứ gì (ví dụ: checksum của' List' có các bit 'X')! Ngoài ra còn có tính không xác định trong các hàm - trong Prolog, bạn có thể viết một số định nghĩa của một hàm, và tất cả chúng sẽ được gọi (nếu bất kỳ trở về đúng, kết quả là đúng). * Tại sao * sẽ khó thực hiện điều này bằng cách sử dụng các luồng riêng biệt? Vì tất cả các biến đều không thay đổi nên chúng ta không cần khóa, phải không? –

+0

Tôi downvoted câu trả lời vì tôi sẽ không nói rằng Prolog là xác định trong một ý nghĩa cụ thể của xác định được sử dụng trong CS. Có một cảm giác liên quan đến ngữ nghĩa chương trình, và Prolog thực sự là một ngữ nghĩa chương trình không xác định mặc dù tìm kiếm đầu tiên chiều sâu là không đầy đủ. Mỗi biến vị ngữ định nghĩa một mối quan hệ giữa thay thế và thay thế câu trả lời được tinh chỉnh. Ngôn ngữ lập trình chức năng đi khá vào một thời gian dài monads, tiếp tục, vv .. để lưu trữ đó. –

1

Tôi tin rằng Haskell có khả năng xây dựng và không xác định máy. Haskell lúc đầu có thể có vẻ quá khó khăn và trừu tượng để sử dụng thực tế, nhưng nó thực sự rất mạnh mẽ.

1

Java 2K

Lưu ý: Trước khi bạn nhấp vào liên kết và bị thất vọng: Đây là một ngôn ngữ esoteric và không có gì để làm với xử lý song song.

+0

Khi tôi nói "không xác định", tôi có nghĩa là chương trình sẽ thực hiện mọi đường dẫn. Chương trình này không phải là không xác định theo nghĩa đó, mặc dù nó chắc chắn không phải là xác định. –

6

Wikipedia article trỏ đến Amb là một phương án có tính dẫn suất với chương trình không xác định. Theo tôi hiểu, lý do chính tại sao ngôn ngữ lập trình không làm điều đó là bởi vì chạy một chương trình không xác định trên một máy tính xác định (như tất cả các máy tính hiện có) vốn là đắt tiền. Về cơ bản, một máy Turing không xác định có thể giải quyết các vấn đề phức tạp trong thời gian đa thức, mà không có thuật toán đa thức nào cho một máy Turing xác định được biết đến. Nói cách khác, lập trình không xác định không nắm bắt được bản chất của thuật toán trong ngữ cảnh của các máy tính hiện có.

Cùng một vấn đề ảnh hưởng đến Prolog. Bất kỳ ứng dụng Prolog hiệu quả, hoặc ít nhất là không khủng khiếp không hiệu quả phải sử dụng toán tử "cut" để tránh khám phá một số đường dẫn. Toán tử đó chỉ hoạt động chừng nào người lập trình có một cái nhìn tinh thần tốt về cách mà người thông dịch Prolog sẽ khám phá những con đường có thể, theo cách xác định và rất thủ tục. Những thứ rất thủ tục không kết hợp tốt với lập trình hàm, vì sau này hầu hết là một nỗ lực không suy nghĩ về mặt thủ tục.

Là một lưu ý phụ, giữa các máy Turing xác định và không xác định, có mô hình "tính toán lượng tử". Một máy tính lượng tử, giả sử rằng một máy tính tồn tại, không làm mọi thứ mà một máy Turing không xác định có thể làm, nhưng nó có thể làm nhiều hơn một máy Turing xác định. Có những người hiện đang thiết kế các ngôn ngữ lập trình cho máy tính lượng tử (giả sử rằng một máy tính lượng tử cuối cùng sẽ được xây dựng). Một số trong những ngôn ngữ mới là chức năng. Bạn có thể tìm thấy một loạt các liên kết hữu ích trên số Wikipedia page này. Rõ ràng, thiết kế một ngôn ngữ lập trình lượng tử, chức năng hay không, và sử dụng nó, không phải là dễ dàng và chắc chắn không phải là "đơn giản".

1

Có ngôn ngữ lập trình cho các vấn đề không xác định được gọi là "lập trình mạng điều khiển". Nếu bạn muốn biết thêm thông tin, hãy truy cập http://controlnetworkprogramming.com. Trang web này vẫn đang được tiến hành nhưng bạn có thể đọc một số thông tin về trang web đó.

4

Một ví dụ về ngôn ngữ không xác định là Occam, dựa trên lý thuyết CSP. Sự kết hợp của các cấu trúc PARALT có thể làm phát sinh hành vi không xác định trong các hệ thống đa xử lý, thực hiện các chương trình fine grain parallel.

Khi sử dụng kênh mềm, tức là kênh giữa các quá trình trên cùng một bộ xử lý, việc triển khai ALT sẽ làm cho hành vi gần với xác định & dagger;, nhưng ngay sau khi bạn bắt đầu sử dụng các kênh cứng (các liên kết truyền thông ngoài bộ xử lý vật lý), bất kỳ ảo ảnh nào về tính quyết định đều biến mất. Các bộ xử lý từ xa khác nhau sẽ không được đồng bộ theo bất kỳ cách nào và chúng thậm chí không có cùng tốc độ lõi hoặc đồng hồ.

& dagger; Cấu trúc ALT thường được triển khai với PRI ALT, vì vậy bạn phải viết mã công bằng nếu bạn cần công bằng.


Non-định mệnh được xem là một bất lợi khi nói đến lý luận về chương trình và chứng minh chính xác, nhưng theo nhiều cách một khi bạn đã chấp nhận nó, bạn được giải phóng khỏi nhiều khó khăn mà lực lượng định mệnh trên lý do của bạn.

Chừng nào các trình tự của thông tin liên lạc không dẫn đến deadlock, có thể được thực hiện bằng cách áp dụng kỹ thuật CSP, sau đó theo thứ tự chính xác trong đó mọi thứ được thực hiện nên quan trọng ít hơn nhiều hơn cho dù bạn có được kết quả mà bạn muốn kịp thời. Có thể cho rằng việc thiếu sự quyết định này là yếu tố chính ngăn cản việc áp dụng hệ thống Occam và Transputer trong các dự án quân sự, được thống trị bởi Ada vào thời điểm đó, nơi biết chính xác CPU đang làm gì ở mỗi chu kỳ đồng hồ. cần thiết để chứng minh một hệ thống chính xác. Không có sự hạn chế này, các hệ thống Occam và Transputer mà nó chạy trên (các CPU duy nhất vào thời điểm đó với việc thực thi điểm nổi đã được chứng minh chính thức) sẽ là một sự phù hợp hoàn hảo cho các hệ thống quân sự thời gian thực cần các chức năng xử lý cao. không gian.

1

Ngôn ngữ lập trình Sly đang được phát triển tại IBM Research là một nỗ lực để bao gồm tính không xác định vốn có trong thực thi đa luồng trong việc thực thi một số loại thuật toán nhất định. Có vẻ như rất nhiều công việc đang diễn ra.

4

Trong Prolog bạn có thể có cả tính không xác định và đồng thời. Không xác định là những gì bạn mô tả trong câu hỏi của bạn liên quan đến mã ví dụ. Bạn có thể tưởng tượng rằng một mệnh đề Prolog có đầy đủ các câu lệnh ngụ ý amb. Nó ít được biết rằng concurrency cũng được hỗ trợ bởi lập trình logic.

Lịch sử nói:

Ngôn ngữ lập trình logic đồng thời đầu tiên là Relational Ngôn ngữ của Clark và Gregory, là một nhánh của IC-Prolog. Các phiên bản sau của lập trình logic đồng thời bao gồm Ngôn ngữ Giềng bảo vệ đồng thời của Prolog và Ueda của Shapiro. https://en.wikipedia.org/wiki/Concurrent_logic_programming

Nhưng hôm nay chúng tôi có thể chỉ đi với các bước bên trong lập trình logic. Here là ví dụ để triển khai tìm kiếm thông qua chuỗi. Điều này cũng có thể được modded để thực hiện tất cả các loại nhiệm vụ trên bộ sưu tập, hoặc thậm chí có thể sản xuất các mạng lưới đại lý hướng tới trí thông minh nhân tạo phân tán.

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