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

Лаб. 6 ФЛП

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

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

%1

% База данных родственных связей

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

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

мать(анна, лиза).

мать(анна, марк).

мать(лиза, виктор).

% Родитель — это либо отец, либо мать

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

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

% Предок — это родитель или предок родителя

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

предок_потомок(X, Y) :- родитель(X, Z), предок_потомок(Z, Y).

%предок_потомок(лиза, X)

% База данных списков

список([1, 2, 3, 4]).

список([apple, banana, orange, mango]).

список([x, y, z, a]).

% Основной предикат: ищем список, в котором последний элемент = Last

my_last2(X, Last) :-

список(X), % Берём список из базы

last(X, Last). % Проверяем его последний элемент

% last/2 — находит последний элемент списка

last([X], X). % База: если в списке один элемент, он и есть последний

last([_ | T], X) :- last(T, X). % Рекурсивный случай: идём дальше по списку

%my_last2(X, a)

%my_last2(X, 2)

Дерево вызовов для предок_потомок(лиза, X):

  1. предок_потомок(X, Y) :- родитель(X, Y).

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

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

  4. предок_потомок(X, Y) :- родитель(X, Z), предок_потомок(Z, Y).

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

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

Дерево вызовов для my_last2(X, a):

  1. my_last2(X, Last)

  2. last([_ | T], X) вызовется 11 раз

  3. last([X], X)

:- begin_tests(predok_potomok).

test(ivan_is_ancestor_of_liza) :-

предок_потомок(иван, лиза).

test(ivan_is_ancestor_of_viktor) :-

предок_потомок(иван, виктор).

test(anna_is_ancestor_of_viktor) :-

предок_потомок(анна, виктор).

test(liza_is_ancestor_of_viktor) :-

предок_потомок(лиза, виктор).

test(marc_is_not_ancestor_of_viktor, fail) :-

предок_потомок(марк, виктор).

test(viktor_is_not_ancestor_of_ivan, fail) :-

предок_потомок(виктор, иван).

:- end_tests(predok_potomok).

:- begin_tests(my_last2).

test(last_element_4) :-

my_last2([1, 2, 3, 4], 4).

test(last_element_mango) :-

my_last2([apple, banana, orange, mango], mango).

test(last_element_a) :-

my_last2([x, y, z, a], a).

test(find_list_with_last_a) :-

my_last2([x, y, z, a], a). % Здесь X не используется, так что избавляемся от неё

test(find_list_with_last_2, fail) :-

my_last2([1, 2, 3, 4], 2). % Здесь тоже X не используется

test(find_list_with_last_pizza, fail) :-

my_last2([x, y, z, a], pizza). % Нет такого элемента в списке

:- end_tests(my_last2).

%2

zip([], [], []). % Пустые списки дают пустой результат.

zip([H1|T1], [H2|T2], [[H1, H2]|ZippedTail]) :-

zip(T1, T2, ZippedTail). % Рекурсивно объединяем оставшиеся элементы.

%zip([a,b,c], [1,2,3], X)

%zip(X, [1,2,3], [[a,1], [b,2], [c,3]])

%zip([a,b,c], X, [[a,1], [b,2], [c,3]])

%zip(X, Y, [[a,1], [b,2], [c,3]])

%zip([a, b], [1, 2, 3], X)

:- begin_tests(zip).

test(zip_normal_case) :-

zip([a, b, c], [1, 2, 3], X),

X == [[a,1], [b,2], [c,3]].

test(zip_empty_lists) :-

zip([], [], X),

X == [].

test(zip_first_argument_var) :-

zip(X, [1, 2, 3], [[a,1], [b,2], [c,3]]),

X == [a, b, c].

test(zip_second_argument_var) :-

zip([a, b, c], X, [[a,1], [b,2], [c,3]]),

X == [1, 2, 3].

test(zip_both_arguments_vars) :-

zip(X, Y, [[a,1], [b,2], [c,3]]),

X == [a, b, c],

Y == [1, 2, 3].

test(zip_unequal_length, fail) :-

zip([a, b], [1, 2, 3], _).

test(zip_partial_match, fail) :-

zip([a, b, c], [1, 2], _).

:- end_tests(zip).

%3

% Предикат успешен, если в списке есть повторяющиеся элементы.

contains_duplicates(List) :-

append(_, [X | Tail], List), % Разделяем список, начиная с элемента X

