Программирование на языке Пролог для искусственного интеллекта
Шрифт:
Эта программа породит только одно решение. Например:
5.2.3. Добавление элемента к списку, если он в нем отсутствует (добавление без дублирования)
Часто требуется добавлять элемент X в список L только в том случае, когда в списке еще нет такого элемента. Если же X уже есть в L, тогда L необходимо оставить без изменения, поскольку нам не нужны лишние дубликаты X. Отношение
где X — элемент, который нужно добавить, L — список, в который его нужно добавить, L1 — результирующий новый список. Правила добавления можно сформулировать так:
если X принадлежит к L, то L1 = L,
иначе L1 — это список L с добавленным к нему элементом X.
Проще всего добавлять X в начало списка L так, чтобы X стал головой списка L1. Запрограммировать это можно так:
Поведение этой процедуры можно проиллюстрировать следующим примером:
Этот пример поучителен, поскольку мы не можем легко запрограммировать "недублирующее добавление", не используя отсечения или какой-либо другой конструкции, полученной из него. Если мы уберем отсечение в только что рассмотренной программе, то отношение
Поэтому отсечение требуется здесь для правильного определения отношения, а не только для повышения эффективности. Этот момент иллюстрируется также и следующим примером.
5.2.4. Задача классификации объектов
Предположим, что у нас есть база данных, содержащая результаты теннисных партий, сыгранных членами некоторого клуба. Подбор пар противников для каждой партия не подчинялся какой-либо системе, просто каждый игрок встречался с несколькими противниками. Результаты представлены в программе в виде фактов, таких как
Мы хотим определить
которое распределяет игроков по категориям. У нас будет три категории:
Например, если в нашем распоряжении есть лишь приведенные выше результаты, то ясно, что Энн и Пат — победители. Том — боец и
Легко сформулировать правило для бойца:
X — боец, если существует некоторый Y, такой, что X победил Y, и
существует некоторый Z, такой, что Z победил X.
Теперь правило для победителя:
X — победитель, если
X победил некоторого Y и
X не был побежден никем.
Эта формулировка содержит отрицание "не", которое нельзя впрямую выразить при помощи тех возможностей Пролога, которыми мы располагаем к настоящему моменту. Поэтому оказывается, что формулировка отношения
Если X победил кого-либо и X был кем-то побежден,
то X — боец,
иначе, если X победил кого-либо,
то X — победитель,
иначе, если X был кем-то побежден,
то X — спортсмен.
Такую формулировку можно сразу перевести на Пролог. Взаимные исключения трех альтернативных категорий выражаются при помощи отсечений:
Заметьте, что использование отсечения в предложении для категории
5.1. Пусть есть программа:
Напишите все ответы пролог-системы на следующие вопросы:
(a)
(b)
(c)
5.2. Следующие отношения распределяют числа на три класса - положительные, нуль и отрицательные:
Сделайте эту процедуру более эффективной при помощи отсечений.
5.3. Определите процедуру
которая разбивает список чисел на два списка: список, содержащий положительные числа (и нуль), и список отрицательных чисел. Например,
Предложите две версии: одну с отсечением, другую — без.
5.3. Отрицание как неуспех
"Мэри любит всех животных, кроме змей". Как выразить это на Прологе? Одну часть этого утверждения выразить легко: "Мэри любит всякого X, если X — животное". На Прологе это записывается так: