Подтвердить что ты не робот

Одиночные переменные в прологе

Я тестировал свою новую версию пролога SWI и продолжаю сталкиваться с ошибкой: singleton variable.

Пример:

member(X,[X|T]).

member(X,[X|T]) :- member(X,T).

находит элемент списка, например:

member(yolands,[yolanda,tim])

X = yes

но вместо этого я получаю ошибку singleton variables для X и T

если я делаю следующее:

member(X,[X|_]).
member(X,[_|T]) :- member(X,T).

Это работает, но выглядит уродливо!

Может ли кто-нибудь объяснить, почему разрешены одиночные переменные и если этот стандарт ANSI?

4b9b3361

Ответ 1

Синглтонные переменные бесполезны в Prolog и легко вводятся путем редактирования опечаток.

Предупреждение приветствуется для меня, поскольку оно позволяет легко выявить такую ​​частую причину ошибки.

Будучи предупреждением, вы можете запускать код, содержащий одиночные числа, но любое значение, которое они в конечном итоге предполагают, будет потеряно.

Я не думаю, что стандарт ISO (никогда не слышал об ANSI) запрещает такие переменные.

Вы можете переписать свой пример таким образом

member(X, [Y|T]) :- X = Y ; member(X, T).

а затем забудьте о синглете.

Ответ 2

У вас есть ошибка здесь:

member(X,[X|T]) :- member(X,T).

То, что вы на самом деле говорит (в отличие от того, что, по вашему мнению, вы говорите), заключается в том, что member/2 выполняется, если X находится во главе списка и присутствует в хвосте списка. Этот предикат будет только когда-либо истинным для первых N копий одной и той же вещи в начале списка, поэтому очень странно сказать!

?- member(X, [a,a,c]).
X = a ;
X = a ;
false.

?- member(X, [b,a,a]).
X = b ;
false.

Теперь вы можете исправить ошибку и по-прежнему иметь одноэлементное предупреждение, выполнив что-то вроде этого:

member(X, [Y|T]) :- member(X, T).

Но это не так хорошо, как обычное определение с двумя головами или версия @CapelliC (+1) с явным OR. Я думаю, вам стоит подождать, пока вы не поймете Prolog немного лучше, прежде чем вкладывать много акций в ваш смысл эстетики кода Prolog. Если вы будете придерживаться этого какое-то время, вы поймете это предупреждение, а также использование анонимных переменных.

То, что делает одиночные переменные бесполезными в Prolog, состоит в том, что они названы, но о них ничего не известно, и они не влияют на остальную часть вычислений. Подчеркивание подчеркивает, что абсолютно все может идти туда, не затрагивая смысла. Что делает

member(X, [X|T]).

true заключается в том, что X является позицией 1 такой же, как X в начале списка в позиции 2. Списки должны быть пустыми или иметь голову и хвост, но то, что в хвосте здесь не имеет значения, важно то, что Х - тоже голова. T может быть остальной частью списка, или это может быть неправильный список, или это может быть хлеб или молния или запах воздуха в день spring. Он не имеет никакого отношения к истине member(X, [X|T]).

Предупреждение singleton сообщает вам: "Вы зарезервировали имя для чего-то здесь, но вы никогда не называете что-либо под этим именем". Первое, что я делаю, когда получаю это сообщение, и это не очевидная опечатка, заменит имя на _ и посмотрим, действительно ли мой код имеет смысл. Если это не так, у меня есть логическая ошибка. Если это так, это, вероятно, не нужно.

Ответ 3

Вы можете прочитать об этом на официальной странице FAQ SWI-Prolog

Наиболее распространенными случаями этого предупреждения являются:

  • Ошибки орфографии в переменных
  • Забудьте использовать/привязать переменную

SWI предлагает несколько способов игнорировать его:

  • Для этой цели используйте анонимную переменную с именем _.
  • Используйте переменную, начинающуюся с _ (например, _T, _X), чтобы избежать предупреждения и документировать то, что вы игнорируете.
  • Если вы знаете, что делаете, вы можете использовать :- style_check(-singleton)., и все предупреждения должны исчезнуть.