- •Глава 1. Введение в пролог
 - •1. Декларативные и процедурные языки программирования
 - •2. Пролог и логика предикатов. Внешние цели
 - •3. Управление программой. Подцели. Механизм сопоставления
 - •4. Внутренние подпрограммы унификации
 - •Глава 2. Внутренние цели. Механизм возврата
 - •1. Структура пролог-программы
 - •2. Использование внутренних целей
 - •3. Встроенный предикат fail
 - •4. Сокращенные варианты внутренних запросов
 - •5. Использование в запросах анонимных переменных
 - •6. Механизм возврата
 - •Глава 3. Типы данных и арифметика Turbo Prolog
 - •1. Стандартные типы данных
 - •2. Структуры, простые и составные
 - •3. Структурные диаграммы
 - •4. Использование в запросах анонимных переменных
 - •5. Использование альтернативных доменов
 - •6. Арифметика в Turbo Prolog
 - •Глава 4. Предикат отсечения (!). Программирование альтернатив. Правила повтора
 - •1. Повторения и возвраты
 - •2. Отсечение (!)
 - •3. Программирование альтернатив
 - •4. Правило повтора
 - •Глава 5. Методы организации рекурсии
 - •1. Простая рекурсия
 - •2. Метод обобщенного правила рекурсии
 - •3. Граничное условие рекурсии. Нисходящая и восходящая рекурсии
 - •4. Программа о подсчете числа точек
 - •Глава 6. Списки
 - •1. Основные понятия
 - •2. Списки и турбо-пролог
 - •3. Атрибуты списка
 - •4. Внутреннее представление списков
 - •5. Применение списков в программе
 - •6. Метод разделения списка на голову и хвост
 - •7. Поиск элемента в списке
 - •8. Присоединение списка
 - •9. Добавление и удаление элемента
 - •10. Подсписок
 - •11. Перестановки списка
 - •Глава 7. Сортировка списков
 - •1. Разделение списка на два
 - •2. Сортировка списков методом вставки
 - •3. Быстрая сортировка
 - •4. Быстрая сортировка_1
 - •5. Компоновка данных в список
 - •Глава 8. Программирование алгоритмов с возвратом. Представление графов в turbo prolog
 - •1. Задача о весах
 - •2. Представление графов в turbo prolog
 - •3. Поиск пути на неориентированном графе
 - •4. Поиск гамильтоновых циклов
 - •5. Поиск пути минимальной стоимости
 - •Глава 9. Динамическая база данных
 - •1. Турбо-пролог и реляционные базы данных
 - •2. Описание предикатов динамических бд
 - •3. Встроенные предикаты asserta, assertz, retract, retractall, save, consult
 - •4. Создание динамической базы данных
 - •5. Обсуждение проекта базы данных
 - •6. Создание базы данных
 - •7. Написание программных модулей
 - •Глава 10. Глобальные переменные в turbo prolog
 - •1. Модификация базы данных
 - •2. Накопление результатов с помощью вынуждаемого возврата
 - •3. Подсчет членов парторганизации
 - •4. Поиск пути минимальной стоимости от a до z
 - •Библиографический список
 - •Оглавление
 
4. Быстрая сортировка_1
Программа быстрой сортировки будет работать очень неэффективно, если один из списков Big и Small существенно длиннее другого. Это произойдет, например, в случае, когда список почти отсортирован. От этого недостатка можно избавиться следующим образом: разбивать список на два списка примерно одинаковой длины.
Итак, необходимо:
1. Разбить L на два списка L1 и L2 примерно одинаковой длины.
2. Отсортировать их, получив списки S1 и S2.
3. Слить отсортированные S1 и S2, получив отсортированный список S.
Рекурсивное правило сортировки supersort1 будет выглядеть так:
supersort1(L,S):-
% разделение на два равных списка
div2(L,L1,L2),
supersort1(L1,S1),
supersort1(L2,S2),
% соединение отсортированных списков
concsort (S1,S2,S).
Определим, что в этой сортировке будет являться граничным условием, то есть задачей, решаемой непосредственно. Список [X], состоящий из одного элемента, правило div2 разделит на два: пустой [] и одноэлементный [X].
Следовательно, у нашей сортировки будут два граничных условия:
supersort1([],[]).
supersort1([X],[X]).
Опишем процедуру div2.
Идея очень простая:
1. Первый элемент списка [X,Y|T] отправляется в список L1, второй — в список L2.
2. Вызывается div2 для хвоста T.
div2([],[],[]).
div2([X],[X],[]).
div2([X,Y|L],[X|L1],[Y|L2]):-
div2(L,L1,L2).
Остается описать процедуру concsort(S1,S2,S) слияния двух отсортированных списков S1 и S2 в отсортированный список S.
Идея следующая:
1. Сравниваются головы H1 и H2 исходных списков. Меньший из этих элементов становится головой целевого списка S.
2. Остатки исходных списков с помощью concsort соединяются в хвост целевого.
concsort([H1|T1],[H2|T2],[H1|T]):-
H1<=H2,!,
concsort(T1,[H2|T2],T).
concsort([H1|T1],[H2|T2],[H2|T]):-
concsort([H1|T1],T2,T).
Так как мы заранее не знаем, какой из списков L1, L2 кончится раньше, то необходимо иметь два граничных условия:
concsort([],L,L).
concsort(L,[],L).
/* Программа 7.3 «очень быстрая сортировка». */
domains
list=integer*
predicates
% очень быстрая сортировка
supersort1(list,list)
% разделение на два примерно равных списка
div2(list,list,list)
% соединение двух отсортированных списков
concsort(list,list,list)
goal
supersort1([1,7,95,1,9,3],L),write(L),nl.
clauses
supersort1([],[]).
supersort1([X],[X]).
supersort1(L,S):-
div2(L,L1,L2),
supersort1(L1,S1),
supersort1(L2,S2),
concsort(S1,S2,S).
div2([],[],[]).
div2([X],[X],[]).
div2([X,Y|L],[X|L1],[Y|L2]):-
div2(L,L1,L2).
concsort([],L,L).
concsort(L,[],L).
concsort([H1|T1],[H2|T2],[H1|T]):-
H1<=H2,!,
concsort(T1,[H2|T2],T).
concsort([H1|T1],[H2|T2],[H2|T]):-
concsort([H1|T1],T2,T).
/* Конец программы */
Упражнение 7.1.
Напишите сортировку методом «пузырька», согласно следующему алгоритму:
% рекурсивное правило bubble:
1. Переставляем первую неупорядоченную пару элементов.
2. Сортируем пузырьком получившийся переставленный список.
% граничное условие bubble:
3. Если такой пары нет (процедура перестановки change дала отказ), значит, исходный список уже отсортирован.
Перестановку двух элементов списка осуществит рекурсивная процедура change:
1. Если первые два элемента списка неупорядочены, то переставляем их.
2. Иначе пропускаем первый элемент и вызываем change для хвоста списка.
