Проверка типа термов

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.