У меня в ПЗУ 1.0
1.1 - это у ММ
Вид для печати
У меня в ПЗУ 1.0
1.1 - это у ММ
Дописываю новую документацию, а пока для истории продолжаю выкладывать старые публикации:
"Информатика и образование" №5 1990
Скрытый текст
С. Григорьев
Йошкар-Ола
Программирование на Прологе-Д
Программа на Прологе представляет собой базу знаний и следующий за ней вопрос. Построению базы знаний посвящена данная статья. Здесь рассматриваются структура программы и некоторые приемы технологии программирования, связанные с использованием встроенных предикатов, рекурсии, графики, специфичные для Пролога-Д. Как и прежде во всех случаях, где это необходимо, будут оговариваться различия Пролога-Д MSX и Пролога-Д БК-0010.
Факты и правила
Особенностью языка Пролог-Д, отличающей его от других языков, используемых для работы на ЭВМ, является его применение не для программирования, но главным образом для описания данных и правил их обработки. Построение базы знаний на Прологе-Д означает выявление множества исследуемых объектов и связей между ними, совокупность которых описывает явление или процесс: иными словами, создание информационно-логической модели описываемого на языке Пролог-Д явления или процесса.
Первый шаг построения базы знаний состоит в выявлении объектов и соотношений между ними, отвечающих на вопрос «что дано?». Такую информацию целесообразно представлять в виде совокупности факсов. Классическим примером фактографии служит англо-русский словарь. Записанный средствами Пролога-Д, он выглядит так:
и т.д. Подобные отношения представляют собой грамматическую конструкцию Пролога-Д, называемую фактом. Факт задается в виде функционала: имя и совокупность аргументов. В данном примере «русангл» - это имя; оно определяет информацию, записываемую в факте. Русские и английские слова мама, mammy, небо, sky, солнце, sun, мальчик, boy представляют собой аргументы фактов, определяющих взаимно-однозначное соответствие между русскими и английскими словами. Необязательно, чтобы факт имел два аргумента. Например, фактКод:русангл(мама,mammy);
русангл(небо,sky);
русангл(солнце,sun);
русангл(мальчик,boy);
имеет один аргумент Николай, а фактКод:мужчина(Николай);
имеет пять аргументов. Однако с точки зрения синтаксиса языка Пролог-Д необходим хотя бы один аргумент. Если факт в базе знаний имеет имя и не имеет аргументов, то система выдаст сообщение о синтаксической ошибке.Код:родился(Петров,Иван,10,сентябрь,1979);
Приведенный пример, по сути дела, уже является базой знаний. Перед этой базой знаний можно ставить различные вопросы:
если необходимо узнать все слова, хранящиеся в базе знаний;Код:?русангл(у,х);
чтобы узнать, как по-английски «мама»;Код:?русангл(мама,х);
чтобы узнать, что значит слово sky.Код:?русангл(х,sky);
Для описания всего множества информации достаточно фактов. Однако если можно задать некоторые связи и отношения между объектами, то удается сократить число фактов и тем самым сделать базу знаний более лаконичной. Связи и отношения между объектами задаются правилами. При построении правил выделяется совокупность отношений, отвечающих на вопрос «что известно?». Правило можно построить, пользуясь известным принципом разделения исходной задачи на более простые, которые тоже, в свою очередь, могут быть разделены. Этот процесс известен под названием декомпозиции задачи. Декомпозиция заканчивается в тот момент, когда отношения связывают зафиксированные в базе знаний объекты. Например, в задаче о построении родственных отношений можно определить следующие правила:
Левая часть правила называется головой; разделенные запятыми выражения в правой части - целями; последние образуют тело правила.Код:бабушка(x,y)<-мама(x,z),мама(z,у);
бабушка(х,у)<-мама(x,z),папа(z,y);
дедушка(х,у)<—папа(х,z),папа(z,у);
дедушка(х,у)<-папа(x,z),мама(z,y);
Процесс декомпозиции не обязательно однозначен. Даже простой пример о родственниках допускает и иную трактовку. Если ввести правило, определяющее понятие «родитель»
то бабушку и дедушку можно определить проще:Код:родитель(х,у)<-мама(х,у);
родитель(х,у)<-папа(х,у);
Если к только что записанным правилам добавить несколько фактов, определяющих мам и пап, то получается база знаний «семья»:Код:бабушка(х,у)<-мама(x,z),родитель(z,y);
дедушка(х,у)<-папа(x,z),родитель(z,y);
В данном примере для определения понятия родитель(х, у) потребовалось более одного правила. По сути дела, здесь использовано недетерминированное ветвление, дающее альтернативное определение этого отношения и используемое системой после того, как было применено первое отношение. Следует подчеркнуть, что в определении участвуют оба правила. В общем случае число правил не ограничено.Код:мама(Саша,Петя);
папа(Сережа,Петя);
мама(Оля,Саша);
папа(Коля,Саша);
мама(Люда,Сережа);
папа(Петя,Сережа);
родитель(x,y)<-мама(x,y);
родитель(x,y)<-папа(x,y);,
бабушка(x,y)<-мама(x,z),родитель(z,y);
дедушка(x,y)<-папа(x,z),родитель(z,y);
Упражнения.
- В электронике известно понятие «стандартный ряд номинальных значений сопротивлений»: 10, 11, 12, 13, 15, 16, 18, 20 22, 24, 27, ЗС, 33, 36, 39, 43, 47, 51, 56, 62, 68, 75, 82, 91. Любое сопротивление, выпущенное промышленностью, имеет номинал, кратный элементам указанного ряда. Напишите базу знаний, в которой описывается этот ряд.
- Опишите на языке Пролог-Д состав своей семьи.
- Составьте базу знаний, описывающую республики, входящие в состав СССР.
- Напишите на языке Пролог-Д таблицу умножения чисел от 1 до 10. Какое количество предложений требуется для записи этой базы знаний?
Арифметические и другие встроенные предикаты в Прологе-Д
Системы логического программирования, к числу которых относится и Пролог-Д, не предназначены для вычислений. Традиционный для Пролога-Д подход при выполнении арифметических действий дан в упражнении 4 из предыдущего раздела. Однако для определения таким образом всех математических действий памяти компьютера будет явно недостаточно. Поэтому традиционные действия, связанные с выполнением арифметических операций, осуществляются посредством специальных, так называемых встроенных предикатов.
В системе Пролог-Д БК-0010 для выполнения арифметических действий предусмотрен один встроенный арифметический предикат:
В системе Пролог-Д MSX для выполнения арифметических действий предусмотрены два встроенных арифметических предиката:Код:ВЫЧ(Арг1,Арг2,АргЗ,Арг4)
Встроенный предикат ВЫЧ (в MSX УМНОЖЕНИЕ) имеет четыре аргумента (целых; переменных, конкретизированных целыми; неконкретизированных переменных). ВЫЧ (в MSX УМНОЖЕНИЕ) обеспечивает реализацию формулыКод:УМНОЖЕНИЕ(Арг1,Арг2,АргЗ,Арг4)
СЛОЖЕНИЕ(Арг1,Арг2,АргЗ)
Предикаты предусматривают обратимость аргументов и полностью покрывают арифметические операции в области целых чисел, предусмотренных синтаксисом входного языка (0 <= <число> <= 65535 «Электроника БК-0010» и -32766 <= <число> <= 32766 в системе MSX). Если результат дробный, он округляется до целого. Оба предиката могут быть использованы только в качестве цели в предложении.Код:Арг1*Арг2+Арг3=Арг4
Предикат СЛОЖЕНИЕ (Арг1,Арг2,АргЗ) обеспечивает реализацию формулы
Следующая база знаний на языке Пролог-Д показывает, как можно описать любые арифметические операции в системе Пролог-Д БК-0010:Код:Арг1+Арг2=Арг3
Во всех четырех случаях X, Y - операнды операций, a Z - результат. Например, СЛОЖЕНИЕ (X, Y, Z) реализует арифметическую операцию Z=X+Y.Код:сложение(X,Y,Z)<-ВЫЧ(1,X,Y,Z);
вычитание(X,Y,Z)<-ВЫЧ(1,X,Z,Y);
умножение(X,Y,Z)<-ВЫЧ(X,Y,0,Z);
деление(X,Y,Z)<-ВЫЧ(Y,Z,0,X);
Аналогично в системе Пролог-Д MSX:
Обратите внимание, вычитание можно определить в MSX и иначе:Код:вычитание(X,Y,Z)<-УМНОЖЕНИЕ(1,X,Z,Y);
умнож(X,Y,Z)<-УМНОЖЕНИЕ(X,Y,0,Z);
деление(X,Y,Z)<-УМНОЖЕНИЕ(Y,Z,0,X);
Более подробное описание синтаксиса встроенных арифметических предикатов ВЫЧ, УМНОЖЕНИЕ, СЛОЖЕНИЕ приведено в технических описаниях трансляторов.Код:вычитание(X,Y,Z)<-СЛОЖЕНИЕ(Y,Z,X);
Пример 1. На Прологе-Д опишем вычисление площади прямоугольника, имеющего стороны длиной a и b: S=a*b. Соответствующий предикат должен иметь три аргумента - длины сторон и величину площади. Имя предиката должно отражать его назначение, этому критерию удовлетворит имя «площадь». В системе Пролог-Д БК-0010:
Первый предикат «умножение» потребовалось определить для наглядности записи. Необходимо отметить, что предикат «площадь» обратим, это означает, что, пользуясь этим описанием, можно вычислить не только площадь по заданным сторонам, но и любую (одну) сторону по другой стороне и площади. Перед базой знаний можно поставить вопрос:Код:умножение(X,Y,Z)<-ВЫЧ(X,Y,0,Z);
площадь(a,b,S)<-умножение(a,b,S);
Ответ системы Пролог-Д: S=200Код:?площадь(10,20,S);
Ответ системы Пролог-Д: а=5Код:?площадь(a,20,100);
В системе Пролог-Д MSX:
Пример 2. На Прологе-Д необходимо описать вычисление объема параллелепипеда высотой h, в основании которого прямоугольник, имеющий стороны длиной a и b: V=a*b*h. Соответствующий предикат должен иметь четыре аргумента - длины сторон a, b, высоту h и объем V.Код:умнож(X,Y,Z)<-УМНОЖЕНИЕ(X,Y,0,Z);
площадь(a,b,S)<-умнож(a,b,S);
В системе Пролог-Д БК-0010:
Как и прежде, предикат «объем» обратим, это означает, что, используя это описание, можно вычислить не только объем по заданным сторонам и высоте, но и любую (одну) сторону или высоту по высоте, стороне и объему.Код:умножение(X,Y,Z)<-ВЫЧ(X,Y,0,Z);
объем(a,b,h,V)<-умножение(a,b,S),умножение(S,h,V);
Можно иначе записать объем, если воспользоваться формулой V=Sz. Эту базу знаний предлагается написать самостоятельно.
Перед данной базой знаний можно поставить вопрос:
Ответ системы Пролог-Д: V=1000Код:?объем(10,20,5,V);
В системе Пролог-Д MSX:
Наряду с арифметическим предикатом в системе БК-0010 существуют два предиката БОЛ и НЕ.Код:умнож(X,Y,Z)<-УМНОЖЕНИЕ(X,Y,0,Z);
объем(a,b,h,V)<-умнож(а,b,S),умнож(S,h,V);
Встроенный предикат БОЛ (Арг1,Арг2) предназначен для сравнения двух целых констант или переменных. Он имеет два аргумента (целых или переменных конкретизированных целыми). Оба аргумента к моменту выполнения должны быть определены. Если эти требования не выполнены, то появится сообщение об ошибке: «Функция не может быть выполнена (ошибка 34)». Предикат выполнен, если Арг1>Арг2, иначе не выполнен.
Несмотря на то что предикат БОЛ один, его достаточно для описания всех возможных предикатов для сравнения числовой информации: равенство - «равно», меньше - «меньше», меньше и равно - «мир» и т. д. Это показывает база знаний, приведенная ниже.
В последнем предложении использован встроенный предикат НЕ, его синтаксис:Код:равно(X,X);
меньше(X,Y)<-БОЛ(Y,X);
мир(X,Y)<-НЕ(БОЛ(X,Y)) ;
Он имеет один аргумент, который обязательно должен быть предикатом. Предикат НЕ выполнен тогда и только тогда, когда предикат-аргумент не выполнен.Код:НЕ(Арг1);
А теперь несложный пример, иллюстрирующий применение БОЛ и НЕ.
Пример 3. Опишите на языке Пролог-Д вычисление функции Хевисайда, определяемую формулой:
h(x)=0, если x<=0;
h(x)=1, если x>0.
База знаний должна содержать описание предиката «меньше и равно», который выше уже был описан; предикат, выполняющийся при вычислении функции Хевисайда, будет называться «хевисайд». Этот предикат будет иметь два аргумента: первый - аргумент функции, второй - ее значение. Предикат «хевисайд» определяется через два альтернативных описания для обоих значений х.
Перед этой базой знании можно поставить различные вопросы.Код:мир(X,Y)<-НЕ(БОЛ(X,Y);
хевисайд(X,0)<-мир(X,0);
хевисайд(X,1)<-БОЛ(X,0);
Ответ системы Пролог-Д: Х=1Код:?хевисайд(20,X);
В системе Пролог-Д MSX существует полный набор предикатов сравнения, их имена БОЛЬШЕ, МЕНЬШЕ, РАВНО.
Еще один, последний, встроенный предикат - «отсечение», предназначенный для управления логическим выводом. Этот предикат потребуется для решения следующих проблем:
- ограничения количества найденных решений;
- нахождения некоторого особенного решения задачи;
- ограничения объема поиска с целью повышения эффективности работы системы.
Предикат «отсечение» обозначается восклицательным знаком !. Это традиционное обозначение отсечения в системах логического программирования. Если данный предикат использовать в качестве цели в предложении, то полученный при этом эффект можно проиллюстрировать дверью, через которую можно пройти только слева направо, но нельзя вернуться назад через эту дверь. Роль двери выполняет символ !. Как известно, система Пролог-Д будет пытаться выполнять цели предложения в порядке просмотра слева направо начиная от символа <-, от первой до последней цели. Если какая-либо цель оказывается невыполненной, то осуществляется возврат и делается попытка найти альтернативные решения. Отсечение ограничивает возможность поиска альтернатив с того момента, как была просмотрена цель, обозначенная символом !. Например, если не выполнены цели А,Б,В, возврат для нахождения альтернативных решений в предложении
возможен, а если не выполнены цели Г, Д или Е, то уже нет. Рубикон при движении слева направо перейден.Код:пример<-А,Б,В,!,Г,Д,Е;
Необходимо отметить важность этого предиката, особенно при описании задач, допускающих множественные решения.
Иллюстрация предиката «отсечение» на примере базы знаний «мама». Действительно, у человека не может быть две матери, поэтому, определив для данного человека имя матери, необходимо прекратить дальнейшие поиски.
Перед базой знаний может быть поставлен вопросКод:мама(Наташа,Петя)<-!;
мама(Наташа,Ваня)<-!;
мама(Оля,Лена)<-!;
мама(Катя,Даша)<-!;
мама(Люда,Сережа)<-!;
мама(Лена,Костя)<-!;
Ответ системы Пролог-Д:Код:?мама(х,Петя);
После отыскания первого решения поиск альтернатив не производится. Что будет, если убрать во всех предложениях предикаты отсечения?Код:х=Наташа
ДРУГИХ РЕШЕНИЙ НЕТ
Упражнения.
- Опишите на языке Пролог-Д вычисление площадей геометрических фигур: трапеции, треугольника, параллелограмма.
- Опишите вычисление площади круга и длины окружности. Какова точность вычислений этих величин? Можно ли вычислить радиус круга по длине окружности?
- На языке Пролог-Д напишите базу знаний, в которой определяется функция, заданная соотношением:
F(x)=x², если x<1,
F(x)=x+1, если -1<=x<1,
F(x)=x², если x>1.
Какие сложности могут возникнуть в базе знаний о мамах, если у двух мам дети будут тезками?- Предположим, что дана программа на Прологе-Д:
Каким должен быть предикат рр(х), чтобы система нашла одно решение; бесконечно много решений?Код:ff(xx);
ff(x)<-pp(xx),ff(x);
Рекурсия
Существует огромное количество задач, в которых отношения между объектами можно определить, только используя сами определяемые соотношения. При этом получаются правила, называемые рекурсивными. Применение рекурсии для списания задач при работе с системами логического программирования - широко распространенный прием.
Рекурсия будет проиллюстрирована несколькими примерами построения программ, как вычислительных, так и логических.
Первым примером будет пример вычисления наибольшего общего делителя (НОД) двух чисел. Предикат, который выполняется, если найден НОД двух данных чисел, будет иметь имя «нод» и три аргумента: числа a, b и значение НОД - c. Для описания вычисления НОД используются следующие соображения:
если a=b, то c=a=b;
если a>b, то необходимо вычислить НОД для чисел b и a-b;
если b>а, то необходимо вычислить НОД для чисел a и b-a.
Эти три утверждения естественным образом могут быть записаны на Прологе-Д в системе БК-0010.
Если перед этой базой знаний поставить вопросКод:нод(a,a,a);
нод(a,b,c)<-БОЛ(a,b),вычитание(a,b,d),нод(b,d,c);
нод(a,b,c)<-БОЛ(b,a),вычитание(b,a,d),нод(a,d,c);
вычитание(X,Y,Z)<-ВЫЧ(1,Y,Z,X);
то система Пролог-Д ответит:Код:?нод(10,15,х);
Предикат «нод» оказывается обратимым.Код:x=5
ДРУГИХ РЕШЕНИЙ НЕТ
В системе Пролог-Д MSX последняя строка базы знаний запишется иначе:
а предикат БОЛ необходимо заменить на БОЛЬШЕ. Других изменений нет.Код:вычитание(X,Y,Z)<-СЛОЖЕНИЕ(Y,Z,X);
В качестве второго примера рассмотрим задачу о вычислении элементов последовательности 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ... известной как последовательность Фибоначчи. Каждый ее элемент определяется следующими правилами:
f(0)=0,
f(1)=1,
f(n)=f(n-1)+f(n-2)
Первая формула утверждает, что значение нулевого элемента последовательности равно нулю. Это можно записать в виде факта
Вторая утверждает, что первый элемент равен 1. На Прологе-Д это можно записать так:Код:Фб(0,0);
Третья формула представляет собой запись рекурсивного соотношения, переписываемого так:Код:Фб(1,1);
«вы» и «сл» - имена предикатов «вычитание» и «сложение», определенных с помощью правилКод:Фб(N,X)<-БОЛ(N,1),вы(N,1,M),вы(N,2,K),Фб(M,Y),Фб(K,Z),сл(Y,Z,X);
в системе БК-0010. Использование таких обозначений объясняется тем, что длина одной строки в редакторе системы Пролог-Д БК-0010 не должна превышать 64 символов.Код:сл(X,Y,Z)<-ВЫЧ(1,X,Y,Z);
вы(X,Y,Z)<-ВЫЧ(1,Y,Z,X);
Данные предложения представляют собой базу данных на языке Пролог-Д, позволяющую вычислять значения элементов последовательности. На вопрос
система Пролог-Д ответит:Код:?Фб(8,X);
Поиск числа Фибоначчи с порядковым номером более 8 невозможен в БК-0010 из-за ограниченной памяти, поэтому рекомендуется первым предложением базы знаний написатьКод:X=21
ДРУГИХ РЕШЕНИЙ НЕТ
Необходимо сказать, что такой путь решения данной задачи не самый лучший. Для нахождения N+1 числа Фибоначчи требуется 2(N+1)-1 рекурсивное обращение. Однако этого можно избежать, если перейти к другой базе знаний, в которой предикат с именем «Фиб» определен как имеющий три аргумента, включающий в себя в качестве аргумента значения N-го и N-1-го элементов последовательности. Запишем эту базу знаний.Код:Фб(N,Y)<-БОЛ(N,8),!;
- Нулевой элемент последовательности равен нулю, а «минус первый» не определен:
в данном случае значение X может быть любым.Код:Фиб(0,X,0);
- Первый элемент последовательности равен 1, а нулевой - 0:
Код:Фиб(1,0,1);
- Для остальных элементов:
Код:Фиб(N,F,f)<-БОЛ(N,1),вы(N,1,M),Фиб(M,Ф,F),сл(Ф,F,f);
Обращение к этой базе знаний будет иметь вид:
Ответ системы Пролог-Д:Код:?Фиб(10,F,f);
При работе с этой базой знаний для вычисления N-го числа Фибоначчи необходимо всегда лишь N рекурсивных обращений.Код:F=55,
f=34
ДРУГИХ РЕШЕНИЙ НЕТ
Для системы Пролог-Д характерна особенность, проявляющаяся при работе с рекурсивными программами. В общем случае порядок предложений в базе знаний не имеет значения. Однако в нижеследующем примере эго не так.
В первом предложении голова имеет то же имя, что и одна из целей - «родитель». В процессе поиска ответа в этой базе знаний будет применено правило «предложение, стоящее первым, будет и применено первым», известное как принцип поиска в глубину. Это приведет к тому, что система будет обращаться только к первому предложению базы знаний и ответ на вопросКод:родитель(X)<-родитель(Y),отец(Y,Z);
родитель(Коля);
отец(Коля,Петя);
родитель(Петя);
не будет найден никогда. Вместе с тем небольшое изменение базы знаний, перестановка двух предложений, приводит к удачному поиску решения:Код:?родитель(Петя);
Неограниченно-повторное обращение к предложению может быть и более замаскированным, как это получается в примере:Код:родитель(Коля);
родитель(X)<-родитель(Y),отец(Y,X);
отец(Коля,Петя);
?родитель(Петя);
Однако если третье предложение стоит на первом месте, то повторного обращения не произойдет и ответ будет найден. Такая ситуация называется петлей.Код:выше(A,B)<-ниже(B,A);
ниже(B,A)<-выше(A,B);
выше(Коля,Петя);
?ниже(Петя,Коля);
При вычислении элементов последовательности Фибоначчи может появляться бесконечная петля при исполнении программы. В самом деле, если вопрос имеет вид
то первый возможный результатКод:?Фиб(0,x,y);
x=0,
y=1
Далее в попытке отыскать следующее решение возникает бесконечная петля так как будет отыскиваться
Фиб(-1,x,y), Фиб(-2,…),…
Для контроля за подобной ситуацией необходима модификация базы знаний.
Первые два предложения должны быть записаны в виде
тогда при поиске альтернативного решения после получения ответа на вопрос:Код:Фиб(0,x,1)<-!;
Фиб(1,1,1)<-!;
будет получен результат: БОЛЬШЕ РЕШЕНИЙ НЕТ. Данный пример иллюстрирует первое возможное использование предиката «отсечение».Код:?Фиб(0,x,y);
х=0
у=1
Еще одно, чисто эстетическое предложение. База знаний на Прологе-Д будет выглядеть лучше, если предложения с одинаковыми именами расположены в одном месте. Для сравнения приводятся две базы знаний:
1.
2.Код:мама(Таня,Надя);
бабушка(X,Y)<~мама(X,Z),мама(Z,Y);
мама(Надя,Катя);
Упражнения.Код:мама(Таня,Надя);
мама(Надя,Катя);
бабушка(X,Y)<—мама(X,Z),мама(Z,Y);
- Написать базу знаний, описывающую вычисление факториала.
- Написать базу знаний, описывающую вычисление суммы чисел натурального ряда.
- Написать базу знаний, описывающую вычисление суммы квадратов чисел натурального ряда.
- Описать вычисление наименьшего общего кратного.
- Написать базу знаний, описывающую известную притчу «У попа была собака, он ее убил. Она съела кусок мяса, он ее убил, на могиле написал...» и т. д. Как сделать, чтобы эта база знаний не содержала петли?
- Написать базу знаний, описывающую сказку о репке, которую тянут-потянут, а вытянуть не могут.
[свернуть]
Извиняюсь, что заучил ;-) но так компактней и информативнее. Дублировать ссылку на zip тоже нет смысла.
Дописываю новую документацию, а пока для истории продолжаю выкладывать старые публикации:
"Информатика и образование" №5 1990 Программирование на Прологе-Д
Программа на Прологе представляет собой базу знаний и следующий за ней вопрос. Построению базы знаний посвящена данная статья. Здесь рассматриваются структура программы и некоторые приемы технологии программирования, связанные с использованием встроенных предикатов, рекурсии, графики, специфичные для Пролога-Д. Как и прежде во всех случаях, где это необходимо, будут оговариваться различия Пролога-Д MSX и Пролога-Д БК-0010.
...[свернуть]
"Информатика и образование" №6 1990
Скачать: Вложение 69223
Скрытый текст
С. Григорьев
Йошкар-Ола
Графические средства системы Пролог-Д
Практически все современные учебные системы программирования предполагают использование компьютерной графики, она является мощным дидактическим средством. В традиционной компьютерной графике построение изображения на экране интерпретируется серией команд. Таким образом, всякое изображение ассоциируется с алгоритмом его построения и служит для иллюстрации алгоритмического подхода к работе ЭВМ. Однако эта концепция не укладывается в принципы декларативного программирования, принятые в системах логического программирования, к которым относится Пролог-Д. Если последовать концепции логического программирования, то необходимым становится описание элементов рисунка в виде совокупности графических объектов, соотношений и связей между ними. В этом случае описание последовательности действий художника-исполнителя становится излишним (а может ли настоящий художник быть исполнителем?).
В системе Пролог-Д определен набор графических примитивов, отображающих графические объекты и построенных таким образом, что с точки зрения синтаксиса каждый из них может быть только целью и принимает значение «истина» (выполняется), если на экране появляется графическое изображение объекта. При записи в правиле нескольких графических примитивов и выполнении данного правила на экране появляется объединение графических образов в той последовательности, как они описаны в данном правиле.
В системе Пролог-Д БК-0010 предусмотрен один встроенный графический предикат ОТР(x,y,z,t,c). Он выполняется, если на экране генерируется отрезок цвета c, соединяющий точки (x,y) и (z,t). Аргументы x,y,z,t должны быть целыми или переменными, связанными с целыми, причем x, z должны быть в пределах от 0 до 256, а y,t - в пределах от 0 до 512.
В качестве примера приведем описание угла, вершина которого находится в точке (x, y).
Сначала будет нарисован отрезок, соединяющий точки (100,100) и (10,10), а затем отрезок, соединяющий точки (100,100) и (50,50). Если бы пятым аргументом предикатов ОТР было число, равное нулю, то точки отрезков были бы невидимы.Код:угол(x,y)<-ОТР(x,y,10,10,1),ОТР(x,y,50,50,1);
?угол(100,100);
Не обязательно, чтобы описание всей картинки было записано в одном предложении. Часть описания может быть выделена в виде отдельного предложения. Программу предыдущего примера можно модифицировать:
Новая программа выполняет те же самые функции.Код:угол(x,y)<-ОТР(x,y,10,10,1),продолжение(x,y);
продолжение(x,y)<-ОТР(x,y,50,50,1);
?угол(100,100);
Система Пролог-Д допускает возможность использования переменных в графических примитивах. В качестве примера приведем описание вектора, выходящего из токи A с координатами (x,y) в точку B с координатами (s,t):
Необходимо отметить особенность графических объектов, описываемых с помощью переменных. В процессе работы системы может оказаться, что какая-то переменная в описании графического примитива не определена. В этом случае графический примитив все равно будет выполнен, однако переменная принимает все допустимые для нее значения. Иными словами, на экране появится геометрическое место точек, задаваемое уравнением графического объекта. В качестве примера приведем вопросКод:вектор(A(x,y),B(s,t))<-ОТР(x,y,s,t,1);
В результате ответа на этот вопрос на экране появится треугольник белого цвета. Причина этого в том, что величина абсциссы второй точки не определена, в этом случае абсцисса должна быть любым числом, в допустимых пределах. Как правило, область допустимых значений ограничена размерами экрана.Код:?ОТР(0,0,x,100,1);
Языковые средства Пролога-Д обеспечивают возможность наращивать определения, естественным путем поддерживают структурность описания объекта. В качестве примера приведем описание построения домика. Домик можно определить как треугольник и квадрат, совмещенные одной стороной. Квадрат можно определить посредством четырех отрезков:
В этом выражении нет нарушения синтаксиса, однако длина этого предложения больше, чем допустимые 64 символа, и чтобы оно было выполнено в рамках системы Пролог-Д БК-0010, необходимо разделить выражение, например, на две части:Код:квадр(x,y,z,t)<-ОТР(x,y,x,t,1),ОТР(x,y,z,y,1),ОТР(x,t,z,t,1),ОТР(z,y,z,t,1);
Аналогично определяется треугольник:Код:квадр(x,y,z,t)<-ОТР(x,y,x,t,1),ОТР(x,y,z,y,1),ч2(x,y,z,t);
ч2(x,y,z,t)<-ОТР(x,t,z,t,1),ОТР(z,y,z,t,1);
Предикат с именем ДЕ - предикат деления первого аргумента на второй, частное в третьем, а предикат с именем СЛ - сложение первого аргумента со вторым, результат в третьем аргументе. К сожалению, и это определение не входит в прокрустово ложе 64 символов. Вот окончательный вариант разделения:Код:треуг(x,y,z,t)<-ОТР(x,y,t,y,1),СЛ(x,t,r),ДЕ(r,2,f),ОТР(x,у,f,z,1),ОТР(f,z,t,y,l);
Определение дома длиной 20 единиц, высотой этажа 10 единиц и высотой крыши 20 единиц имеет видКод:треуг(x,y,z,t)<-ОТР(x,y,t,y,1),ДЕ2(x,t,f),угол(x,y,z,t,f);
угол(x,y,z,t,f)<-ОТР(x,y,f,z,1),ОТР(f,z,t,y,1);
ДЕ2(x,t,f)<-СЛ(x,t,r),ДЕ(r,2,f);
Вновь необходимо разделить это описание на две части: в одной части определяется крыша, а в другой этаж (это тот случай, когда дом приходится начинать строить с крыши).Код:дом(x,y)<-крыша(x,y,r,f),этаж(x,y,f);
этаж(x,y,f)<-СЛ(y,20,z),квадр(x,y,f,z);
крыша(x,y,r,f)<-СЛ(r,10,y),СЛ(x,20,f),треуг(x,y,r,f);
Использование рекурсивных определений дает возможность записать базу знаний более лаконично. Рекурсия может быть использована и для создания динамически изменяющегося графического объекта. Для этого на одном и том же месте последовательно фиксируется образ объекта так, что цвет его элементов попеременно меняется от цвета фона до цвета, определяемого в базе знаний.
Пример - описание летящей птицы, машущей крыльями. В предикате взмах описан взмах вниз и затем взмах вверх. Первому положению соответствует горизонтальное положение отрезка белого цвета, затем этот отрезок гасится, становится цветом фона. Положению «вверх» соответствует угол, состоящий из двух отрезков белого цвета, которые затем гасятся. Каждое из понятий «вверх» и «вниз» описывается отдельно, при этом производятся арифметические операции, необходимые для вычисления координат начала и конца отрезков. Периодическое повторение взмаха вверх и вниз осуществляется с помощью рекурсивного обращения к одному и тому же предикату птица. (Внимание! В некоторых вариантах транслятора не предусмотрена обработка возникающей в данном примере эффекта концевой рекурсии типа петли Следствием этого может быть аварийный останов после нескольких десятков взмахов). Полное описание птицы, машущей крыльями, приведено ниже.
Декларативность языка позволяет создавать достаточно сложные картины, используя известные принципы декомпозиции графического объекта на части и последующее их описание.Код:птица(x,y)<-взмах(x,y),птица(x,y);
взмах(x,y)<-вниз(x,y,1),вниз(x,y,0),вверх(x,y,1),вверх(x,y,0);
вниз(x,y,c)<-сдв(x,y,z,t,u,v),ОТР(z,y,u,y,1);
вверх(x,y)<-сдв(x,y,z,t,u,v),ОТР(x,y,z,t,1),ОТР(x,y,u,v,1);
сдв(x,t,z,t,u,v)<-сдп(x,y,z,t),сдл(x,y,u,v);
сдп(x,y,z,t)<-СЛ(x,5,z),СЛ(t,5,y);
сдл(x,y,z,t)<-СЛ(z,5,x),СЛ(t,5,y);
Например, картина, содержащая дом и летящую птицу, есть пример и описания сложного синтетического объекта, и использования рекурсии для определения динамического изменения объекта.
В ответ на вопрос:Код:СЛ(a,b,c)<-ВЫЧ(1,a,b,c);
дом(x,y)<-крыша(x,y,r,f),этаж(x,y,f);
этаж(x,y,f)<-СЛ(y,20,z),квадр(x,y,f,z);
крыша(x,y,r,f)<-СЛ(r,10,y),СЛ(x,20,f),треуг(x,y,r,f);
треуг(x,y,z,t)<-ОТР(x,y,t,y,1),ДЕ2(x,t,f),угол(x,y,z,t,f);
угол(x,y,z,t,f)<-ОТР(x,y,f,z,1),ОТР(f,z,t,y,1);
ДЕ2(x,t,f)<-СЛ(x,t,r),ДЕ(r,2,f);
квадр(x,y,z,t)<-ОТР(x,y,x,t,1),ОТР(x,y,z,y,1),ч2(x,y,z,t);
ч2(x,y,z,t)<-ОТР(x,t,z,t,1),ОТР(z,y,z,t,1);
птица(x,y)<-взмах(x,y),птица(x,y);
взмах(x,y)<-вниз(x,y,1),вниз(x,y,0),вверх(x,y,1),вверх(x,y,0);
вниз(x,y,c)<-сдв(x,y,z,t,u,v),ОТР(z,y,u,y,1);
вверх(x,y)<-сдв(x,y,z,t,u,v),ОТР(x,y,z,t,1),ОТР(x,y,u,v,1);
сдв(x,t,z,t,u,v)<-сдп(x,y,z,t),сдл(x,y,u,v);
сдп(x,y,z,t)<-СЛ(x,5,z),СЛ(t,5,y);
сдл(x,y,z,t)<-СЛ(z,5,x),СЛ(t,5,y);
на экране будет построен дом и нарисована птица, машущая крыльями. Обратите внимание на одно обстоятельство: предикат птица должен быть описан после предиката дом, так как в нем содержится концевая рекурсия типа петли.Код:?дом(70,110),птица(120,50);
В более мощной системе Пролог-Д MSX число встроенных графических предикатов больше. Полный их перечень приведен в таблице. Все аргументы - целые или переменные, конкретизированные целыми.
Функция ДействиеФОН(T,F) Установка цвета текста и фона. Переменная конкретизируется целым, соответствующим установленному цвету ТОЧКА(X,Y,C) Генерация точки на экране с координатами X, Y и цветом C ЛИНИЯ(X,Y,U,V,C) Генерация линии из точки с координатами X, Y в точку с координатами U, V и цветом C ОКРУЖНОСТЬ(X,Y,R,C) Генерация окружности радиусом R с центром в X, Y
В качестве примера приведем описание двух синих окружностей с центром в точке с координатами 100 и 100, радиусами 10 и 50:
Сначала будет нарисована окружность с радиусом 10, а затем окружность с радиусом 50.Код:синие-окружности<-ОКРУЖНОСТЬ(100,100,10,5),ОКРУЖНОСТЬ(100,100,50,5);
?синие-окружности;
Не обязательно, чтобы описание всей картинки было записано в одном предложении. Часть описания может быть выделена в виде отдельного предложения. Программу предыдущего примера можно модифицировать:
Новая программа выполняет те же функции. Использование переменных в графических примитивах аналогично использованию в системе Пролог-Д БК-0010.Код:синие-окружности<-ОКРУЖНОСТЬ(100,100,10,5),продолжение;
продолжение<-ОКРУЖНОСТЬ(100,100,50,5);
?синие—окружности;
Обратившись к опыту художников-примитивистов, нарисуем дерево в виде ствола - отрезка линии и кроны - окружности.
Если к этому определению в базе знаний задать вопросКод:дерево(x,y,h,r)<-СЛОЖЕНИЕ(z,h,y),ЛИНИЯ(x,y,z,z,14),СЛОЖЕНИЕ(z,r,t),ОКРУЖНОСТЬ(x,t,г,3);
то на экране появится одинокое дерево с координатами комеля 50, 50, высотой 40 и радиусом кроны 10.Код:?дерево(50,50,40,10);
Языковые средства Пролога-Д обеспечивают возможность наращивания определения, естественным путем поддерживают структурность описания объекта. Использование рекурсивных определений дает возможность записать базу знаний более лаконично.
Построим поляну с деревьями.
Если к этой базе знаний задать вопрос:Код:сад(1,x,y,h,r)<-дерево(x,y,h,r);
сад(m,x,y,h,r)<-смещение(x,y,z,t),дерево(z,t,h,r),СЛОЖЕНИЕ(n,1,m),сад(n,z,t,h,r);
смещение(x,y,z,t)<-СЛОЖЕНИЕ(х,10,z),СЛОЖЕНИЕ(у,10,t);
поляна<-ОКРУЖНОСТЬ(v,180,50,2),сад(6,100,150,50,10),сад(5,85,172,50,10);
то на экране появится искомое изображение.Код:?поляна;
Поляна изображена с помощью примитива ОКРУЖНОСТЬ, в описании которого не определена одна из координат центра. Это значит, что на экране должны быть нарисованы все возможные окружности, центры которых лежат на горизонтальной прямой, а радиус равен 50. В этом примере использована рекурсия для определения объекта «сад». В нашем понимании сад - несколько деревьев, расположенных на некотором расстоянии друг от друга. Чтобы нарисовать сад, необходимо воспользоваться рекурсивным определением. Оно содержит начальную, или базовую, ситуацию и описание некоторого рекурсивного соотношения. В примере:
базовой ситуацией будет та, когда в саду одно дерево;
рекурсивное определение получится тогда, когда будет несколько деревьев, смещенных относительно друг друга (смещение задано в виде специальной функции, именно она и определяет взаимное расположение деревьев).
Упражнения.
- Напишите на языке Пролог-Д базу знаний, описывающую прямоугольный треугольник.
- Используя рекурсивное определение, напишите базу знаний, описывающую многоэтажный дом.
- Опишите на языке Пролог-Д построение улицы без учета и с учетом перспективы.
[свернуть]