Пролог Оператор =: = - PullRequest
       31

Пролог Оператор =: =

24 голосов
/ 13 сентября 2009

В Прологе есть несколько специальных операторов, одним из которых является "is", однако недавно я натолкнулся на операторы =: =, и я понятия не имею, как это работает.

Может кто-нибудь объяснить, что делает оператор, а также где я могу найти предопределенный список таких специальных операторов и что они делают?

Спасибо.

Ответы [ 7 ]

86 голосов
/ 23 декабря 2009

Я думаю, что приведенный выше ответ, тем не менее, заслуживает нескольких слов объяснения.

Краткое замечание: арифметические выражения в Прологе - это просто термины («Все - это термин в Прологе»), которые не оцениваются автоматически . (Если у вас есть фон Lisp, подумайте о списках в кавычках). Так что 3 + 4 - это то же самое, что и +(3,4), который ничего не делает сам по себе. Ответственность отдельных предикатов заключается в оценке этих условий.

Несколько встроенных предикатов выполняют неявную оценку, среди них операторы арифметического сравнения, такие как =:= и is. В то время как =:= оценивает оба аргумента и сравнивает результат, is принимает и оценивает только его правильный аргумент как арифметическое выражение.

Аргумент left должен быть атомом, либо числовой константой (которая затем сравнивается с результатом вычисления правого операнда), либо переменной. Если это переменная bound , ее значение должно быть числовым и сравниваться с правым операндом, как в предыдущем случае. Если это несвязанная переменная, результат вычисления правого операнда привязывается к этой переменной. is часто используется в последнем случае для привязки переменных.

Чтобы взять пример из связанного выше словаря Пролога: чтобы проверить, является ли число N четным, вы можете использовать оба оператора:

0 is N mod 2  % true if N is even
0 =:= N mod 2 % dito

Но если вы хотите зафиксировать результат операции, вы можете использовать только первый вариант. Если X не связан, то:

X is N mod 2   % X will be 0 if N is even
X =:= N mod 2  % !will bomb with argument/instantiation error!

Правило большого пальца. Если вам просто нужно арифметическое сравнение, используйте =:=. Если вы хотите зафиксировать результат оценки, используйте is.

24 голосов
/ 13 сентября 2009
?- 2+3 =:= 6-1.
true.

?- 2+3 is 6-1.
false.

Также см. Документы http://www.swi -prolog.org / pldoc / man? Предикат = is / 2

13 голосов
/ 21 апреля 2017

В дополнение к существующим ответам я хотел бы высказать несколько дополнительных моментов:

Оператор есть оператор

Прежде всего, оператор =:=, как следует из названия, является оператором . В Прологе мы можем использовать предикат current_op/3, чтобы узнать больше об операторах. Например:

<b>?- current_op(Prec, Type, =:=).</b>
Prec = 700,
Type = xfx.

Это означает, что оператор =:= имеет приоритет 700 и имеет тип xfx. Это означает, что это бинарный оператор infix .

Это означает, что вы можете , если вы хотите , напишите такой термин, как =:=(X, Y) , эквивалентно , как X =:= Y. В обоих случаях функтор термина равен =:=, а arity этого термина равен 2. Вы можете использовать write_canonical/1 для проверки этого :

?- write_canonical(a =:= b).
<b>=:=(a,b)</b>

Предикат не является оператором

Пока все хорошо! Все это было чисто синтаксической функцией. Однако то, о чем вы на самом деле спрашиваете, это предикат (=:=)/2, имя которого =:= и которое принимает 2 аргумента .

Как уже объяснили другие, предикат (=:=)/2 обозначает арифметическое равенство двух арифметических выражений. true если его аргументы оценивают для того же числа.

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

?- X =:= Y.
<b>ERROR: Arguments are not sufficiently instantiated</b>

Следовательно, этот предикат не является истинным отношением, поскольку мы не можем использовать его для генерации результатов! Это довольно серьезный недостаток этого предиката, противоречащий тому, что вы обычно называете «декларативным программированием».

Предикат работает только в той конкретной ситуации, когда оба аргумента полностью созданы. Например:

?- 1 + 2 <b>=:=</b> 3.
<b>true.</b>

Мы называем такие предикаты moded , потому что они могут использоваться только в определенных режимах использования. Для подавляющего большинства новичков модные предикаты - это кошмар , потому что они требуют от вас думать о ваших программах процедурно , что довольно сложно сначала и остается сложным и позже. Кроме того, измененные предикаты строго ограничивают универсальность ваших программ, поскольку вы не можете использовать их во всех направлениях, в которых вы могли бы использовать чистые предикаты.

Ограничения являются более общей альтернативой

Пролог также предоставляет намного более общих арифметических предикатов в форме арифметических ограничений .

Например, в случае целых чисел , попробуйте ограничения CLP (FD) вашей системы Prolog . Одно из наиболее важных ограничений CLP (FD) обозначает арифметику равенство и называется (#=)/2. В полной аналогии с (=:=)/2 оператор (#=)/2 также определен как оператор infix , поэтому вы можете написать, например:

<b>| ?- 1 + 2 #= 3.</b>

yes

Я использую GNU Prolog в качестве одного конкретного примера, и многие другие системы Prolog также предоставляют реализации CLP (FD).

Главная привлекательность ограничений заключается в их общности . Например, в отличие от (=:=)/2, мы получаем с предикатом (#=)/2:

<b>| ?- X + 2 #= 3.</b>

X = 1

<b>| ?- 1 + Y #= 3.</b>

Y = 2

И мы можем даже задать самый общий запрос:

<b>| ?- X #= Y.</b>

X = _#0(0..268435455)
Y = _#0(0..268435455)

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

В зависимости от области интересов я рекомендую использовать CLP (FD), CLP (Q), CLP (B) и т. Д. вместо использования более низкоуровневых арифметических предикатов.

Также см. , и для получения дополнительной информации.

По совпадению оператор =:= используется CLP (B) с полностью другим значением:

?- sat(A =:= B+1).
<b>A = 1,
sat(B=:=B).</b>

Это показывает, что вы должны различать операторов и предикатов . В приведенном выше случае предикат sat/1 интерпретировал данное выражение как формулу высказывания, и в этом контексте =:= обозначает равенство булевых выражений.

5 голосов
/ 13 сентября 2009

Я нашел свой ответ, http://www.cse.unsw.edu.au/~billw/prologdict.html

1 голос
/ 30 января 2019

Это основной предикатный оператор ISO, который не может быть загружен из унификации (=) / 2 или синтаксического равенства (==) / 2. Это определено в разделе 8.7 Арифметическое сравнение. И это в основном ведет себя следующим образом:

E =:= F :- 
    X is E, 
    Y is F, 
    arithmetic_compare(=, X, Y).

Таким образом, как левая (LHS), так и правая (RHS) должны быть арифметическими выражениями, которые оцениваются перед их сравнением. Арифметическое сравнение может сравнивать по числовым типам. Итак имеем:

   GNU Prolog 1.4.5 (64 bits)

   ?- 0 = 0.0.
   no

   ?- 0 == 0.0
   no

   ?- 0 =:= 0.0.
   yes
0 голосов
/ 21 апреля 2017

Первый оператор =: = проверка равна? например введите описание изображения здесь

возвращаемое значение true. но это возвращает ложь введите описание изображения здесь

0 голосов
/ 14 марта 2014

=: = является оператором сравнения. A1 =: = A2 успешно выполняется, если значения выражений A1 и A2 равны. A1 == A2 успешно выполняется, если члены A1 и A2 совпадают;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...