Ответ 1
?- 2+3 =:= 6-1.
true.
?- 2+3 is 6-1.
false.
Также см. docs http://www.swi-prolog.org/pldoc/man?predicate=is/2
В Prolog есть некоторые специальные операторы, один из которых "есть", однако недавно я столкнулся с операторами =: =, и я понятия не имею, как это работает.
Может кто-нибудь объяснить, что делает оператор, а также где я могу найти предопределенный список таких специальных операторов и что они делают?
Спасибо.
?- 2+3 =:= 6-1.
true.
?- 2+3 is 6-1.
false.
Также см. docs http://www.swi-prolog.org/pldoc/man?predicate=is/2
Я думаю, что вышеупомянутый ответ заслуживает нескольких слов объяснения здесь.
Краткая заметка: арифметические выражения в Prolog - это просто термины ( "Все - это термин в Prolog" ), которые не оцениваются автоматически. (Если у вас есть фон Lisp, подумайте о цитированных списках). Таким образом, 3 + 4
является таким же, как +(3,4)
, что ничего не делает сам по себе. Ответственность за эти термины лежит на индивидуальных предикатах.
Некоторые встроенные предикаты неявно оценивают, среди них арифметические операторы сравнения, такие как =:=
и is
. Пока =:=
оценивает оба аргумента и сравнивает результат, is
принимает и оценивает только его правый аргумент как арифметическое выражение.
Левый аргумент должен быть атомом, либо числовой константой (которая затем сравнивается с результатом оценки правильного операнда), либо переменной. Если это связанная переменная, ее значение должно быть числовым и сравниваться с правым операндом, как в первом случае. Если это несвязанная переменная, результат оценки правильного операнда привязан к этой переменной. 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
.
В дополнение к существующим ответам я хотел бы указать несколько дополнительных пунктов:
Прежде всего, оператор =:=
является, как указывает имя, оператором . В Prolog мы можем использовать предикат 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 аргумента. N/n > .
Как уже объясняли другие, предикат < t (=:=)/2
обозначает арифметическое равенство двух арифметических выражений. Это верно, если его аргументы оцениваются одним и тем же номером.
Например, попробуем самый общий запрос который мы просим о любом решении, используя переменные в качестве аргументов:
?- X =:= Y. ERROR: Arguments are not sufficiently instantiated
Следовательно, этот предикат не является истинным отношением, поскольку мы не можем использовать его для генерации результатов! Это довольно серьезный недостаток этого предиката, столкнувшись с тем, что вы обычно называете "декларативным программированием".
Предикат работает только в очень конкретной ситуации, когда оба аргумента полностью создаются. Например:
?- 1 + 2 =:= 3. true.
Мы называем такие предикаты модными, потому что их можно использовать только в определенных режимах использования. Для подавляющего большинства начинающих модерируемые предикаты - это кошмар для использования, потому что они требуют, чтобы вы относились к вашим программам процедурно, что довольно сложно вначале и остается сложным и позже. Кроме того, измененные предикаты сильно ограничивают общность ваших программ, потому что вы не можете использовать их во всех направлениях, в которых вы можете использовать предикаты pure  .
Prolog также предоставляет гораздо более общие арифметические предикаты в виде арифметических ограничений.
Например, в случае целых чисел попробуйте использовать систему Prolog CLP (FD). Один из самых важных ограничений CLP (FD) обозначает арифметическое равенство и называется (#=)/2
. В полной аналогии с (=:=)/2
оператор (#=)/2
также определяется как оператор infix, поэтому вы можете написать, например:
| ?- 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)
Обратите внимание, как естественно эти предикаты смешиваются с Prolog и действуют как отношения между целыми выражениями, которые могут быть запрошены во всех направлениях.
В зависимости от области интереса моя рекомендация заключается в использовании CLP (FD), CLP (Q), CLP (B) и т.д. вместо использования более низких арифметических предикатов.
Также см. clpfd, clpq и clpb для получения дополнительной информации.
Кстати, оператор =:=
используется CLP (B) с совершенно другим значением:
?- sat(A =:= B+1). A = 1, sat(B=:=B).
Это показывает, что вы должны различать операторы и предикаты. В приведенном выше случае предикат < t217 > интерпретировал данное выражение как формулу пропозиционального и в этом контексте =:=
обозначает равенство логических выражений.
Я нашел свой собственный ответ, http://www.cse.unsw.edu.au/~billw/prologdict.html
=: = - оператор сравнения .A1 =: = A2 успешно, если значения выражений A1 и A2 равны. A1 == A2 преуспевает, если члены A1 и A2 идентичны;
Это базовый стандартный оператор предиката 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
Первый оператор =: = проверяется равным? например введите здесь описание изображения
он возвращает true. но это возвращает false введите здесь описание изображения