Saya seorang pemula di Prolog dan saya memiliki dua membuat tupel dari dua daftar menggunakan rekursi. Misalnya, func ([1, 2, 3], [4, 5, 6]) harus menghasilkan [(1, 4), (1,5), (1,6), (2, 4), (2 , 5), (2, 6), (3, 4), (3 ,5), (3, 6)]. Saya memiliki kode berikut:

func([],_,[]).
func([X|T1],Y,[Z|W]):-
    match(X,Y,Z),
    func(T1,Y,W).

match(X,[Y],[(X,Y)]).
match(X,[Y|T],[(X,Y)|Z]) :-
    match(X,T,Z).

Tapi output saya untuk func([1,2,3],[4,5,6],X) adalah X = [[(1, 4), (1, 5), (1, 6)], [( 2, 4), (2, 5), (2, 6)], [(3, 4), (3, 5), (3, 6)]].

Bagaimana saya bisa menghilangkan tanda kurung siku tambahan di tengah output saya? Saya sudah mencoba bermain dengan tanda kurung dan tanda kurung di kedua fungsi saya, tetapi saya tidak dapat menemukannya.

1
StrickBan 10 April 2020, 01:52

1 menjawab

Jawaban Terbaik

Menggunakan predikat standar findall/3 dan predikat standar de facto member/2:

| ?- findall(X-Y, (member(X,[1,2,3]), member(Y,[4,5,6])), Pairs).

Pairs = [1-4,1-5,1-6,2-4,2-5,2-6,3-4,3-5,3-6]
yes

Untuk memahami solusi ini, amati bahwa, untuk setiap nilai X, kami menghitung dengan menelusuri kembali semua nilai Y. Yaitu. ketika mundur (seperti yang secara implisit dilakukan oleh predikat findall/3 untuk menyusun daftar semua solusi dari argumen kedua), kami menghabiskan semua solusi untuk titik pilihan terakhir (tujuan member(Y,[4,5,6])) sebelum mundur ke titik pilihan sebelumnya (sasaran member(X,[1,2,3])). Ini dikenal sebagai mundur kronologis dan merupakan salah satu karakteristik yang menentukan dari Prolog.

Perhatikan bahwa saya menggunakan X-Y, representasi Prolog biasa untuk pasangan, alih-alih (X,Y), yang bukan merupakan solusi yang disarankan untuk membangun n-tupel karena hanya berfungsi dengan baik untuk pasangan elemen.

1
Paulo Moura 9 April 2020, 23:19