Пролог "append_dl/3" обертка

Я только изучаю Пролог и концепцию списков различий в Прологе, так что терпите меня, пожалуйста.

У меня есть следующий код:

:- op(400, xfx, \).

append(Xs, Ys, Zs) :-
  append_dl( [Xs|T1]\T1, [Ys|T2]\T2, Zs\[]).

append_dl( Xs\Ys, Ys\Zs, Xs\Zs).

Теперь, если я добавлю списки [1,2,3] и [a,b,c] в SWI-интерпретатор, он выдаст списки списков.

?- append([1,2,3],[a,b,c],Zs).
Zs = [[1, 2, 3], [a, b, c]].

Принимая во внимание, что если я вызываю append_dl прямо так:

?- append_dl([1,2,3|T1]\T1,[a,b,c|T2]\T2,Zs\[]).
T1 = [a, b, c],
T2 = [],
Zs = [1, 2, 3, a, b, c].

оно работает...

Что я делаю не так и как следует правильно обернуть эти функции, используя списки различий?

Спасибо ребята за помощь:D

1 ответ

Решение

Хотя этот метод программирования является ключом к Прологу, это append_dl/3 это очень искусственный пример, который никто не использует таким точным способом. Существует учебник по Прологу (Art of Prolog), который использует это как первый "мотивирующий" пример, и некоторые курсы до сих пор следуют таким учебникам буквально...

(Давайте сохраним общее определение append/3 как обычно определяется)

Списки различий не являются списками. Скорее, это различия между списками. Таким образом, список различий будет более подходящим для них именем. В большинстве ситуаций у вас нет таких готовых различий, скорее, вам придется преобразовать фактический список в такую ​​разницу или (чаще) построить разницу, пока вы идете дальше.

Так возьми список [1,2,3] которая может быть представлена ​​разницей [1,2,3|Xs]\Xs, Другой способ представить это будет [1,2,3]\[], Но вы можете использовать append_dl/3 только если различия представлены в их наиболее общем виде, которого у вас нет. Таким образом, сначала вам нужно преобразовать обычные списки в это представление.

mappend(XsL, YsL, ZsL) :-
   append(XsL, Xs,Xs0),       % convert XsL to a difference Xs0\Xs
   append(YsL, Ys,Ys0),       % convert YsL to a difference Ys0\Ys
   append_dl( Xs0\Xs, Ys0\Ys, ZsL\[]).

В этом конкретном примере преобразование было просто накладными. Вам нужен был встроенный append/3 дважды. Также, mappend(XsL, YsL, [1,2]) не заканчивается, тогда как append(XsL, YsL, [1,2]) делает. Для этого случая вы должны изменить порядок целей.

После того, как вы дали это задание, я бы порекомендовал вам изучить нотацию Пролога dcg.

Другие вопросы по тегам