2010-06-03 37 views
9

Toán tử đường ống trong prolog trả về một hoặc nhiều Thủ trưởng nguyên tử và danh sách Đuôi.[a | b | c] đánh giá trong SWI-Prolog là gì?

?- [a,b,c] = [a,b|[c]]. 
true. 

lồng nhau nhiều ống trong một trận đấu duy nhất có thể được thực hiện tương tự như sau:

?- [a,b,c] = [a|[b|[c]]]. 
true. 

Gì suy luận tuyên bố [a|b|c] về a, b và c?

EDIT

Cho đến nay, tất cả tôi có thể suy ra là:

?- [a,b,c] = [a|b|c]. 
false. 

Tôi quan tâm nhiều hơn trong bất kỳ kỹ thuật để tìm câu trả lời chứ không phải là để trả lời câu hỏi vô dụng đường biên giới này.

EDIT2
Tôi rõ ràng không phải là quá quen thuộc với prolog, một nhiệm vụ đơn giản trả lời câu hỏi của tôi ...

?- R = [a|b|c]. 
R = [a| (b'|'c)]. 

gì chính xác đang xảy ra với (b'|'c)?

+1

Có vẻ như bài tập về nhà với tôi. Nếu có, vui lòng gắn thẻ như vậy. –

+3

Tôi không quen với Prolog, nhưng, uhh, tại sao bạn không thể viết một chương trình nhanh để đánh giá nó? – Matchu

+3

Trên thực tế không, chỉ là một câu hỏi thú vị mà tôi tình cờ gặp khi đang học kỳ thi học kỳ tại uni: https://secure.csse.uwa.edu.au/run/help3242?p=np&a=99 Tôi đã dành một lúc câu hỏi của tôi để trông đẹp, mặc dù phù hợp cho một bài thi? :) – Ambrose

Trả lời

9

Vì tôi m giảng viên của bạn tôi, đây là câu trả lời của tôi.
(Ồ, và tôi có thể xác nhận rằng đây không phải là bài tập về nhà, nó liên quan đến bài kiểm tra thực hành).

Cú pháp [a|b|c] thực sự dường như không phải là chuẩn Prolog và một số triển khai diễn giải nó theo cách khác. (Tôi đã biết điều này có thể tôi đã không sử dụng nó.)

Một số diễn giải nó là [a|[b|c]]. (Như tôi đã dự định.)

Nhưng với SWI Prolog (và có lẽ những người khác):

?- [a|b|c] = [a|[b|c]]. 
false. 

Các (b '|' c) là thực sự xây dựng bằng '|' hơn '.' như một danh sách sẽ.Vì vậy, số thứ hai | không được hiểu là một phần của việc xây dựng danh sách.

Để khẳng định điều này, sau đây thành công:

 
    ?- X=(b|c), [a|b|c] = [a|X]. 
    X = (b'|'c) . 

Các '|' đây có vẻ là một khác điều hành nhị phân trên các điều khoản giống như '.'.

Thay vì [a|b|c] tiêu chuẩn trong Prolog là sử dụng [a,b|c].

