Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛабПрактикум(1-5)_ПЗ в ИС_2011 .doc
Скачиваний:
27
Добавлен:
19.11.2019
Размер:
1.56 Mб
Скачать

Практикум 4-3

В программе из Практикума 4-1, посчитать количество увлечений у каждого студента

Проверка принадлежности элемента списку

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

Построим данный предикат, опираясь на тот факт, что объект принадлежит списку, если он либо является первым элементом списка, либо элементом хвоста. Это может быть записано в виде двух предложений:

Рис. 4.6. Проверка вхождения элемента в список

Первое правило описывает ситуацию, когда элемент Х совпадает с головой списка.

Второе правило используется при неуспехе первого правила и описывает новый вызов первого правила, но уже с усеченным списком, в котором нет первого элемента и т.д. Если в списке заканчиваются элементы, остается пустой список, то второе правило оказывается неуспешным и процесс поиска заканчивается с результатом «ложь» (элемент не является членом списка).

Практикум 4-4

Добавьте в задачу об увлечениях студентов из Практикума 4-1 факты.

Используя предикаты member и findall, получите список студентов, увлекающихся лыжами

Слияние двух списков

Пусть L1 и L2 – две переменные, представляющие входные списки. L3 – выходной список, получаемый слиянием L1 и L2.

Рис. 4.7. Программа слияния двух списков

Первое правило этой процедуры выполняется, когда первый список пустой, второе работает в остальных случаях.

Рассмотрим использование этого предиката при следующем вызове:

conc ([1,2,3], [4,5],_).

Здесь первое правило сначала не работает, так как первый список не пустой.

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

conc ([ ],[4,5],_).

После этого срабатывает первое правило, и третий список инициализируется вторым:

conc ([ ],[4,5], [4,5]).

И, наконец, чтобы завершить рекурсивные вызовы, Пролог извлекает из стека (в обратном порядке) элементы первого списка и возвращает их, в соответствии с описанием второго варианта правила, в списки 1 и 3:

conc ([1,2,3], [4,5],[1,2,3,4,5]).

Программу для conc можно применить "в обратном направлении" - для разбиения списка на две части. Например, для цели:

Goal

conc(L1,L2,[a,b,c]).

получим результаты:

L1=[]

L2=[a,b,c]

L1=[a]

L2=[b,c]

L1=[a,b]

L2=[c]

L1=[a,b,c]

L2=[]

Практикум 4-5

1.Проверьте работу приведенной выше программы слияния двух списков с целями:

а) conc ([1,2,3], [4,5], X).

б) conc (X, [4,5], [1,2,3,4,5]).

2.Напишите программу, удаляющую из списка последние два элемента и формирующую новый список. Воспользуйтесь предикатом conc .

3.Напишите программу, удаляющую из списка первый и последний элемент.

Используя conc можно определить отношение принадлежности member следующим эквивалентным способом:

member (X,L) :- conc (_,[X|_],L).