Сначала посмотрим, почему ваш код не работает.
test([],_,_).
test([Child|List],B,C) :-
append([Child],B,C),
test(List,B,C).
Вы пытались определить рекурсивный предикат с двумя предложениями.Аргументами этого предиката являются: список ввода (1), промежуточный список (2) и конечный результат (3).
Таким образом, ваше первое предложение неверно.Предположим, что ваш входной список - просто пустой список.Результатом должен быть пустой список.Но в первом предложении вы оставляете третий аргумент как есть.Либо оно уже было связано с somenthing (в данном случае бесполезно), либо оно было неограниченным, и поэтому оно останется таким.
Во втором пункте рассматривается рекурсия.Он берет первый элемент вашего входного списка, добавляя его перед промежуточным списком, получая другой промежуточный список.Теперь вы делаете шаг рекурсии, снова вызывая test.Но обратите внимание, что теперь три аргумента созданы!поэтому вы не сможете добавить еще один элемент в окончательный список.
Вот ваш предикат test / 3, модифицированный для работы так, как вы ожидаете:
test([],List,List).
test([Child|List],B,D) :-
append([Child],B,C),
test(List,C,D).
Теперь первое предложение просто объединяет второй и третий аргумент.Итак, в нашем первом тестовом примере (пустой входной список) напомним, что второй аргумент также был пустым списком, поэтому третий аргумент также будет пустым списком => правильный.
Теперь для рекурсивного предложения.Он возьмет первый элемент списка ввода и добавит его в промежуточный список, а также объединит его по новой переменной.Теперь мы переходим к шагу рекурсии, но теперь мы используем этот список (C) в качестве промежуточного списка.Это, при рекурсии, создаст список вывода, теперь связанный с D. Это то, что мы используем в качестве вывода.
Поскольку вы просто добавляете один элемент в промежуточный список каждый раз, вы могли бы избавиться отдобавить что-то вроде:
test([],List,List).
test([Child|List],B,C) :-
test(List,[Child|B],C).