Конкатенация списков в прологе

Может кто-нибудь помочь найти ошибку в этих правилах?

concat([], List, List).
concat([Head|[]], List, [Head|List]).
concat([Head|Tail], List, Concat) :- concat(Tail, List, C), concat(Head, C, Concat).

Попытка объединить 2 списка не удалась:

| ?- concat([1,2], [4,7,0], What).

no

Ответ 1

Чтобы исправить ваш код, как вы его намеревались, просто нужно преобразовать Head в [Head] в свой последний вызов concat/3 в своем последнем пункте. Проблема заключалась в том, что вы вызывали ваш предикат с Head только как первый аргумент, который не является списком.

Хотя, вот несколько примечаний:

  • [Head|[]] эквивалентно [Head]
  • ваш алгоритм имеет низкую сложность, n! Я верю.
  • без вырезания, вставленного после вашего второго предложения, вы генерируете бесконечные точки выбора через вызов вашего третьего предложения со списком длины 1 (что, следовательно, вызывает ваше второе предложение, которое затем выполняется через ваше третье предложение и т.д. бесконечный цикл).

Вот версия SWI-pl, чтобы намекнуть вам на хорошую рекурсию пролога:

append([], List, List).
append([Head|Tail], List, [Head|Rest]) :-
    append(Tail, List, Rest).

Вы можете найти другие ресурсы в последних сообщениях здесь или в Learn Prolog Now!, если вы хотите научиться правильно использовать рекурсию.

Ответ 2

Это можно сделать, используя append.

concatenate(List1, List2, Result):-
   append(List1, List2, Result).

Надеюсь, что это поможет.

Ответ 3

Вот конкатенация между двумя правилами:

concat([],L2,L2). concat([Head|Tail],L2,[Head|L3]) :- concat(Tail,L2,L3).