Основы языка Visual Prolog
1.1 ПРОграммирование в ЛОГике
В Прологе решение задачи получается логическим выводом из ранее известных положений. Обычно программа на Прологе не является последовательностью действий, – она представляет собой набор фактов с правилами, обеспечивающими получение заключений на основе этих фактов. Поэтому Пролог известен как декларативный язык.
Пролог базируется на предложениях Хорна, являющихся подмножеством формальной системы, называемой логикой предикатов. Логика предикатов – это простейший способ объяснить, как «работает» мышление, и она проще, чем арифметика, которой вы давно пользуетесь. Пролог использует упрощенную версию синтаксиса логики предикатов.
Пролог включает механизм вывода, который основан на сопоставлении образцов. С помощью подбора ответов на запросы он извлекает хранящуюся (известную) информацию. Пролог пытается проверить истинность гипотезы (другими словами – ответить на вопрос), запрашивая для этого информацию, о которой уже известно, что она истинна. Прологовское знание о мире – это ограниченный набор фактов (и правил), заданных в программе.
Одна из важнейших особенностей Пролога – это то, что в дополнение к логическому поиску ответов на поставленные вопросы, он может иметь дело с альтернативами и находить все возможные решения. Вместо обычной работы от начала программы до ее конца Пролог может возвращаться назад и просматривать более одного «пути» при решении всех составляющих задачу частей.
Логика предикатов была разработана для наиболее простого преобразования принципов логического мышления в записываемую форму. Пролог использует преимущества синтаксиса логики для разработки программного языка. В логике предикатов нужно исключить из предложения все несущественные слова. Затем следует преобразовать эти предложения, ставя в них на первое место отношение, а после него – сгруппированные объекты. В дальнейшем объекты становятся аргументами, между которыми устанавливается это отношение.
Например:
Предложения на естественном языке
Синтаксис логики предикатов
Машина красивая
fun(car)
Розакрасная
red(rose)
Биллу нравится машина, если машина красивая
likes(Bill, car) if fun(car)
Факты и правила
При составлении программы на языке Пролог необходимо описать объекты (objects) и отношения (relations), а затем – правила (rules), при которых эти отношения являются истинными.
Например:
Bill likes dogs.
это предложение устанавливает отношение между объектами Bill и dogs; этим отношением является likes. Правило, определяющее, когда предложение является истинным, может выглядеть так:
Bill likes dogs if the dogs are nice.
Факты.
Отношение между объектами называется фактом (fact). Факты – это отношения или свойства, о которых известно, что они имеют значение «истина». Отношение состоит из имени отношения и объекта или объектов, заключенных в круглые скобки. Как и предложение, факт заканчивается точкой.
likes(bill, dogs).
Факты помимо отношений могут выражать и свойства:
boy(bill).
gray(dogs).
Правила.
Правила позволяют вывести один факт из других фактов. Правило – это заключение, для которого известно, что оно истинно, если одно или несколько других найденных заключений или фактов являются истинными. Правила – это связанные отношения. Они позволяют Прологу логически выводить одну порцию информации из другой. Правило принимает значение «истина», если доказано, что заданный набор условий является истинным.
Например:
Cindy likes everything that Bill likes.
По этому правилу получается, что
Cindy likes dogs.
На Прологе синтаксис у правил будет другим:
likes(cindy, Something) :- likes(bill, Something).
Символ :- имеет смысл «если», и служит для разделения двух частей правила: заголовка и тела. Заголовок – это факт, который был бы истинным, если бы были бы истинными несколько условий. Это называется выводом или зависимым отношением. Тело – это ряд условий, которые должны быть истинными, чтобы Пролог мог доказать, что заголовок правила истинен.
Правило может рассматриваться как процедура. В нашем случае это выглядит так: «Чтобы доказать, что Синди любит что-то, докажите, что Билл любит это». С такой процедурной точки зрения правила могут предписывать выполнение каких-либо действий, отличных от доказательств фактов, – напечатать что-нибудь или создать файл.
Запросы (цели).
Однократно задав несколько фактов, мы можем задавать вопросы, касающиеся отношений между ними. Это называется запросом (query) системы языка Пролог. Пролог всегда ищет ответ на запрос, начиная с первого факта, и перебирает все факты, пока они не закончатся.
Например:
likes(bill, dogs).
likes(cindy,What).
Во втором случае второй объект – What – начинается с большой буквы, тогда как первый объект – cindy – со строчной. Это происходит потому, что cindy – фиксированный, постоянный объект, известная величина, а What – переменная.
Получив запрос о том, что любит Синди, Пролог ответит:
What = dogs
1 Solutions.
Запросы (цели) могут быть простыми или сложными. Сложными называются цели, состоящие из двух или более частей. А каждая часть сложной цели – подцелью. Возможно использование конъюнктивной и дизъюнктивной формы объединения подцелей. В качестве разделителей используются знаки , и ; соответственно.
Составные цели можно использовать для поиска решения, в котором:
ü обе подцели A и B истинны (конъюнкция), разделяя подцели запятой:
ü истинна либо подцель A, либо подцель B (дизъюнкция), разделяя подцели точкой с запятой.
Переменные.
Переменные в Прологе всегда начинаются с заглавной буквы или символа подчеркивания.
Пролог не имеет оператора присваивания. Переменные в прологе инициализируются при сопоставлении с константами в фактах или правилах. До инициализации переменная свободна, после присвоения ей значения она становится связанной. Переменная остается связанной только то время, которое необходимо для получения решения по запросу, затем Пролог освобождает ее и ищет другое решение.
Нельзя сохранить информацию, присвоив значение переменной. Переменные используются как часть процесса поиска решения, а не как хранилище информации.
clauses
likes(ellen,reading).
likes(john,computers).
likes(john,badminton).
likes(leonard,badminton).
likes(eric,swimming).
likes(eric,reading).
goal
likes(Person,reading), likes(Person,swimming).
На этом примере удобно наблюдать как среди фактов выделяется тот, у которого второй аргумент – reading, а переменная Person первоначально связывается со значением ellen и по списку фактов ищет факт, соответствующий второй части запроса: likes(ellen,swimming). Поскольку такого факта нет, то Пролог среди фактов выделяет следующий факт у которого второй аргумент – reading, то есть likes(eric,reading) и переменная Person связывается со значением eric. Далее по списку фактов ищет факт, соответствующий второй части запроса: likes(eric,swimming). И, поскольку данный факт имеет место быть, то Пролог выдает ответ:
Person= eric
1 Solutions.
Анонимныепеременные.
Переменные данного вида используются в том случае, когда необходимо использовать по запросу не полную, а определенную информацию из запроса, проигнорировав ненужные значения. Обозначаются данные переменные символом подчеркивания.
clauses
male(bill).
male(joe).
female(sue).
female(tammy).
parent(bill,joe).
parent(sue,joe).
parent(joe,tammy).
goal
parent(Parent,_).
На такой запрос Пролог ответит:
Parent= bill
Parent= sue
Parent= joe
3 Solutions.
Анонимные переменные могут использоваться и в фактах Пролога. Например, факты:
owns(_,mouth).
drink(_).
Могут быть выражены средствами естественного языка: У каждого есть рот. Все пьют.
Анонимные переменные сопоставляются с любыми данными.
Комментарии.
Многострочные комментарии должны начинаться с символов /* и заканчиваться символами */. Однострочные комментарии можно начинать с символ %. В Visual Prolog можно использовать комментарии после каждого субдомена при объявлении домена:
domains
articles = book( string Title, string Author)
ивобъявлениипредикатов:
predicates
likes(string Uppercase, string Lowercase)
Программы Visual Prolog
Visual Prolog – компилятор, контролирующий типы: для каждого предиката объявляются типы объектов, которые он может использовать. Это объявление типов позволяет программам быть скомпилированными непосредственно в машинные коды.
Основные разделы программ.
– раздел domains (доменов);
– раздел predicates (предикатов);
– раздел clauses (предложений);
– раздел goal (целей).
Раздел предложений. Все предложения для каждого предиката в данном разделе должны располагаться вместе. Последовательность предложений, описывающих один предикат, называется процедурой.
Раздел предикатов. Здесь перечисляются все предикаты, отличные от стандартных (встроенных в VP) и используемые в программе. Предикаты должны быть перечислены с указанием типов (доменов) их аргументов.
Объявление предиката содержит:
1) имя предиката – последовательность латинских букв, цифр и символа подчеркивания, начинающаяся с прописной буквы. Длина имени не может быть больше 250 символов. В именах запрещено использовать такие символы, как пробел, -, * и т.п.;
2) списка доменов (типов) аргументов предиката, заключенного в круглые скобки.
В отличие от предложений раздела clauses описание предиката не заканчивается точкой. Доменами (типами) аргументов могут быть либо стандартные домены, либо домены, объявленные в разделе domains.
Например,
likes(chelovek, dejstvie)
color(symbol)
my_predicate(integer, symbol)
Арность предиката – это количество аргументов, которые он принимает. В программе можно использовать два предиката с одним и тем же именем, но отличающиеся арностью.
Раздел доменов. Если предикат my_predikate (symbol, integer) объявлен в разделе predicates следующим образом:
predicates
my_predikate (symbol, integer)
то нет никакой необходимости объявления доменов его аргументов в разделе доменов, так как symbol и integer – стандартные домены. Но если возникнет необходимость объявления в виде:
predicates
my_predikate (name, number),
то выше надо описать в разделе доменов
domains
name = symbol
number = integer
Домены позволяют задавать разные имена различным видам данных.
Например, предложение «Иван – мужчина, которому 45 лет» можно объявить следующим предикатом: person(symbol, symbol, integer) без объявления доменов в их разделе.
Однако такое объявление недостаточно понятно. Если использовать домены, то предикат станет гораздо более «говорящим»:
domains
imya, pol = symbol
vozrast = integer
predicates
person(imya, pol, vozrast)
Одно из преимуществ объявления собственных доменов – это то, что компилятор может отслеживать ошибки типов:
rovesnik(X, Y) :- person(X, Pol, Let), person(Pol, Y, Let)
Вывод:
если переменная в предложении используется более чем в одном предикате, она должна быть одинаково объявлена в каждом их них.
Стандартные домены
Домен
Описание
Значение
short
короткое, знаковое, количественное
-32 768 .. 32 767
ushort
короткое, беззнаковое, количественное
0 .. 65 535
long
длинное, знаковое, количественное
-2 млрд. .. 2 млрд.
ulong
длинное, беззнаковое, количественное
0 .. 4 млрд.
integer
знаковое, количественное
или -32 768 .. 32 767
или -2 млрд. .. 2 млрд.
unsigned
беззнаковое, количественное
или 0 .. 65 535
или 0 .. 4 млрд.
byte
0 .. 255
word
0 .. 65 535
dword
0 .. 4 млрд.
char
символ, заключенный в апострофы
real
число с плавающей десятичной точкой (эквивалентен типу double в C) в интервале:
10-307 .. 10308
string
1) последовательность символов, заключенных в кавычки
2) последовательность букв, цифр и символов подчеркивания, начинающаяся со строчной буквы
symbol
то же, что и string
Раздел целей
Раздел целей аналогичен телу правила: это просто список подцелей.
Цель отличается от правила следующими признаками:
1) за ключевым словом GOAL не следует знак :-
2) при запуске программы VP автоматически выполняет цель.