The kod, który opublikowałeś, jest (prawie) OK. Kolejność klauzul prostu musi zostać zamienione (aby uczynić to definicja predykatu produktywny, gdy jest stosowany w generatywnej mody):
append([],X,X). % your 2nd line
append([X|Y],Z,[X|W]) :- append(Y,Z,W). % your first line
ta określa relację pomiędzy trzema argumentami, powiedzmy A
, B
i C
.
Pierwsza linia mówi, "C
jest wynikiem dopisywania A
i B
jeśli A
i C
są dla pustych list, oboje mają taką samą głowę (czyli pierwszy element), a ogon z C
jest wynikiem dołączenia ogona A
z tym samym drugim argumentem, B
".
a a
----------
b b
c c
. d d
e e
. .
Pomyśl o tym, ma to sens. To, co robi, chcemy zdefiniować relację append/3
i wiemy, co chcemy, więc po prostu zapisujemy kilka oczywistych faktów na ten temat, które chcemy spełnić, prawa, które muszą przestrzegać, jeśli zechcesz.
Zakładając, że mamy już zdefiniowany kod, jakie prawa musi ono obowiązywać?Oczywiście dołączenie ogona do jakiejś listy z inną listą daje nam ogon wyniku dołączenia pełnej listy do tej drugiej listy.
To definiuje sposób, w jaki "przesuwamy" pierwszą listę. Ale co, jeśli nie ma gdzie się przesuwać? Co jeśli dotarliśmy do końca tej listy? Następnie dotarliśmy do pustej listy, a dołączenie pustej listy z inną listą daje nam tę listę jako wynik. Oczywiście. I to właśnie mówi nam druga linia kodu, mówi: "dodanie pustej listy z inną listą tworzy tę listę jako wynik".
Zadziwiająco, po zapisaniu tych dwóch praw, które musi wykonać append/3
, jest to samo, co zapisanie samej definicji.
dodatkowo: to wyjaśnia to z deklaratywnego punktu widzenia; sprawdź numer an answer by m09, który pokazuje go bardziej z operacyjnego punktu widzenia.
Och, mam na myśli to, jak mogę go zakodować, który będzie działał podobnie jak append() prologu – Zik
Kodujesz to w ten sam sposób jak 'append' jest kodowany !? Już odkryłeś implementację (to pierwsze dwa wiersze kodu w twoim pytaniu). – aioobe