ТОП 10:

Структура программы на Прологе. Стандартные предикаты



 

Структура Пролог-программы

Использование в Пролог-программах только двух секций, т.е. predicates и clauses, является достаточным только для простейших программ, которые не используют описание данных и их структур, не работают с динамическими базами данных. Рассмотрим более подробно назначение каждой из секций программы.

В секции domains объявляются любые нестандартные домены, используемые для аргументов предикатов. Домены в Прологе являются аналогами типов в других языках. Основными стандартными доменами Пролога являются:

char - символ, заключенный в одиночные кавычки (например, 'а');

integer – целое число;

real – вещественное число;

string - последовательность символов, заключенных в двойные кавычки (например, "нажмите ввод");

symbol - либо набор латинских букв, цифр и символов подчеркивания, в котором первый символ - прописная буква (например, n_fax ) ; либо последовательность символов, содержащая пробелы или начинающаяся со строчной буквы, заключенная в кавычки (например, "Список СУБД").

file - символическое имя файла, которое начинается с прописной буквы.

Кроме стандартных доменов пользователь может использовать свои.

Для этого в области объявления доменов можно использовать следующие форматы:

а) ИмяТипаПеременной = СтандартныйДомен.

domains

fio = symbol

year, height = integer

б) ИмяСписка = ИмяТипаПеременной*, где ИмяСписка - область, состоящая из списков элементов типа ИмяТипаПеременной, которая может быть определена пользователем или иметь стандартный тип.

domains

number = integer*

letter = char*

в) ИмяСтруктуры = functor1(d11,…,d1n); functor2(d21,..., d2n) ; ... functorm(dm1,...,dmq) , где ИмяСтруктуры - область, которая состоит из составных объектов, описываемых указанием функтора и областей для всех компонентов. Например,

auto = car(symbol,integer) ,

packing = box(integer, integer, integer)

+ [3, стр10]

г) file = name1; name2 ; ... namen используется, когда пользователю необходимо ссылаться на файлы по их символическим именам.

Пример. Требуется разработать структуру данных для хранения информации о компьютерах. При этом каждый компьютер будет рассматриваться как набор входящих в него устройств, среди которых могут быть: процессоры с указанием их наименования и частоты, жесткий диск с указанием объема и фирмы изготовителя, также мониторы определенного типа. Область определения доменов для этого примера будет иметь вид

domains

name , firm , type = symbol

freq , vol = integer

device = processor(name,freq); disk(firm,vol); monitor(type)

computer = device*

В этом описании домен computer является списком элементов типа device, то есть каждый элемент этого списка может иметь структуру типа либо processor, либо disk, либо monitor, содержащих одну или две компоненты, каждая из которых имеет стандартный символьный или целый тип.

Все структурированные объекты можно представить графически в виде деревьев. Корнем дерева является функтор, а ветвями — компоненты. Если компонент представляет собой структуру, он становится поддеревом этого дерева, которое соответствует всему структурированному объекту.

В секции predicates объявляются предикаты и типы (домены) аргументов этих предикатов. Имена предикатов должны начинаться со строчной латинской буквы, за которой следует последовательность букв, цифр и символов подчеркивания (до 250 знаков). В именах предикатов нельзя использовать символы пробела, минуса, звездочки, обратной (и прямой) черты. Объявление предикатов имеет форму:

predicates

predicateName1 (domen11, domen12,..., domen1m)

predicateNamen (domenn1, domenn2,..., domennk)

Здесь domenij - либо стандартные домены, либо домены, объявленные в секции domains. Объявление домена аргумента и описание типа аргумента - суть одно и то же. Количество доменов (аргументов) предиката определяют арность (размерность) предиката. Предикат может не иметь аргументов и указываться только именем. Обычно выбирается такое имя предиката, чтобы оно отражало определенный вид взаимосвязи между аргументами предиката.

Если предикат один, то он называется однозначным (derministic), а если в базе знаний может быть несколько экземпляров данного предиката, то такой предикат называется неоднозначным (non-derministic), и это необходимо указать в описании предиката.

Пример описания предикатов:

predicates

nondeterm student (string, real)

start /* это однозначный предикат;

determ можно не писать */

nondeterm good_student (string)

Можно использовать несколько описаний одного и того же предиката. При этом все описания должны следовать одно за другим и должны иметь одно и то же число аргументов. Пусть требуется определить отношение между тремя аргументами, первые два из которых соответствуют слагаемым, а третий - сумме двух первых. Этот предикат может быть описан в следующем виде

predicates

nondeterm add(integer,integer,integer)

nondeterm add(real,real,real)

и позволит его аргументам принимать значения как из области целых, так и действительных чисел.

