Скачиваний:
41
Добавлен:
22.05.2015
Размер:
144.38 Кб
Скачать

Точки на плоскости

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

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

Опишем точки в виде предикатов point/2 от двух аргументов – координат. Для этого в разделе class facts объявим недетерминированный предикат:

class facts

point : (integer X, integer Y).

Здесь следует иметь в виду, что X, Y – это не имена переменных, которыми мы будем в программе обозначать координаты точек, а необязательные комментарии к аргументам с доменами integer. Имена же переменных могут быть любыми, в том числе и X,Y.

Множество точек зададим в разделе clauses. Пусть это множество содержит девять точек:

clauses

point(1,1). point(1,2). point(1,4).

point(2,1). point(2,2). point(2,4).

point(3,2). point(4,1). point(4,3).

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

Итак, исходный код в файле main.pro после указанных модификаций должен быть таким:

implement main

open core, console

constants

className = "com/visual-prolog/main".

classVersion = "$JustDate: $$Revision: $".

c

Объявление предиката

lass facts

point :(integer X, integer Y).

clauses

classInfo(className, classVersion).

p

Задание точек

oint(1,1). point(1,2). point(1,4).

point(2,1). point(2,2). point(2,4).

point(3,2). point(4,1). point(4,3).

run():-

Тело цели – предиката run()

init(),

succeed().

end implement main

goal

mainExe::run(main::run).

Листинг 2.Описание точек на плоскости

Пример 4. Осуществим поиск точки с координатами, например, X=1 и Y=2. Для этого вставим вызов предиката point(1,2) в тело предиката run() и выведем сообщение о найденной точке. Для случая отсутствия искомой точки не забудем предусмотреть второе предложение с выводом соответствующего сообщения:

run():-

init(),

point(1,2), !,

write("Точка с указанными координатами найдена"), 

_=readchar();

write("Точка с указанными координатами НЕ найдена"),

_=readchar().

При запуске программы Пролог начнёт выполнять цель – предикат run(). Так как этот предикат имеет две альтернативные ветви (два предложения), то машина логического вывода войдёт в первую ветвь (первое предложение), запомнив в стеке адрес входа во вторую ветвь (второе предложение), с которого она продолжит поиск решения в случае отката в первой ветви.

В первом предложении машина логического вывода Пролога сама будет просматривать предикаты point/2 до тех пор, пока не встретит предикат с искомыми аргументами X=1 и Y=2. В этом случае она также запомнит в стеке адрес возврата, с которого она впоследствии сможет продолжить поиск новых решений при откате назад. После этого выведет сообщение о найденном решении и, встретив знак отсечения, удалит все адреса возврата из стека, которые были туда помещены в ходе выполнения предиката run(), а их было всего два.

Если же точка с указанными координатами не будет найдена, то предикат point/2 завершится неудачей, что вызовет откат из первой ветви во вторую – благо адрес возврата в вершине стека как раз указывает на начало второй ветви. Вторая ветвь выведет на экран сообщение о том, что точка не найдена.

Пример 5. Осуществим поиск точки с координатами, вводимыми с клавиатуры. Для этого используем такую цель:

run():-

init(),

write("X = "),X=read(),

write("Y = "),Y=read(),

clearInput(),

point(X,Y), !,

write("Точка с указанными координатами найдена"), 

_=readchar();

write("Точка с указанными координатами НЕ найдена"),

_=readchar().

Пример 6. Осуществим поиск точки с заданной координатой X, и в случае успешного нахождения определим координату Y:

run():-

init(),

write("X = "),X=read(),

clearInput(),

point(X,Y), !,

writef("Найдена точка с координатами %,%",X,Y), 

_=readchar();

write("Точка НЕ найдена"),

_=readchar().

Обратите внимание, что в программе есть несколько точек с координатой, например, X=1. Как найти все эти точки? В Прологе это делается очень просто. В предложении, где осуществляется поиск надо убрать отсечение и принудительно вызвать откат назад с помощью предиката fail().

Пример 7. Осуществим поиск всех точек с заданной координатой X, и в случае успешного нахождения определим координату Y каждой из них:

run():-

init(),

write("X = "),X=read(),

clearInput(),

point(X,Y),

writef("Найдена точка с координатами %,% \n",X,Y),

fail();

write("Всё!!!"),

_=readchar().

Предикат writef осуществляет вывод форматированной строки. Вместо знаков процента он последовательно подставляет значения переменных, указанных через запятую правее форматированной строки. Знак \n является символом перевода на новую строку. Если этот знак не указывать, то весь вывод будет осуществляться в одну строку.

Пример 8. Осуществим поиск всех точек, находящихся выше горизонтальной прямой Y=2:

run():-

init(),

point(X,Y), Y>2,

writef("Найдена точка с координатами %,% \n",X,Y),

fail();

write("Всё!!!"),

_=readchar().

Пример 9. Осуществим поиск всех точек, находящихся на прямой y=x:

run():-

init(),

point(X,X),

writef("Найдена точка с координатами %,% \n",X, X),

fail();

write("Всё!!!"),

_=readchar().

Обратите внимание, что в этом примере вместо цели point(X,Y), X=Y мы использовали цель с внутренней унификацией аргументов point(X,X), которая сама выполнит проверку равенства: X=Y.

Задание 3. Вывести на экран координаты X,Y всех точек.

Задание 4. Вывести все точки, сумма координаты X и координаты Y которых равна 5.

Задание 5. Вывести все точки, лежащие внутри прямоугольника, ограниченного координатами 1<=X<3, 2<Y<=4.

Задание 6. Вывести все точки, имеющие чётную координату X и нечётную координату Y. Подсказка: операция определения остатка целочисленного деления чётного числа на 2 возвращает 0, а нечётного – возвращает 1. Эта операция обозначается mod.

Задание 7. Вывести все точки, находящиеся ниже линии y = 0.6x + 0.4.

Задание 8. Вывести все точки, находящиеся выше линии y = kx + b. Значения k и b вводить с клавиатуры.

Задание 9. Вывести все точки, принадлежащие квадрату с центром в точке (X,Y) и стороной A=2. Координаты X,Y вводить с клавиатуры.

Задание 10. Вывести все точки, принадлежащие кругу с центром в точке (2,2) и радиусом R=1.8. Подсказка: для вычисления квадратного корня, квадратов и абсолютного значения используйте библиотеку math.

Задание 11. Вывести все точки, лежащие вне круга с центром в точке (X,Y) и радиусом R. Значения X,Y и R вводить с клавиатуры.

Соседние файлы в папке Лабораторные работы