В дополнение к существующим ответам я хотел бы высказать несколько дополнительных моментов:
Оператор есть оператор
Прежде всего, оператор =:=
, как следует из названия, является оператором . В Прологе мы можем использовать предикат 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) и т. Д. вместо использования более низкоуровневых арифметических предикатов.
Также см. clpfd , clpq и clpb для получения дополнительной информации.
По совпадению оператор =:=
используется CLP (B) с полностью другим значением:
?- sat(A =:= B+1).
<b>A = 1,
sat(B=:=B).</b>
Это показывает, что вы должны различать операторов и предикатов . В приведенном выше случае предикат sat/1
интерпретировал данное выражение как формулу высказывания, и в этом контексте =:=
обозначает равенство булевых выражений.