A+B:-findall(X,(append(X,Y,A),append(Y,X,A)),[_|Z]),length(Z,B).
Cobalah online!
Mendefinisikan predikat +/2yang mengambil string (dalam bentuk daftar kode karakter) sebagai argumen pertama ( A) dan menetapkan argumen kedua ( B) ke urutan rotasi simetris urutan tertinggi.
Penjelasan
Program ini menggunakan fakta bahwa himpunan rotasi simetris pada string adalah grup siklik sehingga urutan himpunan rotasi simetris sama dengan urutan rotasi simetris urutan tertinggi. Dengan demikian program ini dapat menghitung hasil yang diinginkan dengan menemukan jumlah total rotasi simetris pada string input.
Penjelasan Kode
Mayoritas pengangkatan berat dilakukan dengan panggilan ke findall/3predikat. The findall/3predikat menemukan semua nilai yang berbeda yang mungkin untuk argumen pertama ( Xdalam kasus ini) sehingga ekspresi yang diberikan sebagai argumen kedua adalah benar ( (append(X,Y,A),append(Y,X,A))lebih pada nanti). Akhirnya ia menyimpan masing-masing nilai yang mungkin Xsebagai daftar dalam argumen terakhir ( [_|Z]).
Ekspresi dilewatkan findall/3sebagai arugment kedua, (append(X,Y,A),append(Y,X,A))menggunakan append/3predikat untuk menentukan bahwa Xdigabungkan dengan beberapa belum terdefinisi Yharus sama dengan A, string input, dan bahwa Ydigabungkan dengan yang sama Xjuga harus sama dengan A. Ini berarti bahwa Xharus ada beberapa awalan Asehingga jika dihapus dari depan Adan ditambahkan ke belakang maka string yang dihasilkan sama dengan A. Himpunan Xs dengan properti ini hampir memiliki korespondensi satu-ke-satu dengan rotasi simetris A. Selalu ada satu kasus penghitungan ganda yang disebabkan oleh fakta bahwa string kosong dan AawalanAyang sesuai dengan 0-rotasi A. Karena 0-rotasi Aselalu simetris, panjang dari daftar Xs yang dihasilkan findall/3akan lebih besar dari jumlah rotasi simetris yang aktif A.
Untuk mengatasi masalah penghitungan ganda, saya menggunakan pencocokan pola pada argumen ketiga dari findall/3predikat. Dalam daftar Prolog diwakili sebagai pasangan kepala mereka (elemen pertama) dan ekor mereka (sisanya). Dengan demikian [_|Z]mewakili daftar yang ekornya sama dengan Z. Ini berarti bahwa panjang Zsatu kurang dari jumlah awalan yang ditemukan oleh findall/3predikat dan dengan demikian sama dengan jumlah rotasi simetris A. Akhirnya, saya menggunakan length/2predikat untuk mengatur Bpanjang Z.