A+B:-findall(X,(append(X,Y,A),append(Y,X,A)),[_|Z]),length(Z,B).
Hãy thử trực tuyến!
Xác định một vị từ +/2lấy một chuỗi (dưới dạng danh sách mã ký tự) làm đối số thứ nhất ( A) và đặt đối số thứ hai ( B) của nó theo thứ tự xoay đối xứng bậc cao nhất.
Giải trình
Chương trình này sử dụng thực tế là tập hợp các phép quay đối xứng trên một chuỗi là một nhóm tuần hoàn và do đó thứ tự của tập hợp các phép quay đối xứng bằng với thứ tự của phép quay đối xứng bậc cao nhất. Do đó, chương trình có thể tính toán kết quả mong muốn bằng cách tìm tổng số phép quay đối xứng trên chuỗi đầu vào.
Giải thích mã
Phần lớn của việc nâng vật nặng được thực hiện bằng một cuộc gọi đến findall/3vị ngữ. Vị findall/3ngữ tìm thấy tất cả các giá trị khác nhau có thể có cho đối số thứ nhất ( Xtrong trường hợp này) sao cho biểu thức được đưa ra làm đối số thứ hai là đúng ( (append(X,Y,A),append(Y,X,A)), nhiều hơn về điều đó sau). Cuối cùng, nó lưu trữ từng giá trị có thể này Xdưới dạng một danh sách trong đối số cuối cùng ( [_|Z]).
Biểu thức được truyền vào findall/3dưới dạng arugment thứ hai, (append(X,Y,A),append(Y,X,A))sử dụng biến append/3vị ngữ để xác định rằng Xnối với một số chưa được xác định Yphải bằng A, chuỗi đầu vào và cùng được Ynối với Xcũng phải bằng A. Điều này có nghĩa là Xphải có một số tiền tố Asao cho nếu nó được xóa khỏi mặt trước Avà thêm vào phía sau thì chuỗi kết quả giống như A. Tập hợp Xs với tính chất này gần như có sự tương ứng một-một với các phép quay đối xứng của A. Luôn luôn có chính xác một trường hợp đếm kép được gây ra bởi thực tế là cả chuỗi rỗng và Atiền tố củaAtương ứng với 0 vòng quay của A. Vì sự 0bảo vệ của Aluôn luôn đối xứng nên độ dài của danh sách kết quả của Xs findall/3sẽ lớn hơn số lần quay đối xứng trên A.
Để giải quyết vấn đề đếm kép, tôi sử dụng khớp mẫu trên đối số thứ ba của findall/3vị ngữ. Trong danh sách Prolog được thể hiện dưới dạng cặp đầu (phần tử đầu tiên) và đuôi của chúng (phần còn lại). Do đó, [_|Z]đại diện cho một danh sách có đuôi bằng với Z. Điều này có nghĩa là độ dài của Zmột ít hơn số lượng tiền tố được tìm thấy bởi findall/3vị ngữ và do đó bằng với số lần quay đối xứng của A. Cuối cùng, tôi sử dụng length/2vị ngữ để đặt thành Bđộ dài của Z.