Проверка типа термов
7.1.1. Предикатыvar, nonvar, atom, integer, float, number, atomic, compound
Термы могут принадлежать к разным типам: переменная, целое число, атом и т.д. Если терм представляет собой переменную, то он может быть в некоторый момент во время выполнения программы конкретизирован или не конкретизирован. Кроме того, если он конкретизирован, его значением может быть атом, структура и т.д. Иногда необходимо знать, к какому типу относится это значение. Например, в программе может потребоваться сложить значения двух переменных, X и Y, следующим образом:
Z is X + Y
Прежде чем выполнить эту цель, необходимо конкретизировать X и Y числовыми значениями. А если нет полной уверенности в том, что к этому моменту х н Y действительно конкретизированы числовыми значениями, то следует проверить это в программе перед выполнением арифметической операции.
Для этого может использоваться встроенный предикат number. Предикат number (X) принимает истинное значение, если X — число или переменная, значением которой является число. В таких случаях принято говорить, что X "должен в настоящее время обозначать" число. Таким образом, цель, предусматривающую сложение X и Y, можно защитить (обеспечить ее безошибочное выполнение) с помощью следующей проверки X и Y: ..., number! X), number ( Yj', Z is X + Y, ...
Если и X, и Y не являются целыми числами, то не будет предпринята попытка выполнить арифметическую операцию. Поэтому предикат number предназначен для "защиты" цели 2 is х + V от бессмысленного выполнения,
К встроенным предикатам такого типа относятся var, nonvar, atom, integer, float, number, atomic, compound. Назначение этих предикатов описано ниже.
• var{ X). Выполняется успешно, если X в настоящее время — неконкретизи-розаштяпеременная.
• nonvar ( X). Выполняется успешно, если X — ■ не переменная или X— уже конкретизированная переменная.
• atom( X). Принимает истинное значение, если X в настоящее время обозначает атом.
• integer ( X). Принимает истинное значение, если X в настоящее время обозначает целое число.
• float [X). Принимает истинное значение, если х в настоящее время обозначает число с плавающей точкой.
• number ( X). Принимает истинное значение, если X в настоящее время обозначает число.
• atomic ( X). Принимает истинное значение, если X в настоящее время обозначает число или атом.
• compound ( X). Принимает истинное значение, если X в настоящее время обозначает составной терм (структуру).
Приведенные ниже примеры вопросов к системе Prolog иллюстрируют использование этих встроенных предикатов.
?- var (Z) , Z = 2 .
Z = 2
?- Z = 2, var( Z).
no
1- integer( Z), S = 2.
no
?- z = 2, integer[ z) , nonvar[ z) ,
z - >
?- atom! 3.14) .
no
?- atomic; 3.14) .
yes
?- at«a( ==> ;.
yes
?- ato»( pd)). no
?- compound ( 2 + X)
yes
Часть I. Язык Prolog
• Рассмотрим необходимость в использовании предиката atom на примере. Предположим, что требуется подсчитать, сколько раз указанный атом встречается в заданном списке объектов. Для этой цели определим следующую процедуру:
count! A, L, И)
где А — атом, L — список, а N — количество вхождений. Первая попытка определить процедуру count может представлять собой следующее:
count! , [] , 0) .
count [~Ar [AIL], В) :- !,
count! A, L, N1), % HI — количество вхождений атома в хвосте списка N is N1 + 1. count! A, L 1 L], N) :-count! A, L, Щ .
Проверим функционирование этой процедуры на нескольких примерах следующим образом:
?- count! а, rarb,a,a], H) . N = 3
?- count ( a, [a,b,X,Y], Nat. На - 3
?- count! Ь, [a,b,X,Y], lib). Mb = 3
?- L = [а, Ь, X, У], count! a, L, Na), count [ Ь, L, Nb).
Na = 3 Nb = 1
Y=a
В последнем примере и X, и Y были конкретизированы значением а, поэтому были получены результаты подсчета, учитывающие только одно вхождение a, Ко = 1, но это не входило в наши намерения. Данная процедура предназначена для подсчета количества реальных вхождений указанного атома, а не количества термов, которые согласуются с этим атомом. В соответствии с данным более точным определением отношения count необходимо проверить, является ли голова рассматриваемого списка атомом. Модифицированная программа приведена ниже.
count (А, [В | L] ,т: -
atom! В), а = Б, !, % Представляет лисобой В атом А?
count! a. Lr N1) , \ Если да, то выполнитьподсчет в хвосте списка
В is Mi + 1
count ( A, L, N). % Иначе выполнять подсчет только в хвосте списка
В следующем, более сложном упражнении по программированию в области решения числовых ребусов применяется предикат nonvar.