Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
РК_19_03_2008.doc
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
2.57 Mб
Скачать

Порядок виконання завдання

1. Рекомендується попередньо розібратися з наведеними теоретичними відомостями.

2. Відпрацюйте приклад 1. Результати (питання та відповіді в Пролог) занесіть у звіт. Питання повинні бути такими: Хто батьки Кароліни? Чи правда, що Едвард Кеннеді є родителем для Патріка? Хто батьки Кари та Едварда молодшого?

Приклад 1. Необхідно записати базу знань у вигляді логічних тверджень для генеалогічного дерева відомої родини Кеннеді (рис. 4.17). Після цього треба задати наступні питання: Хто батьки Кароліни? Чи правда, що Едвард Кеннеді є родителем Патріка? Хто батьки Кари та Едварда молодшого?

Рис. 4.17. Генеалогічне дерево родини Кеннеді

Розв’язок. Створимо новий файл в головному вікні Пролога як це показано на рис. 4.18. Рекомендується набрати та запустити наведений нижче лістинг програми в Пролог з метою набуття навичок практичного розв’язання представленої типової задачі.

Рис.4.18. Інтерфейс Пролога

родитель(джозеф, джон).

родитель(роуз, джон).

родитель(джон, кароліна).

родитель(жаклін, кароліна).

родитель(джон, джон_молодший).

родитель(жаклін, джон_молодший).

родитель(джон, патрік).

родитель(жаклін, патрік).

родитель(джозеф, едвард).

родитель(роуз, едвард).

родитель(едвард, кара).

родитель(вірджінія, кара).

родитель(едвард, едвард_молодший).

родитель(вірджінія, едвард_молодший).

родитель(едвард, патрік_молодший).

родитель(вірджінія, патрік_молодший).

Тепер збережіть файл, а в діалоговому вікні оберіть команду Consult Тепер можна задавати питання. Відповіді разом із питаннями мають бути занесені у звіт.

3. Відпрацюйте приклад 2. Результати (визначення родинних відносин типу „батько”, „сестра”, „небіж” у Пролог) занесіть у звіт.

Приклад 2. Необхідно додати до попередньої програми ще декілька родинних відносин (мати, батько, сестра, брат).

Розв’язок. Визначимо відношення мати наступним чином:

Для всіх X і Y

X - мати Y,

якщо X - родитель Y

і X - жінка.

Додаймо до програми нове правило:

мати( X, Y) :- родитель( X, Y), стать(X, жінка).

Давайте тепер спитаємо у інтерпретатора Пролог: хто мати Джона? Це буде виглядати таким чином:

?- мати(Хто,джон).

Хто = роуз ;

No

Тепер час для того, щоб визначити відношення брат:

Для всіх X і Y,

X – брат Y,

якщо X і Y мають однакових батьків, і

якщо X - чоловік.

брат(X, Y):-родитель(Z, X),

родитель(Z, Y),

стать(X, чоловік).

Тепер спитаємо Пролог-інтерпретатора: хто брат Джона?:

?- брат(X, джон).

Відповідь буде досить дивною, як на перший погляд:

X = джон ;

X = джон ;

X = едвард ;

X = едвард ;

No

Спробуйте усунути дані неточності у відповідях та крім того розширити програму за рахунок введення нових відносин „батько”, „сестра” і „небіж”. Результати мають бути занесені у звіт.

ПІДКАЗКА Зверніть увагу на такий корисний вбудований предикат як dif(A,B). Він забезпечує обмеження на те, щоб A і B були різними термами.

Необхідно також визначити відношення „пращур” через рекурсію та занести у звіт формулювання питання „Хто є пращурами Джона молодшого?” та відповідь на неї.

4. Відпрацюйте приклад 3. Результати (повний лістинг процедури розв’язок та результати виконання програми) занесіть у звіт.

Приклад 3. Необхідно розв’язати задачу про вісім ферзів. Необхідно знайти таке розташування восьми ферзів на пустій шахівниці, при якому жоден з ферзів не буде знаходитися під ударом інших.

Розв’язок. Розв’язок будемо представляти у вигляді унарного відношення: розв’язок (Положення), яке істинно тоді і тільки тоді, коли змінна Положення відображає позицію, в якій вісім ферзів не б’ють один одного. Далі буде наведено один з можливих варіантів розв’язання вказаної задачі.

Спочатку треба обрати спосіб представлення позицій на дошці. Один з можливих та найприродніших способів – представити позицію у вигляді списку з восьми елементів, кожен з яких відповідає одному з ферзів. Кожен елемент буде описувати те поле дошки, де стоїть відповідний ферзь. Крім того, кожне поле дошки можна описати з допомогою пари координат (Х, Y ), де кожна координата – ціле число від одного до восьми. В програмі таку пару будемо записувати у вигляді: X/Y, де оператор "/" позначує не ділення, а служить лише для об’єднання координат поля в один елемент списку. На рис. 4.19 показано один із можливих розв’язків задачі про вісім ферзів і його запис у вигляді списку.

Після того, як було обрано таке представлення, задача звелася до знаходження списку вигляду:

