Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лаб. 5 ФЛП

.docx
Скачиваний:
0
Добавлен:
29.05.2025
Размер:
394.41 Кб
Скачать

Лабораторная работа 5

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

'язык Пролог' – строка в одинарных кавычках. В Prolog строки в таких кавычках считаются атомами.

Пролог – начинается с заглавной буквы, а значит, это переменная.

Альберт(любит, мясо) – выглядит как сложный терм (функтор с аргументами), но Альберт с заглавной буквы интерпретируется как переменная. В таком виде это не терм.

любит(Альберт, мясо) – корректный сложный терм: функтор любит (с маленькой буквы, как и положено), два аргумента (Альберт – переменная, мясо – атом).

  1. meal(food(Y), X) = meal(X, drink(Z))

  • Термы имеют одинаковый функтор meal/2, поэтому можно пытаться унифицировать их аргументы:

    • food(Y) = X

    • X = drink(Z)

    • Подставляя X = drink(Z) в первое уравнение: food(Y) = drink(Z)

    • food(Y) и drink(Z) не могут быть равны (разные функторы).

  • Сопоставление не удастся.

  1. food(bread, X, beer) = food(Y, burger)

  • Термы food/3 и food/2 имеют разное количество аргументов, поэтому сопоставление не удастся.

  1. likes(X, cola) = likes(Y, cola)

  • Функторы и вторая часть аргументов (cola) совпадают.

  • Остаётся X = Y, что возможно.

  • Успешное сопоставление: X = Y.

  1. 'bread' = bread

  • В Prolog 'bread' и bread – это одно и то же (одинаковые атомы).

  • Сопоставление удастся.

  1. likes(X, food(Y)) = likes(Y, food(Z))

  • Функторы совпадают, разбираем аргументы:

    • X = Y

    • food(Y) = food(Z), что даёт Y = Z.

  • Успешное сопоставление: X = Y, Y = Z.

%3

отец(иван, настя). % Иван – отец Насти

отец(сергей, анна). % Сергей – отец Анны

%отец(X, настя)

%отец(иван, X)

%4

мать(елена, анна).

мать(ирина, сергей).

родитель(X, Y) :- отец(X, Y).

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

счастлив(X) :- родитель(X, _).

%счастлив(X)

%5

% Родственные отношения

отец(иван, анна).

отец(иван, сергей).

отец(пётр, мария).

отец(пётр, виктория).

отец(пётр, алексей).

мать(елена, анна).

мать(ирина, сергей).

мать(марина, мария).

мать(марина, виктория).

мать(марина, алексей).

мать(виктория, игорь).

мать(виктория, светлана).

мать(мария, павел).

% Общий предикат родитель/2

родитель(X, Y) :- отец(X, Y).

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

% Предикат "тётя"

тётя(X, Y) :-

сестра(X, Родитель), % X – сестра одного из родителей Y

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

% Определение сестры

сестра(X, Y) :-

родитель(Родитель, X),

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

X \= Y, % X и Y – разные люди

женский(X).

% Пол

женский(анна).

женский(мария).

женский(елена).

женский(ирина).

женский(марина).

женский(виктория).

женский(светлана).

%тётя(мария, игорь)

%тётя(мария, светлана)

%тётя(виктория, павел)

%тётя(марина, алексей)

%тётя(пётр, светлана)

% Факты

автор("Война и мир", "Лев Толстой").

автор("Анна Каренина", "Лев Толстой").

автор("Преступление и наказание", "Фёдор Достоевский").

автор("Идиот", "Фёдор Достоевский").

автор("Мастер и Маргарита", "Михаил Булгаков").

жанр("Война и мир", "Роман").

жанр("Анна Каренина", "Роман").

жанр("Преступление и наказание", "Драма").

жанр("Идиот", "Драма").

жанр("Мастер и Маргарита", "Фантастика").

написал_в("Лев Толстой", 1869).

написал_в("Фёдор Достоевский", 1866).

написал_в("Фёдор Достоевский", 1869).

написал_в("Михаил Булгаков", 1940).

% Современники (разница в годах написания <= 50 лет)

современники(Автор1, Автор2) :-

написал_в(Автор1, Год1),

написал_в(Автор2, Год2),

Автор1 \= Автор2,

abs(Год1 - Год2) =< 50.

% Прямые связи между книгами (по автору или жанру)

прямая_связь(Книга1, Книга2) :-

автор(Книга1, Автор), автор(Книга2, Автор), Книга1 \= Книга2.

прямая_связь(Книга1, Книга2) :-

жанр(Книга1, Жанр), жанр(Книга2, Жанр), Книга1 \= Книга2.

% Рекурсивное правило: если Книга1 связана с КнигаПромежуточная, а та — с Книга2

связаны(Книга1, Книга2) :- связаны(Книга1, Книга2, []).

связаны(Книга1, Книга2, _) :-

прямая_связь(Книга1, Книга2).

связаны(Книга1, Книга2, Visited) :-

прямая_связь(Книга1, КнигаПромежуточная),

КнигаПромежуточная \= Книга1,

КнигаПромежуточная \= Книга2,

not(member(КнигаПромежуточная, Visited)), % Проверяем, не посещали ли уже

связаны(КнигаПромежуточная, Книга2, [КнигаПромежуточная | Visited]).

%современники("Лев Толстой", "Фёдор Достоевский")

%связаны("Война и мир", "Идиот")

%связаны("Мастер и Маргарита", "Анна Каренина")

%связаны("Война и мир", "Анна Каренина")

%связаны("Преступление и наказание", "Идиот")

% Факты о рейсах между городами

есть_рейс(мос, спб).

есть_рейс(мос, ект).

есть_рейс(мос, новосиб).

есть_рейс(спб, новосиб).

есть_рейс(спб, сочи).

есть_рейс(спб, минск).

есть_рейс(ект, сочи).

есть_рейс(сочи, киев).

есть_рейс(минск, новосиб).

есть_рейс(минск, киев).

есть_рейс(казань, омск).

% Двусторонние рейсы

рейс(X, Y) :- есть_рейс(X, Y).

рейс(Y, X) :- есть_рейс(X, Y).

% Связанность городов (учёт циклов)

связаны(X, Y) :- связаны(X, Y, []).

связаны(X, Y, _) :- рейс(X, Y). % Прямой рейс

связаны(X, Y, Посещённые) :-

рейс(X, Z),

Z \= Y,

\+ member(Z, Посещённые), % Не заходили в Z раньше (предотвращаем циклы)

связаны(Z, Y, [Z | Посещённые]). % Добавляем Z в список посещённых

%связаны(мос, киев)

%связаны(новосиб, киев)

%связаны(спб, мос)

%forall((есть_рейс(A, _); есть_рейс(_, A)), forall((есть_рейс(B, _); есть_рейс(_, B)), связаны(A, B)))

Соседние файлы в предмете Функциональное и логическое программирование