В секции clauses размещаются факты и правила, с которыми будет работать - Пролог, пытаясь разрешить цель программы.

Пример фактов, определяющих отношение, заданное предикатом student, может иметь вид:

clauses

student ("Петров", 4.5).

student ("Сидоров",3.75).

Правила содержат утверждения, истинность которых зависит от некоторых условий (подцелей), образующих тело правила. В Прологе правила представляются в виде

Заголовок :- Подцель1 , Подцель2 , ... , ПодцельN .

где обозначение :- читается как "если", а Заголовок имеет такую же форму, как и факт. Тело правила - это список подцелей, разделенных запятыми. Запятая понимается как конъюнкция и читается как "и". Пример записи правила

good_student(Name) :- student(Name , В) , В > 4.

Для того, чтобы заголовок правила оказался истинным, необходимо, чтобы каждая подцель, входящая в тело правила, была истинной.

Практикум 2-1

: Создайте базу знаний (БЗ), хранящую сведения о студентах (не менее 10) и их средних баллах. Напишите правило, определяющее «хороших» (по среднему баллу) студентов. Практически у каждого студента есть какое-то хобби (возможно, не одно). Добавьте факты с информацией о хобби в БЗ. Создайте запросы для ответов на следующие вопросы: 1. Какие хобби у «хороших» студентов? 2. Кто-нибудь увлекается фотографией? 3. Какие средние баллы у студентов, увлекающихся футболом?

 

Множество правил, заголовки которых содержат одинаковые имена предикатов и одинаковое количество аргументов, называются процедурой. На рис. 2.1 представлены правила, которые реализуют процедуру нахождения наибольшего из двух действительных чисел, определяемую предикатом вида max(number1, number2, max_number). Считается, что между этими правилами неявно присутствует соединительный союз "или".

Рис. 2.1.Нахождение максимального числа

Практикум 2-2

:   Создайте программу вычисления максимального и минимального из трех целых чисел.  

 

В секции goal задается внутренняя цель программы. Цель может состоять из нескольких предикатов (из нескольких подцелей). Если внутренняя цель не используется, то в процессе работы есть возможность вводить в диалоговом окне внешнюю цель.

Часто целью является сложный запрос к программе. Для разрешения какой-либо сложной цели Пролог должен разрешить все его подцели, создав при этом необходимое множество связанных переменных. Если же одна из подцелей ложна, Пролог возвратится назад и просмотрит альтернативные решения предыдущих подцелей, а затем вновь пойдет вперед, но с другими значениями переменных. Этот процесс называется "поиск с возвратом".

Стандартные предикаты

В систему Пролог включено более 200 встроенных стандартных предикатов и более дюжины стандартных доменов. В случае использования этих предикатов и доменов нет необходимости объявлять их в программе.

Ввод и вывод

С помощью встроенных предикатов ввода-вывода программа, взаимодействуя с пользователем, может принимать от него данные и печатать результаты. Рассмотрим простейшие предикаты ввода\ вывода.

Ввод данных.

readln(X) – для ввода строки

readint(X) – для ввода целых чисел

readchar(X) – для ввода символов

readreal(X) – для ввода действительных чисел

По умолчанию данные вводятся с клавиатуры терминала, ввод завершается нажатием клавиши “Enter”.

Для вывода используется предикат

write(T1,T2,…,Tn).

Он выводит значения T1,T2,…,Tn на текущее устройство вывода, по умолчанию, на экран. Предикат write(…) не допускает повторного согласования и выполняется лишь один раз. Переход на новую строку при печати данных обеспечивается встроенным предикатом nl, название которого образовано аббревиатурой (начальными буквами) слов «newline» новая строка. Как и write, предикат nl выполняется только один раз.

 

Перечень и назначение стандартных предикатов приведен в Приложении 1.

Рассмотрим пример программы, в которой используется обращение к стандартным предикатам (рис.2.2):

Рис. 2.2. Использование стандартных предикатов

В этой программе запрашивается Ваше имя, а затем оно выводится на экран.

Практикум 2-3

:   Добавьте в программу, представленную на рис.2.2 факты, хранящие пароли пользователей с параметрами (Имя, Пароль). Модифицируйте предикат hello (или создайте новый) - после ввода пользователем имени запросите пароль, если среди фактов будет обнаружено такое сочетание имени и пароля, то сообщить приветствие, а если нет – выдать сообщение: «Пользователь или пароль указан не верно. Повторить попытку (да или нет)? ». Если пользователь ответил «да», то повторить запрос имени и пароль, если «нет», то закончить работу программы.  

 







Последнее изменение этой страницы: 2017-02-10; Нарушение авторского права страницы

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.234.244.18 (0.009 с.)