Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | ||
|
Термы бывают разных типов: переменные, целые числа, атомы и т.д. Если терм — переменная, то в некоторый момент выполнения программы он может оказаться конкретизированным или не конкретизированным. Далее, если он конкретизирован, то его значение может быть атомом, структурой и т.п. Иногда бывает полезно узнать, каков тип этого значения. Например, пусть мы хотим сложить значения двух переменных X и Y:
Z is X + Y
Перед вычислением этой цели необходимо, чтобы X и Y были конкретизированы целыми числами. Если у нас нет уверенности в том, что X и Y действительно конкретизированы целыми числами, то перед выполнением арифметического действия нужно проверить это программно.
Для этого следует воспользоваться встроенным предикатом integer (целое). Предикат integer(X) принимает значение истина, если X — целое или если X — переменная, имеющая целое значение. Будем говорить в этом случае, что X "обозначает" целое. Цель для сложения X и Y можно тогда "защитить" такой проверкой переменных X и Y:
..., integer(X), integer(Y), Z is X + Y,...
Если неверно, что X и Y оба являются целыми, то система и не будет пытаться их сложить. Таким образом, цели integer "охраняют" цель Z is X + Y от бессмысленного вычисления.
Встроенные предикаты этого типа таковы: var (переменная), nonvar (непеременная), atom (атом), integer (целое), atomic (атомарный). Они имеют следующий смысл:
var(X)
Эта цель успешна, если X в текущий момент — не конкретизированная переменная.
nonvar(X)
Эта цель успешна, если X — терм, отличный от переменной, или если X — уже конкретизированная переменная.
atom(X)
Эта цель истинна, если X обозначает атом.
integer(X)
Цель истинна, если X обозначает целое.
atomic(X)
Цель истинна, если X обозначает целое или атом.
Следующие примеры вопросов к пролог-системе иллюстрируют применение этих встроенных предикатов:
?- var(Z), Z = 2.
Z = 2
?- Z = 2, var(Z).
no
?- integer(Z), Z = 2.
no
?- Z = 2, integer(Z), nonvar(Z).
Z = 2
?- atom(22).
no
?- atomic(22).
yes
?- atom(==>).
yes
?- atom(p(1)).
no
Необходимость в предикате atom продемонстрируем на следующем примере. Пусть мы хотим подсчитать, сколько раз заданный атом встречается в некоторой списке объектов. Для этого мы определим процедуру
счетчик(А, L, N)
где А — атом, L — список и N — количество вхождений этого атома. В качестве первой попытки можно было бы определить счетчик так:
счетчик(_, [], 0).
счетчик(A, [A | L], N):-!,
счетчик(A, L, N1),
% N1 - число вхождений атома в хвост
N is N1 + 1.
счетчик(А, [ _ | L], N):-
счетчик(A, L, N).
Теперь на нескольких примерах посмотрим, как эта процедура работает:
?- счетчик(а, [а, b, а, а], N).
N = 3
?- счетчик(a, [a, b, X, Y], Na).
Na = 3
...
?- счетчик(b, [a, b, X, Y], Nb).
Nb = 3
...
?- L=[a, b, X, Y], счетчик(а, L, Na), счетчик(b, L, Nb).
Na = 3
Nb = 1
X = a
Y = a
...
В последнем примере как X, так и Y после конкретизации получили значение а, и поэтому Nb оказалось равным только 1, однако мы хотели не этого. Нас интересовало количество реальных появлений конкретного атома, а вовсе не число термов, сопоставимых с этим атомом. В соответствии с этим более точным определением отношения счетчик мы должны теперь проверять, является ли голова списка атомом. Усовершенствованная программа выглядит так:
счетчик(_, [], 0).
счетчик(А, [В | L], N):-
atom(В), А = В,!, % B равно атому А?
счетчик(A, L, N1), % Подсчет в хвосте
N is N1 + 1;
счетчик(А, L, N).
% Иначе - подсчитать только в хвосте
В следующем более сложном упражнении по программированию числовых ребусов используется предикат nonvar.
Дата публикования: 2015-10-09; Прочитано: 181 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!