- •Основные понятия Искусственного Интеллекта
- •Основные направления исследований в области Искусственного Интеллекта
- •Логическое программирование. Основные понятия языка Пролог (Предикаты, Факты, Правила, Простые и составные запросы).
- •Константы, переменные и составные термы. Сопоставление.
- •Основные разделы Prolog. Встроенные предикаты
- •Арифметические вычисления и сравнения в прологе
- •Встроенные предикаты ввода и вывода
- •Управление поиском решений. Встроенный механизм поиска с возвратом. Использование предиката fail и отсечение.
- •Рекурсия
- •Обработка списков. Объявление и использование.
- •Обработка строк. Предикаты для строк. Встроенные предикаты для преобразования типов. Использование строк.
- •Файлы. Оисание. Стандартные предикаты. Операции над файлами.
- •Работа с внутренними базами данных: добавление и удаление фактов из базы данных.
- •Данные и знания.
Встроенные предикаты ввода и вывода
Предикат readln считывает строку с текущего устройства ввода и связывает ее со своим единственным выходным параметром.
Предикат readint читает с текущего устройства целое число и связывает его со своим единственным выходным параметром.
Предикат readreal отличается от предиката readint тем, что он считывает не целое, а вещественное число.
Для чтения символа с текущего устройства ввода используется предикат readchar. Есть еще предикат inkey, который так же, как и readchar, читает символ со стандартного устройства ввода. Разница между ними в том, что предикат readchar приостанавливает работу программы до тех пор, пока не будет введен символ, а предикат inkey не прерывает выполнение программы. Если нужно просто проверить, нажата ли клавиша, можно воспользоваться предикатом keypressed, не имеющим аргументов.
Предикат readterm предназначен для чтения сложных термов. У него два параметра: первый входной указывает имя домена, второй параметр конкретизируется термом домена, записанного в первом параметре. Если считанная этим предикатом строка не соответствует домену, указанному в его первом параметре, предикат выдаст сообщение об ошибке.
Для записи данных в текущее устройство записи служит предикат write. Он может иметь произвольное количество параметров. Кроме того, в Турбо Прологе есть еще и предикат writef, который служит для форматного вывода данных.
Для осуществления перехода на следующую строку (возврат каретки и перевод строки) применяется предикат nl, не имеющий параметров.
Управление поиском решений. Встроенный механизм поиска с возвратом. Использование предиката fail и отсечение.
Основной операцией в Прологе при поиске решений, является операция сопоставления цели с имеющимися в программе фактами, для получения логического вывода об истине или лжи значений цели.
В прологе имеются средства позволяющие управлять, при необходимости, процессом поиска решений. Для организации повторений можно применять встроенный предикат «fail». Выполнение этого предиката всегда дает ложное значение.
Например: В прологе содержатся имена городов, вывести все имена во внутренней цели.
Predicates
city(symbol)
show
Clauses
city(moskow).
city(kiev).
city(kazan).
show :- city(X), write(X), nl, fail.
Goal
show.
На экране увидим:
moskow
kiev
kazan
Замечание: Всегда ложный предикат fail, вызывает откат для поиска других утверждений, который может обеспечить выполнение цели, без fail, то для внутренней цели поиск был бы прекращен, после нахождения названия первого города. Применение этого метода, позволяет извлекать данные из каждого утверждения.
Для того чтобы иметь возможность выбирать данные удовлетворяющие некоторым условиям, необходимо иметь средство управления откатом. В прологе для этого используется предикат отсечения (!). Этот предикат, вычисление которого всегда успешно, заставляет внутри программы сопоставления забыть все указатели отката, установления во время попыток вычислить предыдущие подцели.
Рекурсия
Для организации повторений, в прологе используется рекурсия.
Рекурсия — это предикат, вызывающий сам себя, до тех пор, пока не будет соблюдено некоторое условие, которое остановит рекурсию.
Пример рекурсии: найти факториал n!.
Задача нахождения значения факториала n! очень хорошо решается с помощью рекурсии, поскольку может быть сведена к решению аналогичной подзадачи, которая, в свою очередь, сводится к решению аналогичной подзадачи и т.д.
Действительно, чтобы найти значение факториала n!, можно найти значение факториала (n-1)! и умножить найденное значения на n. Для нахождения значения факториала (n-1)! можно пойти по уже известному пути - найти значение факториала (n-2)! и умножить найденное значения на n-1. Так можно действовать до тех пор, пока не доберемся до нахождения значения факториала (n-n)! или другими словами, факториала 0!. Значение факториала 0! известно - это 1. Вот это и будет граничное условие, которое позволит остановить рекурсию. Все, что теперь остается - это умножить полученную единицу на (n-(n-1)), затем на (n-(n-2)) и т.д. столько раз, сколько было рекурсивных вызовов. Результат n! получен.
Вот как выглядит программа, которая проделывает вычисление n! (нужно заметить, что предложения Prolog - программы достаточно точно повторяют формулировку задачи на естественном языке).
PREDICATES
factorial (integer, integer)
CLAUSES
%факториал 0! равен 1
factorial (0, 1):- !.
%факториал n! равен факториалу (n-1)!, умноженному на n
factorial (N, Factorial_N):- M=N-1, factorial (M, Factorial_M),
Factorial_N=Factorial_M*N.
GOAL
write ("Для какого числа Вы хотите найти факториал? "), readint (Number),
factorial (Number, Result), write (Number, "!=", Result).
Результат работы программы: 3!=6