Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка_РЛП_4_форм.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
644.61 Кб
Скачать

3.13.Решение головоломки на языке пролог(задача Эйнштейна)

Рассмотрим головоломку Эйнштейна,

Условия задачи.

Общие условия

1. Есть 5 домов, каждый разного цвета, и пронумерованы они слева направо.

2. В каждом доме живет по одному человеку отличной друг от друга национальности.

3. Каждый жилец пьет только один определенный напиток, курит определенную марку табака и держит определенное животное.

4. Никто из 5 человек не пьет одинаковые с другими напитки, не курит одинаковый табак и не держит одинаковое животное.

Дополнительные условия:

1. Англичанин живет в красном доме.

2. Швед держит собаку.

3. Датчанин пьет чай.

4. Зеленый дом стоит слева от белого.

5. Жилец зеленого дома пьет кофе.

6. Человек, который курит Pall Mall, держит птицу.

7. Жилец из среднего дома пьет молоко.

8. Жилец из желтого дома курит Dunhill.

9. Норвежец живет в первом доме.

10. Курильщик Marlboro живет около того, кто держит кошку.

11. Человек, который содержит лошадь, живет около того, кто курит Dunhill.

12. Курильщик Winfield пьет пиво.

13. Норвежец живет около голубого дома.

14. Немец курит Rothmans.

15. Курильщик Marlboro живет по соседству с человеком, который пьет воду.

Вопрос: кому принадлежит рыба?

Решение задачи

Общие условия находят свое отражение в пролог-программе в виде специального списка из пяти структур (соответствующих пяти домам), каждая из которых содержит пять полей, соответствующих цвету дома, национальности жильца, напитку, марке табака и животному.

list([f_(C1,N1,D1,K1,A1), f_(C2,N2,D2,K2,A2),

f_(C3,N3,D3,K3,A3), f_(C4,N4,D4,K4,A4),

f_(C5,N5,D5,K5,A5)]).

Для упрощения работы с полями структуры служат следующие предикаты:

color(f_(A,B,C,D,E),A).

nationality(f_(A,B,C,D,E),B).

drink(f_(A,B,C,D,E),C).

smok(f_(A,B,C,D,E),D).

animal(f_(A,B,C,D,E),E).

Пространственные отношения между домами программируются в виде следующих предикатов:

Быть слева (считаем, что слева – значит слева рядом).

left(A,B,[A,B,C,D,E]).

left(B,C,[A,B,C,D,E]).

left(C,D,[A,B,C,D,E]).

left(D,E,[A,B,C,D,E]).

Быть в центре.

center(C,[A,B,C,D,E]).

Быть первыи.

first(A,[A,B,C,D,E]).

Быть соседом.

near(X,Y,Z):-near1(X,Y,Z).

near(X,Y,Z):-near1(Y,X,Z).

near1(A,B,[A,B,C,D,E]).

near1(B,C,[A,B,C,D,E]).

near1(C,D,[A,B,C,D,E]).

near1(D,E,[A,B,C,D,E]).

Дополнительные условия программируются следующим предложением (используем встроенный предикат member):

cond(F):- list(F), %заголовок предиката и сопоставление переменной с основной структурой

% Англичанин живет в красном доме

member(M11,F),

nationality(M11, england),

color(M11,red),

% Швед держит собаку.

member(M12,F),

nationality(M12, sweden),

animal(M12,dog),

% Датчанин пьет чай.

member(M13,F),

nationality(M13, danmark),

drink(M13,tea),

% Зеленый дом стоит слева от белого.

left(M14,M24,F),

color(M14,green),

color(M24,white),

% Жилец зеленого дома пьет кофе.

member(M15,F),

color(M15,green),

drink(M15,cafe),

% Человек, который курит Pall Mall, держит птицу.

member(M16,F),

smork(M16,pallmall),

animal(M16,bird),

% Жилец из среднего дома пьет молоко.

middle(M17,F),

drink(M17,milk),

% Жилец из желтого дома курит Dunhill.

member(M18,F),

color(M18,yellow),

smork(M18,danhill),

% Норвежец живет в первом доме.

first1(M19,F),

nationality(M19, norway),

% Курильщик Marlboro живет около того, кто держит кошку.

near(M110,M210,F),

smork(M110,marlboro),

animal(M210,cat),

% Человек, который содержит лошадь, живет около того, кто курит Dunhill.

near(M111,M211,F),

smork(M211,danhill),

animal(M111,horse),

% Курильщик Winfield пьет пиво.

member(M112,F),

smork(M112,winfield),

drink(M112,beer),

% Норвежец живет около голубого дома.

near(M113,M213,F),

nationality(M113, norway),

color(M213,blue),

% Немец курит Rothmans.

member(M114,F),

nationality(M114, german),

smork(M114,rothmans),

% Курильщик Marlboro живет по соседству с человеком, который пьет воду.

near(M115,M215,F),

smork(M115,marlboro),

drink(M215,water).

Вопрос записывается в виде следующего предложения. Определим цвет дома и национальность владельца рыбы.

% кому принадлежит рыба?

queries(F,[['Fish -', C, N]]):-member(Q1,F),

nationality(Q1,N),

color(Q1,C),

animal(Q1,fish).

Наконец основной предикат можно определить следующим образом.

main(X,Z):- cond(X), queries(X,Z).

После запроса к системе получим ответ.

?- main(X,Z).

X = [f_(yellow, norway, water, danhill, cat), f_(blue, danmark, tea, marlboro, horse), f_(red, england, milk, pallmall, bird), f_(green, german, cafe, rothmans, fish), f_(white, sweden, beer, winfield, dog)]

Y = [['Fish -', green, german]]

Переменная X содержит всю структуру, а Yответ на поставленный вопрос.

Можно несколько ослабить условие задачи. Например, отношение «быть слева» можно интерпретировать в смысле слева и необязательно рядом. Это приведет к небольшим изменениям в программе (в предикате left) и по запросу будет выдано несколько вариантов решений.