Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Teacher(symbol,symbol,symbol)

Поиск

Clauses

Teacher(ed,willis,english1).

Teacher(ed,willis,math1).

Teacher(ed,willis,hystory).

Teacher(mary,marker,english2).

Teacher(mary,marker,math2).

Teacher(mary,marker,geometry).

Тут возникает необходимость повторять имена профессоров для каждого предмета. Это трудоёмко, поэтому лучше всего использовать тип списка. В следующем примере аргумент classes описан как тип списка.

Domains

classes = symbol*

Predicates

Teacher(symbol,symbol,classes)

Clauses

teacher(ed,wills,[english1,math1,hystory]).

teacher(mary,marker,[english2,math2,geometry]).

В этом примере отметим описание раздела domains:

Domains

classes = symbol*.

Здесь демонстрируется, как описываются в Прологе списки. Символ (*) означает, что аргумент classes является символьным списком. Аналогично можно описать список целочисленных данных:

Domains

integer_list = integer*.

Элементами списка могут быть самые разные данные, даже другие списки. Все элементы должны принадлежать одной области. Описание областей для элементов должно иметь следующую форму:

Domains

elementlist = elements*

elements = integer

Список – это рекурсивная структура, которая состоит из головы и хвоста. Головой называют первый элемент списка, а хвост – это все остальные элементы. Хвост списка всегда будет списком, а голова – это один элемент. Отметим, что пустой список не возможно разделить на голову и хвост. Обозначается пустой список как [].

Концептуально списки имеют структуру дерева. Например, список [a,b,c,d] можно представить следующим образом:

List

 
 


A list

B list

c list

d []

А одноэлементный список [а] имеет вид:

List

 
 


a []

Пролог даёт возможность явно задавать голову и хвост списка. Вместо отделения элементов запятыми, можно выделить голову и хвост знаком «|». Например, список [a,b,c] равен списку [a | [b,c]] [a | [b | [c | []]]].

Разделители можно также комбинировать. Так список [a,b,c,d] можно задать следующим образом [a,b | [c,d]].

Для обработки списков лучше всего подходят рекурсивные алгоритмы. Обработка списка состоит из рекурсивного смещения и обработки головы списка до тех пор, пока список не станет пустым. Алгоритм такого типа традиционно состоит из двух фраз. Первая из них говорит, что необходимо делать со списком, а вторая – что делать с пустым списком.

Обеспечить печать элементов списка можно следующим образом:

Domains

list = integer* % или любой другой тип, который хотите использовать

Predicates

write_a_list(list)

Clauses

write_a_list([]). % если список пуст, то ничего не делать.

write_a_list([H | T]):- /* отделяем голову списка Н (Head) и хвост Т(Tail), затем печатаем Н и рекурсивно обрабатываем Т */

Write(H),nl,

write_a_list(T).

Если задать цель: write_a_list([1,2,3]), то список [1,2,3] будет разбит на голову Н=1 и хвост Т = [2,3]. Предикатом write(H) напечатается голова, и рекурсивно будет обрабатываться предикатом write_a_list(T) хвост [2,3]. Процесс завершится, когда хвост станет пустым списком.

Используя тот же рекурсивный принцип, можно выявить, принадлежит ли данный элемент заданному списку. Пусть предикат, выясняющий данный факт, будет иметь вид:

Member(name, namelist)

В следующей программе первая фраза исследует голову списка. Если голова списка совпадает с именем элемента, которое мы ищем, тогда можно сделать вывод, что имя принадлежит списку. Так как в данном случае хвост списка нас не интересует, то он характеризуется анонимной переменной. Если же имени нет в голове, то его необходимо рекурсивным образом поискать в хвосте списка. За это и отвечает вторая фраза программы.

is_a_member_of(Name,[Name|_]).

is_a_member_of(Name,[_|Tail]):- is_a_member_of(Name,Tail).

Существуют и другие полезные рекурсивные процедуры обработки списков:

Является ли списком:

 

list([]):-!.

list([H|T]):-

list(T).

Объединение двух списков:

append([],L,L).

append([H|T],L,[H|T1]):-

append(T,L,T1).

Разбиение списка на два: c положительными и отрицательными элементами:

split([],[],[]):-!.

split([H|T],[H|T1],L):-

H>=0,!,

split(T,T1,L).

split([H|T],L,[H|T1]):-

split(T,L,T1).

Соединениедвух списков [a1,a2,a3,...] и [b1,b2,b3,...] по правилу [a1,b1,a2,b2,a3,b3,...]:

app([],L,L).

app(L,[],L).

app([H1|T1],[H2|T2],[H1,H2|T]):-

app[T1,T2,T).

Число элементов в списке:

number([],0).

number([H|T],N):- number(T,M), N=M+1.

Удаление первого вхождения элемента в список:

del1(X,[X|Y],Y):-!.

del1(X,[Z|Y],[Z|W]):- del1(X,Y,W).

Удаление всех вхождений элемента в список:

del_all(X,[],[]).

del_all(X,[X|Y],W):- del_all(X,Y,W).

del_all(X,[Z|Y],W):- del_all(X,Y,W).

Индексация элементов списка (получить элемент под номером N или узнать номер элемента X):

get([X|Y],1,X).

get([W|Y],N,X):- N=M+1, get(Y,M,X).

Поиск максимального элемента в списке:

max([X],X).

max([X|Y],X):- max(Y,W), X>W,!.

max([X|Y],W):- max(Y,W).

Обращение списка:

revers([X],[X]).

revers([X|Y],Z):- revers(Y,W), app(W,[X],Z).

 

ПРАКТИЧЕСКИЕ ЗАДАНИЯ

2. Определить два предиката чётнаядлина(Список) и нечётнаядлина(Список) таким образом, чтобы они были истинными, если их аргументом является список четной и нечётной длины соответственно.