[Xl/Yl, X2/Y2, X3/Y3, X4/Y4, X5/Y5, X6/Y6, X7/Y7, X8/Y8],

що задовольняє вимогам відсутності нападу. Отже, процедура розв’язання має знайти відповідну реалізацію змінних X1, Y1, Х2, Y2, ..., Х8, Y8.

Рис. 4.19. Розв’язок задачі про вісім

ферзів у вигляді списку

[1/4,  2/2,  3/7,   4/3,  5/6,  6/8,  7/5,  8/1].

Оскільки відомо, що всі ферзі мають знаходитися на різних вертикалях для уникнення нападу по вертикальним лініям, то можна відразу обмежити перебір для полегшення пошуку рішення. Тому можна відразу зафіксувати Х-координати так, щоб список, що відображає розв’язок, задовольняв наступному, конкретнішому шаблону:

[1/Y1, 2/Y2, 3/Y3, 4/Y4, 5/Y5, 6/Y6, 7/Y7, 8/Y8].

Нас цікавить розв’язок на дошці розміром 8х8. Але, як часто буває у програмуванні, іноді ключ до розв’язання проблеми легше знайти, розглянувши загальну постановку задачі. Після розв’язання загальної задачі рішення для конкретної задачі знаходиться як частинний випадок.

В нашому випадку будемо узагальнювати задачу в кількості ферзів (тобто кількості вертикальних ліній у списку), дозволив кількості ферзів приймати будь-яке значення, включаючи нуль. Тоді відношення розв’язок можна сформулювати, розглянувши два випадки:

Випадок 1. Список ферзів пустий. Пустий список без сумніву є рішенням, оскільки нападів в цьому випадку немає.

Випадок 2. Список ферзів не пустий. Тоді він виглядає так:

        [ X/Y | Інші]

У випадку 2 перший ферзь знаходиться на полі Х/Y, а інші - на полях, що указані в списку Інші. Якщо ми хочемо, щоб це було рішенням, то мають виконуватися наступні умови:

(1) Ферзі, що перераховані у списку Інші, не повинні бити один одного; тобто список Інші сам має бути розв’язком.

(2) Х і Y повинні бути цілими числами від 1 до 8.

(3) Ферзь, що стоїть на поле X/Y, не повинен бити жодного ферзя із списку Інші.

Щоб запрограмувати першу умову, можна використати саме відношення розв’язок. Друга умова може бути сформульована так: Y повинен належати до списку цілих чисел від 1 до 8, тобто [1, 2, 3, 4, 5, 6, 7, 8]. З іншого боку, про координату Х можна не хвилюватися, оскільки список-рішення повинен відповідати шаблону, для якого Х-координати вже визначені. тому Х гарантовано отримує правильне значення від 1 до 8. Третя умова може бути забезпечена з допомогою нового відношення не_б’є. Все це можна записати у Пролог так:

розв’язок([X/Y|Інші]):-

розв’язок(Інші),           належить(Y, [1,2,3,4,5,6,7,8]),

не_б’є( X/Y, Інші).

Залишилось визначити відношення не_б’є:

    не_б’є( Ф, Фспис)

І знову його опис можна розбити на два випадки:

(1) Якщо список Фспис пустий, то відношення безумовно виконано, оскільки немає кого бити (немає ферзя, на якого можні було б напасти).

(2) Якщо Фспис не пустий, то він має форму

        [Ф1 | Фспис1]

і дві умови повинні виконуватися:

(а)         ферзь на полі Ф не повинен бити ферзя на полі Ф1 і

(b)         ферзь на полі Ф не повинен бити жодного ферзя із списку Фспис1.

Виразити умову, щоб ферзь, який знаходиться на певному полі, не бив інше поле, досить просто: ці поля не повинні знаходитися на одних і тих самих горизонталях, вертикалях і діагоналях. Наш шаблон рішення гарантує, що всі ферзі знаходяться на різних вертикалях, тому залишається тільки забезпечити, щоб

1) Y-координати ферзів були різними і

2) ферзі не знаходились на одній діагоналі, тобто відстань між полями за напрямком Х не повинна дорівнювати відстані між полями по Y.

Фрагмент програми Пролог для розв’язання вказаної задачі наведений нижче. Завданням є завершити програму та занести результати (декілька можливих, не всі!) у звіт.

розв’язок([]).

розв’язок ([X/Y|Інші]):-

%перший ферзь на полі X/Y, інші ферзі на полях із списку Інші

____________________________,

____________________________,

____________________________. % перший ферзь не б’є інших

не_б’є (_, []). % немає ферзів для атаки

не_б’є (X/Y, [X1/Y1|Інші]):-

Y=\=Y1,

%різні координати Y

Y1-Y=\=X1-X,

%різні діагоналі

Y1-Y=\=X-X1, не_б’є(X/Y, Інші).

належить(X, [X | L] ).

належить(X, [Y|L]):-

належить( X, L).

% шаблон розв’язку

шаблон([1/Y1, 2/Y2, 3/Y3, 4/Y4, 5/Y5, 6/Y6, 7/Y7, 8/Y8]).

У запиті для генерацію розв’язків необхідно записати:

?- шаблон(S), розв’язок(S).