2016-07-01 15 views
5

Đây là một quan sát đầu tiên:is_list/1 và biến miễn phí

?- is_list([]), is_list([_,_,_]). 
true. 

Dưới đây là một quan sát:

?- [] = _, [_,_,_] = _. 
true. 

Vì vậy, tại sao is_list/1 được thực hiện như vậy mà

?- is_list(_). 
false. 

hoặc

?- is_list([_|_]). 
false. 

khi _ có thể được thống nhất rõ ràng với danh sách? Điều đó sẽ không hợp lý hơn khi nó là true?

Trong SWI-Prolog's documentation for is_list/1, một lưu ý nói:

Trong các phiên bản trước 5.0.1, is_list/1 chỉ cần kiểm tra cho [] hoặc [_|_]proper_list/1 có vai trò của hiện tại is_list/1. Định nghĩa hiện tại phù hợp với tiêu chuẩn thực tế.

Tại sao tiêu chuẩn thực tế?

Trả lời

6

Khi quan sát một cách chính xác, is_list/1không lành mạnh, hay đúng hơn là không đầy đủ , bởi vì nó sai nói rằng có không có giải pháp nào khi truy vấn chung nhất được đặt ra.

 
?- is_list(Ls). 
false. 

Không có danh sách? Thôi nào!

đặc điểm đáng tiếc này được chia sẻ bởi tất cả các loại di truyền kiểm tra các vị từ như atom/1, integer/1   vv mà incorrectness Rõ ràng HLV đã khi những vị đã được hình thành nhưng đã đẩy thông qua sau khi ghi nhãn những người phản đối một cách chính xác ngữ nghĩa được gợi ý của họ là "chủ nghĩa thuần túy" (trong đó, tại thời điểm đó, thiếu nhân vật miễn phí từ đó đã có được).

trường hợp như:

 
?- is_list(Ls), Ls = []. 
false. 

?- Ls = [], is_list(Ls). 
Ls = []. 

minh họa rõ ràng rằng một cái gì đó về cơ bản bị phá vỡ từ một điểm hợp lý xem có như vậy không đơn điệu   kiểm tra. "Prolog's (,)/2 không phải là sự kết hợp logic", vâng, nếu bạn sử dụng các biến vị ngữ bất hợp pháp ở vị trí đầu tiên trong mã của bạn. Nếu không, (,)/2 luôn là kết hợp logic của các mục tiêu.

Cách dọn dẹp chính xác và hợp lý là để ném lỗi instantiation trong trường hợp chưa xác định được.

library(error) và đặc biệt must_be/2 đi vào một hướng đi âm thanh sau khi incorrectness các vị vô lý di truyền đã trở thành không thể chịu đựng ngay cả đối với người dùng bình thường của   Prolog:

 
?- must_be(list, X). 
Arguments are not sufficiently instantiated 

?- must_be(list, [_|_]). 
Arguments are not sufficiently instantiated 

?- must_be(list, [a,b,c]). 
true. 

must_be/2 là dễ sử dụng và một tốt đầu tiên bước tới các chương trình logic chính xác hơn. Các cấu trúc khác cũng xuất hiện trên đường chân trời và tôi hy vọng những người khác nhận xét về trạng thái hiện tại.

Và bây giờ cho các từ ngữ thực tế: Bỏ qua những vấn đề cơ bản nêu trên, các tranh ám chỉ trong các tài liệu SWI   là liệu kiểm tra functor ngoài cùng cũng đủ để coi một thuật ngữ như một danh sách, hoặc cho dù danh sách phải thực sự tuân theo định nghĩa quy nạp của danh sách, là:

  • nguyên tử [] là danh sách.
  • nếu Ls là một danh sách, sau đó '.'(_, Ls) là một danh sách.

Lưu ý rằng trong các phiên bản SWI gần đây, [] thậm chí không phải là nguyên tử, do đó, nó lại vi phạm với khái niệm này.

+3

Nhưng 'must_be (danh sách, non_list) 'tạo ra một lỗi loại khi một thất bại đơn giản có thể thích hợp hơn. Có thể ['itype'] (http://stackoverflow.com/a/30600104/772868) là một giải pháp. – false

+1

Vâng, một trong hai điều này, hoặc có thể là một lá cờ có thể biến gõ lỗi vào thất bại im lặng? – mat

+1

Vấn đề thực tế đi kèm với các mục tiêu thành công như là kết quả của một số thất bại thầm lặng. Đây là lý do tại sao ngay cả ý tưởng "thất bại thầm lặng" cho tôi creep — nó chỉ cầu xin rắc rối ... nó sẽ đòi hỏi một số cách để đảm bảo sự im lặng thất bại là ** không được sử dụng khi chứng minh một số mục tiêu. – repeat

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