(Tôi chỉ quyết định sử dụng [a|b|c] trong Paradigms Lập trình bởi vì nó trực tiếp hơn liên quan đến các ký hiệu a::b::c từ F #, và chúng tôi chỉ nhìn thấy một cái nhìn thoáng qua nhỏ của Prolog. Trong tương lai tôi đoán tôi sẽ liên hệ với [a|[b|c]] và sau đó cung cấp cho [a,b|c] dưới dạng viết tắt.)

+0

Ồ, đúng rồi! Vì vậy, '[a | b | c]' là cú pháp đường cho ''.' (A, (b '|' c))'!Vì vậy, toán tử '|' khác với '::' trong đó đuôi không nghiêm chỉnh cần phải là một danh sách, chỉ là một "điều"? Tôi vẫn đang cố gắng nuốt chính xác những gì nó có nghĩa là cho một ngôn ngữ để ** không ** có các loại ... – Ambrose

+1

Về mặt kỹ thuật ''.'' và'' | ''là các toán tử. Cả hai có thể được áp dụng cho bất kỳ hai thuật ngữ để tạo ra một loại một cặp - không giống như '::' trong F #/ML, nơi kiểm tra loại đảm bảo '::' chỉ được sử dụng cho cặp đầu và đuôi tương ứng. ''.'' gần như luôn được sử dụng cho danh sách, và cú pháp' [t1, t2 | t3] 'là viết tắt của' '.' (t1, '.' (t2, t3)) '. Nếu 't3' thực sự là' t4 | t5' thì '|' đó không phải là một phần của từ viết tắt, vì vậy bạn nhận được ''.' (t1, '.' (t2, (t4 '|' t5)))'. – RD1

+1

Hệ thống nào đã giải thích '[a | b | c]' thành '[a | [b | c]'? Xin vui lòng xem câu trả lời của tôi cho tiêu chuẩn. – false

5

Nó không phải là một tuyên bố, đó là một thuật ngữ, và nó không ngụ ý bất cứ điều gì cả về a, b hoặc c. Nó chỉ xây dựng một danh sách không đúng.

Để xây dựng: Cú pháp [|] thực sự là cú pháp đường cho toán tử .(). Danh sách được xây dựng bên trong thông qua '.'(a,[]), nhưng vì điều đó trở nên vô cùng tẻ nhạt để nhập ngay lập tức, bạn được phép viết [a] thay thế. Vì vậy, toán tử . được cho là có một danh sách và danh sách dài hơn, sau đó sẽ có một danh sách dài hơn, nhưng vì không có cách gõ, không ai ngăn cản bạn áp dụng nó vào hai nguyên tử hoặc bất kỳ thứ gì khác. Kết quả là một cấu trúc mà trên đó một số hoạt động danh sách thành công và một số khác thất bại. Điều này đôi khi hữu ích (nghĩ cây nhị phân), nhưng không phổ biến như danh sách, do đó không có cú pháp đọc đặc biệt cho nó.

(Điều tương tự cũng xảy ra với cons nhà điều hành trong Lisp;. Nếu bạn google "danh sách không đúng" bạn phải chịu trách nhiệm để có được nhiều kết quả hơn về Lisp, nhưng nguyên tắc là giống hệt nhau)

+0

Câu trả lời tuyệt vời, cảm ơn! Bất kỳ cơ hội nào bạn có thể cho tôi một con trỏ trong lần chỉnh sửa thứ hai của câu hỏi, với ''|''? – Ambrose

+0

Có, ngoại trừ trong SWI Prolog (và có thể là những người khác) thứ hai '|' không được hiểu là '.'. – RD1

5

Trong ISO-Prolog, [a|b|c] là cú pháp không hợp lệ. Và trong thời gian chờ đợi cũng trong SWI. Có vẻ như bạn đã sử dụng phiên bản cũ hơn. Một số hệ thống Prolog đưa ra thuật ngữ này một số giải thích. Than ôi, tất cả chúng đều khác nhau theo cách rất chính xác cách chúng diễn giải thuật ngữ đó. Một số là [(a'|'b)|c] hoặc [a|(b'|'c)] hoặc [a|(b;c)] ... tốt, bạn hiểu.

Liên quan đến điều này là việc sử dụng thanh như một toán tử kết hợp ('|')/2.

Với ISO/IEC 13211-1:1995/Cor.2:2012, Corrigendum kỹ thuật 2, xuất bản 2012-02-15 việc sử dụng thanh | làm toán tử kết xuất giờ đây được xác định chính xác. Trước đó, | phải được trích dẫn. Ở đây is its draft.

Bây giờ, '|' có thể được định nghĩa là một nhà điều hành ghi nhưng chỉ với một ưu tiên cao hơn 1000. Theo cách này các trường hợp khác mơ hồ như [a|b|c] vẫn cú pháp không hợp lệ, nhưng sử dụng của | cho DCG và CHR là hợp lệ.

Nếu bạn muốn tìm hiểu cú pháp bằng cách dùng thử, tốt nhất là sử dụng writeq/1write_canonical/1.

Cú pháp ISO-Prolog phù hợp nhất với cú pháp ISO-Prolog là GNU Prolog.

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