Программирование на языке пролог
Шрифт:
человек(сократ).
человек(аристотель).
афинянин(сократ).
Можно было бы сделать несколько вопросов:
?- афинянин(сократ).
да
?- афинянин(аристотель).
нет
?- грек(сократ).
нет
Хотя тот факт, что Аристотель жил когда-то в Афинах, может быть исторически верным, мы просто не можем доказатьего на основе фактов, представленных в базе данных. Более того, хотя в базе данных содержится факт о том, что Сократ жил в Афинах, это не доказываеттого, что он был греком, если только в базе данных нет дополнительной информации. Таким образом, когда Пролог на вопрос отвечает нет, это значит не доказуемо, не согласуется с базой данных.
В приведенном ранее примере
Обсуждавшиеся до сих пор факты и вопросы не представляют большого интереса. Все что мы можем сделать – это получить обратно ту же самую информацию, которую мы ввели в систему. Более полезны были бы вопросы вида: «Какие объекты нравятся Мэри?».Именно для реализации такой возможности предназначены переменные.
1.3. Переменные
Если вы хотите узнать, что нравится Джону, то было бы утомительно спрашивать «Нравятся ли Джону книги?», «Нравится ли Джону Мэри?»и так далее, получая каждый раз ответ даили нет. Более разумно обратиться к Пролог-системе с просьбой назвать что-нибудь, что нравится Джону. Такой вопрос можно сформулировать следующим образом« «Нравится ли Джону X?».Задавая вопрос, мы не знаем, для обозначения какого объекта использована литера X. Нам хотелось бы, чтобы Пролог перечислил все имеющиеся возможности для обозначения какого объекта использована литера X. В Прологе можно не только присваивать имена конкретным объектам, но и использовать имена, подобные X, для обозначения объектов, которые должны быть определены Пролог-системой. Имена такого типа называются переменными.Переменная в Прологе может иметь либо не иметь конкретное значение. Переменная конкретизирована, если имеется объект, который обозначает эта переменная. Переменная не конкретизирована, если еще не известно, что именно она обозначает. В Прологе используется соглашение, позволяющее отличать переменные от имен конкретных объектов – каждое имя, начинающееся с прописной буквы, рассматривается как переменная.
При поиске ответа на вопрос Пролог организует просмотр всех фактов в базе данных, чтобы обнаружить объект, который эта переменная могла бы обозначать. Так, когда мы спрашиваем «Нравится ли Джону X?»,Пролог просматривает все известные ему факты для обнаружения тех вещей, которые нравятся Джону.
Такая переменная, как X, сама по себе не является именем какого-то конкретного объекта, но она может быть использована для обозначения объектов, которым мы не можем дать имя. Например, мы не можем чему-то, что нравится Джону,дать имя как объекту, поэтому для выражения подобных вопросов вместо вопросов вида
?- нравится(джон, Что-то, что любит Джон).
Пролог позволяет использовать переменные и задавать вопросы в виде
?- нравится(джон,Х).
При желании можно давать переменным более длинные имена. Следующий вопрос вполне приемлем в Прологе:
?- нравится(джон, Что-точтонравитсяджону).
Почему? Потому что переменной может быть любое имя, начинающееся с прописной буквы. Рассмотрим следующую базу данных и запрос к Прологу:
нравится (джон,цветы).
нравится (джон,мэри).
нравится(поль,мэри).
?- нравится(джон,Х).
В вопросе спрашивается: Существует ли что-нибудь, что нравится Джону?В ответ Пролог напечатает:
Х=цветы
а затем будет ждать дальнейших приказов; это мы вкратце обсудим далее. Как это произойдет? При поступлении такого вопроса в Пролог-систему переменная, входящая в вопрос, изначально является неконкретизированной. Пролог просматривает базу данных в поисках факта, сопоставимогос вопросом. Если неконкретизированная переменная появляется в качестве аргумента, то Пролог считает, что такой аргумент сопоставим с любымдругим аргументом, находящимся в той же самой позиции факта. В нашем примере Пролог ищет любой факт с предикатом нравитсяи первым аргументом джон. Второйаргумент в этом случае может быть каким угодно, так как в вопросе вторым аргументом является неконкретизированная переменная. При обнаружении такого факта переменная Xстановится
конкретизированной, обозначая объект, являющийся вторым аргументом найденного факта, каким бы этот аргумент ни был. Пролог просматривает факты базы данных в том порядке, в каком они вводились (на печатной странице это соответствует просмотру сверху вниз), поэтому факт нравится(джон, цветы)найден первым. С этого момента переменная Xобозначает объект цветыили, говоря другими словами, переменная Xконкретизируется значением цветы. Пролог с помощью специального маркераотмечает место в базе данных, в котором произошло сопоставление. Обсудим кратко причины, по которым оказалось необходимым использование такого маркера.Обнаружив факт, соответствующий вопросу, Пролог печатает имена объектов, которые теперь обозначают переменные. В нашем примере есть только одна переменная X, которой соответствует объект цветы. Затем Пролог ждет дальнейших указаний, как об этом говорилось выше. Если в этой ситуации нажать на терминале клавишу
Предположим, что в ответ на первое найденное Прологом соответствие ( Х=цветы) мы предлагаем системе продолжить поиск (введя
Что произойдет, если, имея те же факты, что и ранее, мы зададим вопрос:
?- нравится(Х,мэри).
В этом вопросе спрашивается: «Существует ли объект, которому нравится Мэри?».Теперь вы сами можете понять, что в примере объектами, которые нравятся Мэри, являются джони поль. Опять, если бы мы хотели увидеть все варианты, мы должны были бы вводить; после каждого ответа, выдаваемого Прологом:
?- нравится(Х, мэри). наш вопрос
Х=джон; первый ответ. Мы вводим
Х=поль; второй ответ. Вновь вводим
нет больше ответов нет.
1.4. Конъюнкции
Предположим, что мы хотим получать ответы на вопросы о более сложных отношениях, таких как: «Нравятся ли Джон и Мэри друг другу?».Один из способов сделать это – узнать сначала, нравится ли Джону Мэри, и если Пролог ответит да, то спросить, нравится ли Мэри Джон. Таким образом, эта задача состоит из двух «целевых утверждений» (или целей), которые Пролог должен согласовать. Ввиду того что подобная комбинация часто используется при программировании на Прологе, для нее имеется специальное обозначение. Предположим, мы имеем следующую базу данных:
нравится(мэри,пища).
нравится(мэри,вино).
нравится(джон,вино).
нравится(джон,мэри).
Мы хотим узнать, нравятся ли Джон и Мэри друг другу. Для этого мы спрашиваем: «Нравится ли Джон Мэрии нравится ли Мэри Джон?».Связка ивыражает тот факт, что нас интересует конъюнкция двух указанных целей – мы хотим последовательно согласовать с базой данных обе цели. Мы выражаем это в вопросе, записывая обе цели через запятую: