Это не ошибки, а предупреждения.Интерпретатор Prolog предупреждает, что он может найти только одно вхождение одной или нескольких переменных, что странно, поскольку обычно переменные используются для выполнения объединения, передачи значений из одного предиката в другой и т. Д.
Определение переменной за один раз имеет смысл только как заполнитель : когда вам нужно , чтобы указать переменную для правильного объединения.Но у Пролога есть стандартизированный способ сделать это: с подчеркиванием _
.Вы можете увидеть подчеркивание как «выбрасываемую переменную».Если предикат содержит два (или более) подчеркивания, то это две (разные) переменные.Цель подчеркивания состоит в том, чтобы прояснить, что это заполнитель, и таким образом он подавит предупреждение.
Таким образом, вы можете переписать предикат следующим образом:
member(X,[X|_]).
member(X,[_|R]) :- member(X,R).
Обратите внимание, что многиереализации member/2
используют вспомогательный предикат member/3
, чтобы избежать распаковки каждого "cons" (элемента списка) дважды, например, в SWI-Prolog мы видим:
member(El, [H|T]) :-
member_(T, El, H).
member_(_, El, El).
member_([H|T], El, _) :-
member_(T, El, H).
Итак, здесь мы распаковываем список в параметрах вызова предиката.Это означает, что первое предложение и второе предложение member_
не должны выполнять распаковку в голове (здесь мы делаем некоторые предположения относительно того, как интерпретатор работает, конечно), а в последнем предложении member_
,мы распаковываем следующие минусы только один раз.