Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
учебное_пособие_флп.doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
675.84 Кб
Скачать

6.2.Предикат findall

findall(Variable,<предикат>,ListVariable) - записывает значение объекта Variable в список ListVariable. Variable должен являться одним из аргументов указанного предиката.

Рекурсивная процедура хранит память о промежуточных результатах по мере выполнения программы, так как она передает информацию через параметры от одного рекурсивного вызова к другому. Но рекурсия не может осуществить поиск всех альтернативных решений в цели, который обычно выполняет поиск с возвратом. Поэтому, когда вам нужны все решения для целевого утверждения, и они необходимы все сразу, как часть единой составной структуры, то вы будете использовать встроенный предикат findall. Этот предикат использует целевое утверждение в качестве одного из своих аргументов и собирает все решения для этого целевого утверждения в единый список методом поиска с возвратом.

Листинг 6.2.1. использование предиката findall

/*Пусть есть БД – группа студентов, есть отметки, полученные студентом на экзамене по ФЛП Найти средний балл по указанной группе*/

domains

name=string

mark=integer

list=mark* % список оценок

predicates

student(name,mark) % предикат БД

sum_list(list,mark,integer) % сумма всех оценок в списке по ФЛП

report_average_student_mark %средний балл

goal

report_average_student_mark.

clauses

student(“Орлов”,4).

student(“Абрамов”,3).

student(“Смирнов”,5).

report_average_student_mark:-

findall(Mark,student(_,Mark),Mark_list),

sum_list(Mark_list,Sum,Number),

Average=Sum/Number,

write(“Группа студентов по дисциплине имеет:”),nl,

write(“Средний балл=”,Average).

sum_list([],0,0).

sum_list([H|T],Sum,Number):-

sum_list(T,Sum1,Number1),

Sum=H+Sum1,

Number=Number1+1.

6.3. Операции со структурами данных.

Сортировка списков

Список может быть упорядочен (отсортирован), если между его элементами определено отношение порядка.

Отношение порядка – больше(x,y)

ask_order(X,Y):-

X>Y (для чисел)

Если элементы списка – атомы, то отношение “больше”

соответствует алфавитному порядку.

В качестве примера приведем программу, реализующую быструю сортировку.

Метод быстрой сортировки (quick_sort)

Идея: 1 Удалить из списка L какой-либо элемент X и разбить оставшуюся часть на два списка- Smaller и Larger

2 разбиение(деление) списка производить следующим образом: все элементы>X принадлежат списку Larger,остальные- списку Smaller

3 Отсортировать список Smaller и результат – список Sort_Smaller

4 Отсортировать список Larger и результат – список Sort_larger

5 Получить результирующий упорядоченный список как конкатенацию списков Sort_Smaller и [X|Sort_Larger].

[5,2,4,8,9,3,7] --исходный список

/ --удаляем X=5( обычно голова списка)

[2,4,8,9,3,7]

/ \ --деление списка по признаку-<=5 >5

[2,4,3] [8,9,7]

/ \ ---сортировка

[2,3,4] [7,8,9]

\ / ---конкатенация с добавлением X

[2,3,4,5,7,8,9] ---отсортированный список

Время выполнения сортировки зависит от того, насколько повезет при разбиении сортируемого списка. Если оба разбиваемых списка примерно одинаковой длины, то время выполнения порядка n*log n,где n-длина исходного списка

Если один из списков значительно длиннее другого, то время выполнения порядка n2 (как и при сортировке со вставками- с ростом n время растет пропорционально n2.)

Анализ показывает, что чаще произведенная сортировка оказывается ближе к лучшему случаю.

Листинг 6.3.3. быстрая сортировка

trace

domains

number=integer

list=number*+

predicates

quick_sort(list,list)

split(list,number,list,list)

append(list,list,list)

clauses

quick_sort([],[]).

quick_sort([X|Tail],Sort_list):-

split(Tail,X,Little_list,Large_list),

quick_sort(Little_list,Sort_little_list),

quick_sort(Large_list,Sort_large_list),

append(Sort_little_list,[X|Sort_large_list],Sort_list).

split([],_,[],[]).

split([X|Tail],Y,[X|Sort_little_list],Sort_large_list):-

X<=Y,

split(Tail,Y,Sort_little_list,Sort_large_list).

split([X|Tail],Y,Sort_little_list,[X|Sort_large_list]):-

X>Y,

split(Tail,Y,Sort_little_list,Sort_large_list).

append([],L,L).

append([X|L1],L2,[X|L3]):-

append(L1,L2,L3).

Список литературы

1. Адаменко А, Кучумов А. Логическое программирование и Visual prolog: руководство в подлиннике – СПб.: БХВ-Петербург,2003 -993с.

2.Стерлинг Л.,Шапиро Э. Искусство программирования на языке Пролог:Пер с анг.-М.:Мир,1990. -235с.

3.Братко И. Алгоритмы искусственного интеллекта на языке Prolog,3-е издание.:пер. с англ. – М.:Издательский дом “Вильямс”, 2004. – 640с.

4.Хювёнен Э.,Сеппянен Й. Мир Лиспа.В 2-х т. Т1:Введение в язык Лисп и функциональное программирование. Пер. с финск. – М.: Мир, 1990. -447c.

5.Душкин Р.В.Функциональное программирование на языке Haskell.-М.:ДМК Пресс,2007. -608с.

94