====== Лабораторная работа №3: Рекурсивные структуры данных (списки) ======
===== Цель работы =====
Изучение и исследование рекурсивных структур данных в языке Visual Prolog на примере списков.
===== Основные теоретические положения =====
Пролог позволяет определить и использовать рекурсивные типы данных. Примерами рекурсивных типов данных служат списки и деревья. Список -- это объект данных, содержащий конечное число других объектов (элементов списка). Список, содержащий числа 1, 2 и 3, записывается следующим образом: ''[1, 2, 3]''.
Для объявления списка используется следующее описание домена:
domains
integerlist=integer*
Список является рекурсивным составным объектом, он состоит из двух частей:
* головы списка -- первого элемента списка;
* хвоста списка -- списка, включающего все последующие элементы.
Пусть имеется список ''[1|[2, 3]]''. Тогда головой списка будет элемент ''1'', а хвостом ''[2, 3]''.
Так как список имеет рекурсивную составную структуру, для работы со списками используется рекурсия.
//Пример 1.// Вывод элементов списка.
domains
integerlist=integer*
predicates
printlist(integerlist)
clauses
printlist([]) :- !. % Для пустого списка ничего не делать
printlist([H|T]) :- write(H), nl, printlist(T). % Для непустого списка
% отделить голову,
% вывести ее,
% продолжить вывод для
% хвоста списка
//Пример 2.// Необходимо преобразовать список, элементами которого являются целые числа, инвертируя знак элементов списка, то есть положительные числа преобразовать в отрицательные, отрицательные в положительные, для нулевых значений никаких действий не предпринимать.
Придется рассмотреть два случая -- для непустого и пустого списков. Преобразование пустого списка дать в результате также пустой список. Если же список не пуст, то следует рекурсивно выполнять отделение головы списка, ее обработку и рассматривать полученный результат как голову списка-результата.
domains
intlist=integer*
predicates
inverting(intlist, intlist)
processing(integer, integer)
clauses
% обработка пустого списка дает, в результате, тоже пустой список
inverting([ ], [ ]) :- !.
% если список непустой, отделить голову, обработать ее,
% и добавить в качестве головы списка-результата
inverting([H | T], [Inv_H | Inv_T]):-
processing(H, Inv_H), inverting(T, Inv_T).
% предикат processing выполняет действия по обработке элемента списка в
% зависимости от его знака, предикат имеет два предложения,
% так как нужно рассмотреть два варианта: ненулевое и нулевое значения
processing(0, 0) :- !.
processing(H, Inv_H) :- Inv_H=-H.
goal
inverting([-2, -1, 0, 1, 2], Inv_List), write("Inv_List=", Inv_List).
Результат работы программы:
Inv_List=[2, 1, 0, -1, -2]
===== Постановка задачи =====
Реализовать на языке Visual Prolog программу, выполняющую заданные операции над списками в соответствии с индивидуальным вариантом задания.
===== Порядок выполнения работы =====
- Напишите на языке Visual Prolog программу, реализующую заданные операции над списками в соответствии с индивидуальным вариантом задания.
- Произведите отладку программы в системе Visual Prolog для запросов на решение прямой и обратной задачи и задачи на перебор вариантов.
- Постройте трассу программы при выполнении каждого запроса.
===== Варианты заданий =====
[[.:lab3:lab3_vars]]
===== Содержание отчёта =====
* Цель работы.
* Краткое изложение основных теоретических понятий.
* Постановка задачи с кратким описанием порядка выполнения работы.
* Трассы выполнения запросов и объяснение результатов их выполнения.
* Общий вывод по проделанной работе.
* Код программы.