Пролог "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.