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

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

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


person nubela    schedule 13.09.2009    source источник


Ответы (8)


?- 2+3 =:= 6-1.
true.

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

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

person Volodymyr Gubarkov    schedule 13.09.2009
comment
По сути, арифметический оператор, который проверяет, заканчиваются ли результаты некоторых вычислений одним и тем же результатом? Похоже на то, что переменная равна 5 + 10, но вычисляется с обеих сторон, а затем объединяется, что дает в результате истину или ложь. - person G_V; 19.01.2018

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

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

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

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

Чтобы взять пример из приведенного выше словаря Prolog Dictionary: чтобы проверить, является ли число 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.

person ThomasH    schedule 23.12.2009
comment
Почему это не было выбрано в качестве правильного ответа, я никогда не узнаю ( ._.) - person iGbanam; 28.05.2013
comment
При использовании is у вас может быть более одной переменной в левой части? X + Y = 2 +3 например. - person hiswendy; 12.06.2018
comment
@hiswendy Что из этого должно получиться?! Помните, что is оценивает свою правую часть как арифметическое выражение. В вашем примере это будет 5. Как 5 унифицировать с левым термином, таким как X + Y?! - Предикат =/2, который вы используете, является наиболее общей функцией объединения, которая пытается сопоставить и связать два произвольных термина. Он не выполняет автоматических арифметических вычислений и, следовательно, сильно отличается от =:=, который также обсуждается здесь. - person ThomasH; 13.06.2018
comment
@ThomasH hiswendy технически верен, хотя в том, что ?- X + Y = 2 + 3. дает результат, и этот результат равен X = 2, Y = 3. Но с арифметикой CLP можно сделать X + 4 #= 2 + 3. и получить X = 1., что более полезно. - person Erik Kaplun; 25.01.2021
comment
@ErikKaplun Я согласен при использовании =. Но вопрос Венди касался is, и это не работает. - person ThomasH; 25.01.2021

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

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

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

?- current_op(Prec, Type, =:=).
Prec = 700,
Type = xfx.

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

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

?- write_canonical(a =:= b).
=:=(a,b)

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

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

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

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

?- X =:= Y.
ERROR: Arguments are not sufficiently instantiated

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

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

?- 1 + 2 =:= 3.
true.

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

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

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

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

| ?- 1 + 2 #= 3.

yes

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

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

| ?- X + 2 #= 3.

X = 1

| ?- 1 + Y #= 3.

Y = 2

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

| ?- X #= Y.

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

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

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

См. также clpfd, clpq и clpb для получения дополнительной информации.

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

?- sat(A =:= B+1).
A = 1,
sat(B=:=B).

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

person mat    schedule 21.04.2017
comment
очень хороший ответ, мат. Мне особенно нравится, как вы представляете использование op и write_canonical. По моему мнению, op является исключительной особенностью Пролога. - person Kintalken; 07.05.2017
comment
Однако я категорически не согласен с вашим утверждением, что op не является предикатом. На мой взгляд, часть блестящего гения пролога заключается в том, что каждый оператор ЯВЛЯЕТСЯ функтором (предикатом). Фактически каждый элемент вашего источника становится предикатом. Таким образом, можно видеть, что функция разметки и синтаксического анализа в интерпретаторе пролога заключается в создании синтаксического дерева, и это синтаксическое дерево полностью определяется через функтор. - person Kintalken; 07.05.2017

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

person nubela    schedule 13.09.2009

Это стандартный стандартный оператор предиката 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
person Mostowski Collapse    schedule 30.01.2019

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

Выражение =:= означает точно равно.

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

Информации мало, но надеюсь, что она хоть как-то поможет.

person profiile_samir    schedule 06.11.2020

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

person Ayyappa Boligala    schedule 14.03.2014

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

он возвращает true. но возвращает false введите здесь описание изображения

person Okan Çiftçi    schedule 21.04.2017