Sử dụng các toán tử số học làm các hàm xây dựng và cặp khuyết điểm
Nếu bạn cần vượt qua một cấu trúc duy nhất bao gồm hai hoặc nhiều giá trị, điều rõ ràng nhất để sử dụng là một danh sách, ví dụ [A,B]
. Điều đó thực sự dài dòng, mặc dù.
Có một sự thay thế. Các giá trị Prolog có thể lưu trữ một cấu trúc lồng nhau tùy ý, không được đánh giá. Đây là một ví dụ cho thấy cách thức hoạt động:
| ?- member(member(A,B),C).
C = [member(A,B)|_] ? ;
C = [_,member(A,B)|_] ? ;
(etc.)
member(A,B)
chỉ là một tuple được đặt tên trong tình huống này và bên ngoài member
(là một lời gọi hàm) đang xử lý nó như vậy.
Mặc dù các bộ dữ liệu được đặt tên khá hữu ích trong lập trình Prolog không chơi gôn, chúng có thể thậm chí còn dài dòng hơn so với cách tiếp cận danh sách. Tuy nhiên, chúng ta có thể sử dụng khá nhiều ký tự tùy ý trong tên của hàm tạo tuple (giả sử chúng được trích dẫn chính xác); thay vì một cái gì đó dễ thương như member
hoặc một nhân vật như thế a
, chúng ta có thể làm một cái gì đó như thế này:
| ?- A = '-'('/'(1,2), '/'(3,4)).
A = 1/2-3/4
Ở đây, các nhà xây dựng tuple của chúng tôi là '-'
và '/'
. Và thật thú vị khi lưu ý những gì máy in đẹp đã làm với họ; đó là sử dụng ký hiệu infix cho các bộ dữ liệu. Điều này thực sự ngắn gọn và phân tích giống như cách hoạt động số học có thể so sánh được. (Điều này cũng giải thích tại sao sử dụng số học is
không =
; A = 1+2
có thể thống nhất A
với các tuple '+'(1,2)
, vì vậy cú pháp riêng biệt là cần thiết để thực sự đánh giá biểu thức số học unevaluated.) Bởi vì một constructor tuple phải được gọi là một cái gì đó , bạn cũng có thể sử dụng một nhân vật có một ngắn gọn cú pháp (và như một phần thưởng, -
và/
cũng là một số lựa chọn phổ biến nhất trong mã không chơi gôn khi họ muốn một hàm tạo tuple nhanh chóng thay vì một cái gì đó có ý nghĩa, theo cách tương tự i
thường được sử dụng như một biến vòng lặp, vì vậy chúng hoàn toàn hợp lý để sử dụng trong bạn đầu vào và đầu ra nếu bạn tình cờ muốn một tuple ở đó vì một số lý do).
'-'
và '/'
là những lựa chọn tốt cho các nhà xây dựng tuple bởi vì họ có quyền ưu tiên ứng xử tốt và hữu ích, cho phép bạn viết tuple nghĩa đen một cách chặt chẽ. Tuy nhiên, lưu ý rằng bạn không cần phải lo lắng về quyền ưu tiên khi các giá trị trung gian được tạo ra trong chương trình. Prolog giữ các bộ dữ liệu được lưu trữ dưới dạng cây chứ không phải là mã nguồn và các máy in đẹp có thể xuất ra một cách rõ ràng:
| ?- A = '-'('-'(1,2), '-'(3,4)).
A = 1-2-(3-4)
Vì cú pháp tuple rất ngắn gọn ( f(A,B)
không ngắn hơn f(A-B)
), nên bạn có thể thay thế nhiều đối số dự đoán bằng các tuple miễn phí, nghĩa là nếu một vị từ cần truyền hai hoặc nhiều đối số của nó cho một vị từ khác, bạn có thể thường xuyên tạo chúng thành một tuple và chỉ vượt qua tuple (mặc dù điều này sẽ yêu cầu thay đổi tất cả các cuộc gọi thành vị ngữ, ngoài chính vị ngữ đó, để sử dụng một hỗn hợp thích hợp của các hàm tạo tuple và dấu phẩy).
Một ưu điểm khác của cú pháp này là nếu bạn cần sử dụng danh sách nội bộ (thay vì tương tác với các vị từ chuẩn); một danh sách về cơ bản chỉ là một tập hợp các ô khuyết điểm lồng nhau và một ô khuyết chỉ là một bộ dữ liệu với hàm tạo '.'
, như có thể thấy ở đây:
| ?- Q = '.'('.'(A,B),'.'(C,D)).
Q = [[A|B],C|D]
Nếu mã của bạn sử dụng danh sách "thủ công", việc sử dụng một hàm xây dựng tuple ít cồng kềnh hơn sẽ có ý nghĩa hơn nhiều '.'
. Một lựa chọn phổ biến đối với tôi là đại diện cho một ô khuyết điểm '/'(Tail,Head)
(vì đó là phần dễ đọc nhất mà bạn có thể nhận được trong đầu ra gỡ lỗi mà không lãng phí các ký tự). Lưu ý rằng bạn cũng có thể muốn []
tương đương của riêng bạn ; bạn có thể sử dụng []
nhưng nó dài hai byte và có rất nhiều nguyên tử một byte (tất cả các chữ cái viết thường) mà bạn có thể sử dụng thay thế.
Vì vậy, ví dụ, danh sách sau đây:
[1,2,3]
có thể được chuyển đổi thành biểu diễn thủ công trong cùng một số ký tự như thế này:
x/3/2/1
trong khi đạt được lợi thế, các [H|T]
mẫu khớp kiểu giờ đây có thể được viết chặt chẽ hơn T/H
, và một bài kiểm tra đối với danh sách trống x
thay vì dài hơn []
. (Tất nhiên, điều này đi kèm với những bất lợi rõ ràng rằng member
, append
vv, sẽ không hoạt động trên đại diện này.)
prolog
từ khóa là kinda vô dụng. Trừ khi chúng tôi có một thử thách Prolog phiên dịch, chúng tôi không cần nó.