member(X, Tail). % Проверяем, есть ли X в оставшейся части списка

%contains_duplicates([a, b, a, b, c, c, a])

%contains_duplicates([a, b, c])

%contains_duplicates([X, Y, X])

%contains_duplicates([X, Y, Z])

:- begin_tests(contains_duplicates).

test(duplicates_present) :-

contains_duplicates([a, b, a, b, c, c, a]).

test(no_duplicates, fail) :-

contains_duplicates([a, b, c]).

test(empty_list, fail) :-

contains_duplicates([]).

test(single_element_list, fail) :-

contains_duplicates([a]).

test(two_same_elements) :-

contains_duplicates([x, x]).

:- end_tests(contains_duplicates).

%4

% Базовый случай: пустой список расплющивается в пустой список

my_flatten([], []).

% Если голова списка — это список, рекурсивно обрабатываем его и объединяем с остальным

my_flatten([H | T], Flattened) :-

my_flatten(H, FlatHead), % Расплющиваем голову

my_flatten(T, FlatTail), % Расплющиваем хвост

append(FlatHead, FlatTail, Flattened). % Объединяем результат

% Если голова списка — не список, просто добавляем её к результату

my_flatten(X, [X]) :-

X \= [],

X \= [_|_].

%my_flatten([a, [[b], c], [[d]]], X)

%my_flatten([[1, [2, 3]], [4, [5]], 6], X)

%my_flatten([], X)

:- begin_tests(my_flatten).

% Тест для простого случая: уже плоский список

test(flatten_simple) :-

my_flatten([a, b, c], X),

X == [a, b, c].

% Тест для вложенных списков

test(flatten_nested) :-

my_flatten([a, [[b], c], [[d]]], X),

X == [a, b, c, d].

% Тест для глубоко вложенных списков

test(flatten_deeply_nested) :-

my_flatten([[1, [2, [3, [4, 5]]]], 6], X),

X == [1, 2, 3, 4, 5, 6].

% Тест для списка с пустыми подсписками

test(flatten_with_empty_lists) :-

my_flatten([a, [], [b, []], [[]], c], X),

X == [a, b, c].

% Тест для пустого списка

test(flatten_empty_list) :-

my_flatten([], X),

X == [].

% Тест для списка с одним элементом

test(flatten_single_element) :-

my_flatten([x], X),

X == [x].

% Тест для списка, содержащего только вложенные пустые списки

test(flatten_only_empty_lists) :-

my_flatten([[], [[]], [[[]]]], X),

X == [].

:- end_tests(my_flatten).

%5

% Базовый случай: код Грея для одного бита

gray([_], [[0], [1]]).

% Рекурсивное построение кода Грея для N бит

gray([_|T], Code) :-

gray(T, SmallerCode), % Строим код для (N-1) бит

reverse(SmallerCode, RevCode), % Переворачиваем его

add_prefix(0, SmallerCode, ZeroPrefixed), % Дописываем 0 в начало

add_prefix(1, RevCode, OnePrefixed), % Дописываем 1 в начало

append(ZeroPrefixed, OnePrefixed, Code). % Объединяем

% Вспомогательный предикат: добавляет префикс к каждому элементу списка

add_prefix(_, [], []).

add_prefix(Prefix, [H|T], [[Prefix|H]|Rest]) :-

add_prefix(Prefix, T, Rest).

%gray([0], Code)

%gray([0,0], Code)

%gray([0,0,0], Code)

:- begin_tests(gray).

test(gray_1bit) :-

gray([0], [[0], [1]]).

test(gray_2bit) :-

gray([0,0], [[0,0], [0,1], [1,1], [1,0]]).

test(gray_3bit) :-

gray([0,0,0], [[0,0,0], [0,0,1], [0,1,1], [0,1,0],

[1,1,0], [1,1,1], [1,0,1], [1,0,0]]).

test(gray_4bit) :-

gray([0,0,0,0], [[0,0,0,0], [0,0,0,1], [0,0,1,1], [0,0,1,0],

[0,1,1,0], [0,1,1,1], [0,1,0,1], [0,1,0,0],

[1,1,0,0], [1,1,0,1], [1,1,1,1], [1,1,1,0],

[1,0,1,0], [1,0,1,1], [1,0,0,1], [1,0,0,0]]).

test(gray_invalid_input, fail) :-

gray([], _).

:- end_tests(gray).

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