
ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ
УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ
«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М.А. БОНЧ-БРУЕВИЧА»
(СПбГУТ)
ФАКУЛЬТЕТ ИНФОКОММУНИКАЦИОННЫХ СЕТЕЙ И СИСТЕМ (ИКСС)
КАФЕДРА ПРОГРАММНОЙ ИНЖЕНЕРИИ И ВЫЧИСЛИТЕЛЬНОЙ ТЕХНИКИ (ПИИВТ)
ДИСЦИПЛИНА: «Логическое и функциональное программирование»
Лабораторная работа №4.
«Задачи на переливание»
Выполнил:
Козлов Н.С
Подпись____________
Принял:
Ерофеев С.А.
Подпись____________
«_____»________ 2022
Оглавление
Постановка задачи 3
Описание алгоритма 3
Код программы 4
Пример работы программы 5
Выводы 6
Постановка задачи
Требуется написать программу на языке логического программирования Prolog, осуществляющую решение задач на переливание с двумя сосудами объёмов m и n. Решением задачи является выведенная программой последовательность действий, с помощью которой возможно было бы отмерить x литров воды, пользуясь вышеописанными сосудами.
Описание алгоритма
Алгоритм исследует два способа переливания с помощью представленных ёмкостей. Затем выбирается наиболее короткий способ решения поставленной задачи и отправляет его на вывод.
Для
решения задачи, алгоритм имеет 3 действия:
наполнить сосуд, опустошить сосуд,
перелить из одного сосуда в другой.
Код программы
domains int = integer str = string ss = string* predicates fill(int, int, int, str) empty(int, int, int, str) pour(int, int, int, int, int, int, str) find(int, int, int) find_1(int, int, int, int, int, int, int, ss) find_2(int, int, int, int, int, int, int, ss) output(int, ss, int, ss) clauses fill(K, 0, K, S):- format(S, "Fill % liter container", K),!. fill(_, X, X, "").
empty(K, K, 0, C):- format(C, "Empty % liter container", K),!. empty(_, X, X, "").
pour(K1, A, A1, K2, B, K2, C):- A + B > K2, A1 = A + B - K2, !, format(C, "Fill %-liter container from % liter container", K2, K1), nl. pour(K1, A, 0, K2, B, B1, C):- B1 = A + B, !, format(C, "Pour into %-liter container from % liter container", K2, K1), nl.
find(_,X,X):- write("Number of transfusions = 0"), nl, write("Steps: ", "Fill ", X, " liter container with ", X, " liters"), nl, !. find(X,_,X):- write("Number of transfusions = 0"), nl, write("Steps: ", "Fill ", X, " liter container with ", X, " liters"), nl, !. find(K1,_,X):- K1 > X, write("Containers must be less than X"), nl, !. find(K1, K2, X):- find_1(K1,0,K2,0,X,0,X1,Steps1), find_2(K1,0,K2,0,X,0,X2,Steps2), output(X1, Steps1, X2, Steps2).
find_1(_,X,_,_,X,H,H,[]):-!. find_1(_,_,_,X,X,H,H,[]):-!. find_1(K1, A, K2, B, X, H, F, [Fill,Empty,Pour|Steps]):- fill(K1, A, A1, Fill), empty(K2, B, B1, Empty), pour(K1, A1, A2, K2, B1, B2, Pour), Ch1=H+1,!, find_1(K1, A2, K2, B2, X, CH1, F, Steps).
find_2(_,X,_,_,X,H,H,[]):-!. find_2(_,_,_,X,X,H,H,[]):-!. find_2(K1, A, K2, B, X, H, F, [Fill,Empty,Pour|Steps]):- empty(K1, A, A1, Empty), fill(K2, B, B1, Fill), pour(K2, B1, B2, K1, A1, A2, Pour), Ch1=H+1,!, find_2(K1,A2,K2,B2,X,CH1,F,Steps).
output(N1, Steps1, N2, _):- N1 < N2, !, write("Number of transfusions = ", N1), nl, write("Steps: ", Steps1), nl. output(_,_,H,Steps):- write("Number of transfusions = ", H), nl, write("Steps: ", Steps), nl. |
Пример работы программы
Выводы
В среде разработке Turbo Prolog 2.0, на языке логического программирования Prolog, была разработана программа, позволяющая найти оптимальное решение задач на переливание с неопределёнными заранее аргументами.