Факты вызова в запросе

#prolog

#prolog

Вопрос:

Это мой код:

 sentence([['o'],['m','e','n','i','n','o'],['a','l','e','g','r','e']]).

lastWord(X,[X]).
lastWord(X,[_|Z]) :- lastWord(X,Z).
  

Если я попытаюсь lastWord(X,[1,2,3]). или даже lastWord(X,[['o'],['m','e','n','i','n','o'],['a','l','e','g','r','e']]). получу то, что хочу (что, конечно, является последним элементом списка (в примерах, 3 и ['a','l','e','g','r','e'] .

Но если я попытаюсь lastWord(X, sentence). или lastWord(X, sentence(Y)). получу false .

Как я могу «вызвать» определенный список (в данном случае «предложение») в lastWord?

Ответ №1:

Prolog не является функциональным языком. Таким образом, в таких целях, как lastWord(X, sentence) или lastWord(X, sentence(Y)) , не собирается заменять sentence or sentence(Y) аргументом sentence/1 предиката. Попробуйте вместо:

 ?- sentence(List), lastWord(Last, List).
List = [[o], [m, e, n, i, n, o], [a, l, e, g, r, e]],
Last = [a, l, e, g, r, e] ;
false.
  

Обратите внимание, что для запроса осталась ложная точка выбора. Вы можете устранить это, переписав определение предиката lastWord/2 . Подобный предикат, обычно именуемый last/2 , часто доступен в библиотеках:

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

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

Обратите внимание на другой порядок аргументов (рекомендации по кодированию Prolog предполагают, что входные аргументы предшествуют выходным аргументам). Использование этого предиката вместо:

 ?- sentence(List), last(List, Last).
List = [[o], [m, e, n, i, n, o], [a, l, e, g, r, e]],
Last = [a, l, e, g, r, e].