Вывдеталейузла(Р): Р– это список структур чис,который выдается на печать по одной структуре на строке вывода. Цель put(9)выводит литеру с кодом ASCII=9, что соответствует горизонтальной табуляции. С предикатом присоединитьмы уже неоднократно встречались ранее.
Полностью Пролог-программа выглядит так:
деталиузла(Т):-деталиузлов(1,Т,Р), co6paть(P,Q), вывдеталейузла(Q).
деталиузлов(N,Х,Р):-узел(Х,S), деталировка(N,S,Р).
деталиузлов(N,Х, [чис(Х,N)]):- деталь(Х).
деталировка(_, [], []).
деталировка(N, [чис(Х, Число) |L],T):-М is N * Число, деталиузлов(М,Х,Хдетали),деталировка (N, L,Остдетали,Т),присоединить(Хдетали,Остдетали,Т).
собрать([],[]).
coбpaть([чис(X,N)|R],[чис(X,Nитог)|R2]):-дособрать(Х,N,R,O,Nитог),собрать(О,R2).
досo6paть(_,N,[],[],N).
дособрать(Х,N,[чис(Х,Число)|Oст],Прочие,Nитог):-!,М is N+Число, дособрать(Х,М,Ост,Прочие,Nитог).
дособрать(Х,N,[Друг|Ост],[Друг|Прочие],Nитог):-дособрать(Х, N, Ост, Прочие, Nитог).
вывдеталейузла([]).
вывдеталейузла([чис(Х,N)|R):-tab(4),write(N),put(9),write(X),nl, вывдеталейузла(R).
7.5. Обработка списков
В этом разделе мы рассмотрим некоторые основные предикаты, полезные при работе со списками. Поскольку Пролог позволяет работать с произвольными структурами данных, списки не могут играть в нем той незаменимой роли, какая им отводится в других языках программирования, таких, как Лисп и Поп-2. Однако независимо от того, будут или не будут использоваться списки в ваших программах, всегда важно представлять себе, как работают предикаты, определения которых рассматриваются в данном разделе, поскольку они основаны на принципах, которые применимы при работе с любыми структурами данных.
последний(Х,[Х]).
последний(Х,[_,|Y]):- последний(Х,Y).
?- последний(Х,[talk,of,the,town]).
X = town
следомза(Х,Y,[Х,Y|_]).
следомза(Х,Y,[_|Z]):- следомза(Х,Y,Z).
?- присоединить([a,b,с],[d,e,f],Q).
Q=[a,b,c,d,e,f]
Определение предиката присоединитьвыглядит следующим образом:
присоединить([],L,L).
присоединить([Х|L1],L2,[Х|LЗ]):- присоединить(L1,L2,LЗ).
Граничное условие выполняется тогда, когда первый аргумент является пустым списком. Действительно, пополнение какого-либо списка пустым списком не изменяет его. В дальнейшем мы постепенно приближаемся к граничному условию, поскольку каждое рекурсивное обращение к присоединитьудаляет один элемент из головы первого аргумента.
Заметим, что любые два аргумента присоединитьмогут быть конкретизированы, и в этом случае присоединитьконкретизирует третий аргумент соответствующим результатом. Этим свойством, которое можно было бы назвать «недетерминированным программированием», обладают многие из определяемых в данной главе предикатов. Указанная гибкость присоединитьпозволяет определить с его помощью ряд других предикатов, что мы и сделаем:
последний(Е1,Список):- присоединить(_,[Е1],Список).
следомза(Е11,Е12,Список):-
присоединить(_,[Е11,Е12|_], Список).
принадлежит(Е1,Список):- присоединить(_,[Е1|_],Список).
обр([],[]).
обр([Н|Т],L):- обр(T,Z), присоединить(Z,[Н],L).