3. Определить отношение перевод(Список1,Список2) для модификации списка чисел от 0 до 9 в список соответствующих слов. Например, перевод([3,1,7],[три,один,семь]).

4. Напишите предикат палиндром(Список). Список называется палиндромом, если он читается одинаково как справа налево, так и слева направо. Например, [м,а,д,а,м].

5. Индивидуальное задание. Напишите программу согласно своему варианту.

1) Написать программу на Прологе, при использовании которой из предложенного списка англоязычных слов пользователь смог бы выбрать одно из них и получить его русский эквивалент.

2) Написать программу, которая объединяет два списка в один, упорядочивает полученный список и находит произведение его первого и последнего элементов.

3) Обратить два имеющихся списка, объединить их и найти среднее арифметическое значение элементов.

4) Написать программу, которая объединяет два списка и обращает полученный список.

5) Написать программу, которая находит разность между максимальным и минимальным элементами списка, являющегося обращенным по отношению к заданному.

6) Написать программу на Прологе, которая находит среднее арифметическое между максимальным и минимальным элементами двух объединенных списков.

7) В данном списке, полученном путем обращения исходного, найти максимальный элемент, удалить из списка его первое вхождение, а остальные элементы, равные максимальному, уменьшить на величину n, где n – позиция соответствующего элемента в списке.

8) Дан некоторый список чисел. Получить новый список, который состоит из элементов, превышающих соответствующие элементы исходного списка в 5 раз. Получить среднее арифметическое элементов исходного списка и сумму элементов результирующего списка.

9) Упорядочить два объединенных исходных списка. Найти число элементов полученного списка. Если это число нечетное, то вывести элемент, являющийся центральным в данном списке, если же число элементов четное, то вывести два центральных элемента.

10) Написать программу, которая позволяет получить новый список путем объединения двух исходных списков, далее разделяет его на два других, первый из которых содержит нечетные элементы, а второй – четные.

11) Объедините два списка, найдите среднее арифметическое между максимальным и минимальным элементами списка. Удалите из списка те элементы, которые делятся без остатка на целую часть от полученного среднего арифметического.

12) Обратите введенный пользователем список и упорядочите его. Найдите среднее арифметическое тех элементов списка, которые делятся на 4.

13) Написать программу, которая находит разность между максимальным и минимальным элементами списка и удаляет все элементы из данного списка, равные этой разности.

14) Даны два списка: первый – список чисел от 1 до 33, а второй – это список букв русского алфавита. После того, как пользователь задаст какой-либо список из чисел в пределах от 1 до 33, на экран должен быть выведен соответствующих этим числам список букв. Подсчитать длину полученного в итоге списка.

15) Обеспечить ввод двух исходных списков. Упорядочить каждый из введённых списков. Найти максимальные и минимальные элементы в этих списках. Объединить списки и заменить элементы, равные максимальному элементу из первого списка, на сумму максимального и минимального элементов второго списка, а элементы, равные минимальному элементу второго списка, на разность максимального и минимального элементов первого списка.

16) Написать программу, объединяющую два исходных списка в один, удаляющую из полученного списка все элементы, равные максимальному, и заменяющую элементы, равные минимальному, их порядковыми номерами.

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

18) Объединить два заданных списка. Из полученного списка удалить все чётные элементы.

19) Объединить два исходных списка. Заменить все четные элементы списка величиной (ai+maxнечет), а нечетные элементы величиной (ai+minчет), где ai – i-ый элемент списка, maxнечет – максимальный элемент среди нечетных элементов списка, minчет – минимальный элемент среди четных элементов списка.

20) Написать программу, умножающую все элементы исходного списка на величину минимального элемента и разделяющую полученный список на три других таким образом, чтобы первый из них содержал четные элементы, второй – элементы, делящиеся на три без остатка, третий – все остальные элементы.

21) Найти среднее арифметическое между минимальным элементом заданного списка и произведением всех элементов этого списка. Удалите из списка все элементы, равные целой части полученного числа.

22) Написать программу, обращающую заданный пользователем список. Из списка удалить все элементы, кратные 2, оставляя те элементы, которые делятся на 6.

23) В исходном списке найти минимальный и максимальный элементы. Вывести результат на экран. Далее, при поэлементном выводе списка на экран, вместо элементов, равных максимальному или минимальному элементу, должна выводиться информация: «максимальный элемент» или «минимальный элемент» соответственно.

24) Написать программу, которая позволяет объединить два исходных списка, обратить полученный список и заменить все четные элементы величиной (max-min)*n, где max – максимальный элемент списка, min – минимальный элемент списка, n – порядковый номер соответствующего элемента в списке.

 

КОНТРОЛЬНЫЕ ВОПРОСЫ

6. Что такое список в Прологе?

7. Как задаётся список на Прологе?

8. Объясните принцип разделения списка на голову и хвост.

9. Как представить список в виде дерева? Приведите пример.

10. Объясните алгоритм печати элементов списка.

11. Объясните алгоритм проверки принадлежности элемента списку.

12. Объясните алгоритм печати элементов списка.

13. Объясните алгоритм добавления элементов в список.

14. Объясните алгоритм подсчёта длины списка.

15. Как работать с процедурой индексации элементов списка?

 

 

ЛАБОРАТОРНАЯ РАБОТА №6

Тема: Файловая система Visual Prolog. Строки в Visual Prolog.

Цель: Научиться использовать возможности Visual Prolog по организации работы со строками и файловой системой.

 

ТЕОРЕТИЧЕСКАЯ ЧАСТЬ



Поделиться:


Последнее изменение этой страницы: 2016-12-30; просмотров: 454; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.221.161.43 (0.009 с.)