Печатать элементы списка, но обрабатывать последний элемент по-разному - PullRequest
1 голос
/ 09 ноября 2019

Я написал предикат, который печатает каждый элемент в списке, кроме последнего. Последний элемент должен обрабатываться по-разному;вместо этого должно быть напечатано LAST!. Это то, что у меня есть.

write_data([]).
write_data([X]) :-
    !, write('LAST!'), nl.
write_data([X | Rest]) :-
    write(x), nl,
    write_data(Rest).

Есть ли лучший способ? Есть ли способ сделать это без разреза?

Ответы [ 3 ]

1 голос
/ 09 ноября 2019

Общее определение для предиката last/2, предоставляющего доступ к последнему элементу списка:

last([Head| Tail], Last) :-
    last(Tail, Head, Last).

last([], Last, Last).
last([Head| Tail], _, Last) :-
    last(Tail, Head, Last).

При вызове с первым аргументом, связанным с закрытым списком, вспомогательный предикат, last/3, избегает ложных точек выбора, предполагая, что система Prolog реализует обычную индексацию первого аргумента. Можете ли вы изменить этот предикат, чтобы делать то, что вы хотите?

1 голос
/ 09 ноября 2019

Вы можете избежать сокращения, выполнив объединение со списком, который содержит как минимум два элемента, например:

write_data([]).
write_data([_]) :-
    write('LAST!'),
    nl.
write_data([X|Rest]) :-
    <b>Rest = [_|_],</b>
    write(X), nl,
    write_data(Rest).

Кроме того, мы можем избежать двойной распаковки с предикатом-помощником:

write_data([]).
write_data([H|T]) :-
    write_data(T, H).

write_data([], _) :-
    write('LAST!'), nl.
write_data([H|T], X) :-
    write(X), nl,
    write_data(T, H).
0 голосов
/ 12 ноября 2019

Общее правило для удаления среза заключается в том, чтобы отметить, что было true в предложении, которое содержит разрез, а затем убедиться, что * false в другом пункте (ах).

Таким образом:

write_data([]).

write_data([X]) :-
    /*!,*/write('LAST!'), nl.

write_data([X | Rest]) :-
    dif(Rest,[]) , /**/
    write(x), nl,
    write_data(Rest).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...