Во-первых, предикат может быть успешным или неуспешным.
Более технически и отмечен в стандарте Пролога
В Прологе то, что вы бы назвали вызовом, являетсявыполнение.
Выполнение - это последовательность активаций, которые пытаются достичь цели.
В Прологе то, что вы думаете о возврате, указано как
Если активация BP прошла успешно, замените текущий активатор CCG активатором true, активация которого описана в (7.8.1 .l).
, поэтому значения передаютсявставка и извлечение состояний в стек.
Для простоты я вместо этого буду использовать более общие термины программирования (вызов, передача, параметр), даже если они не являются технически правильными терминами для использования при описании работы Пролога..
Чтобы вызвать foo
из bar
, чтобы bar
мог передать значение foo
, было бы так:
bar :-
foo(Passed_to_foo).
foo(Received_from_bar) :-
% Do something with Received_from_bar.
Чтобы развернуть предыдущее и передатьзначение обратно от foo
тo bar
будет выглядеть так:
bar :-
foo(Passed_to_foo,Received_from_foo).
foo(Received_from_bar,Passed_to_bar) :-
% Do something with Received_from_bar
% Generate/Compute Passed_to_bar
Если вы не знаете, будет ли аргумент содержать ни одного элемента, одного или многих элементов, вы правы, думая, что список, но список можеттакже выполните все три.
Чтобы не передавать значения в виде списка, просто передайте пустой список
[]
Чтобы передать одно значение в списке, просто поместите его в список и передайтеlist
[first_value]
Чтобы передать более одного значения, просто поместите их в список и передайте список
[first_value, second_value, third_value, ... ]
Поскольку значения всегда будут в списке, просто используйте старый добрыйрекурсия для обработки элемента (ов) в списке.
Базовый регистр
foo([],Result).
Рекурсивный регистр
foo([H|T],Result) :-
% Do something with head of list `H`
% Pass tail of list `T` back to foo for processing
foo(T,Result).