Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по СИИ.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
424.24 Кб
Скачать

2) Добавление элемента.

Цель: добавить(X,L,SP)

Наиболее простой способ добавить элемент в список – это поставить его в самое начало так, чтобы он стал его новой головой.

добавить(X,L,[X|L]), где Х – новый элемент, L – исходный список, SP=[X|L] – результирующий список.

3) Удаление элемента.

Предикат удалить(X,L,NL) определяется аналогично отношению принадлежности.

Здесь NL – список, который совпадает со списком L, у которого удалён элемент X.

Снова имеем два случая:

1) Если Х является головой списка, тогда результатом удаления будет хвост этого списка.

2) Если X находится в хвосте списка, тогда его нужно удалить оттуда.

На Прологе:

удалить(Х,[X|Hvost],Hvost).

удалить(X,[Y|Hvost],[Y|Hvost1]) :- удалить(X,Hvost,Hvost1).

В случае, если элемента Х нет в списке L, то предикат удалить терпит неуспех.

Вопрос: как использовать предикат удалить для того, чтобы добавлять элементы в список?

Элемент “a” добавить в список [b,c,d].

? удалить (a,L,[b,c,d])

Т.е. мы спрашиваем у Пролог-системы, каким должен был быть список L, чтобы после удаления из него элемента “a” получился список [b,c,d].

Вопрос: как использовать предикат удалить для проверки на принадлежность?

Идея: некоторый X принадлежит списку SP, если X можно из него удалить, т.е.:

принадлежит1(X,SP) :- удалить(X,SP,_).

В данном случае NSP не нужен. Мы его заменяем на “_”.

4) Сцепление (конкатенация) списков.

Определим отношение:

конк(L1,L2,L3), где L1 и L2 – два списка, а L3 – список, получаемый при их сцеплении.

Например: конк([a,b], [c,d], [a,b,c,d]) истинно,

конк([a,b], [c,d], [a,b,a,c,d]) ложно,

конк([a,b], [c,d], [a,b,d,c]) ложно.

Нам придётся рассмотреть два случая в зависимости от вида первого аргумента L1.

1) Если первый аргумент пуст, тогда второй и третий аргументы представляют собой один и тот же список.

На Прологе: конк([ ], L, L).

2) Если первый аргумент отношения «конк» не пуст, то он имеет голову и хвост и выглядит так: [G|Hvost1].

Рассмотрим графически, как происходит сцепление списка [G|Hvost1] с произвольным списком L2.

G

Hvost1

L2

G

Hvost3

Hvost1=L1=[G|Hvost1],

L2=L2

Hvost3=L3=[G|Hvost3], где Hvost3 получен путём сцепления Hvost1 и L2.

На Прологе: конк([G,Hvost1], L2, [G|Hvost3]) :- конк(Hvost1, L2, Hvost3).

Отношение «конк» можно использовать в обратную сторону, т.е. для разбиения заданного списка на две части.

Например, если задать Пролог-системе вопрос: ?конк(L1,L2,[a,b,c]),

то Пролог-система выдаст последовательно все варианты разбиения:

L1=[ ] | L1=[a] | L1=[a,b] | L1=[a,b,c]

L2=[a,b,c] | L2=[b,c] | L2=[c] | L2=[ ]

Также, отношение конк можно использовать для поиска в списке комбинации элементов, отвечающей некоторому условию, задаваемому в виде шаблона или образца.

Например, можно найти все месяцы, предшествующие данному, и все месяцы, следующие за ним, сформулировав цель:

?конк(Do, [“май” | Posle], [“янв”, “февр”, “март”, “апр”, “май”, “июнь”, “июль”, “авг”, “сент”, “окт”, “нояб”, “дек”]).

Ответ: Do=[“янв”, “февр”, “март”, “апр”]

Posle=[“июнь”, “июль”, “авг”, “сент”, “окт”, “нояб”, “дек”]

Вопрос: что мы узнаём, задав вопрос:

?конк( _, [M1, “май”, M2 | _], [“янв”, “февр”, “март” …“дек” ].

Ответ: мы узнаём месяц, непосредственно предшествующий маю и следующий за маем.

М1=”апрель”

М2=”июнь”.

Вопрос: удалить из списка L1 всё, что следует за тремя последовательными вхождениями элемента Z в L1 вместе с этими тремя Z.

? L1=[a,b,z,z,c,[z,z,z|d,e],

конк(L2,[z,z,z| _ ], L1).

Ответ: L1=[a,b,z,z,c,z,z,z,d,e]

L2=[a,b,z,z,c]

С помощью отношения “конк” можно также определить отношение принадлежности

принадлежит2(X,L) :- конк(L1,[X|L2],L).

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

Задание:

1) Используя отношение “конк”, напишите цель, соответствующую вычёркиванию трёх последних элементов списка L. Результат – новый список L1

Ответ: конк(L1,[ _, _, _], L).

2) Напишите последовательность целей для нахождения списка L2, получающегося из списка L вычёркиванием его трёх первых и трёх последних элементов.

Ответ: 1 вариант: конк([ _, _, _],L1, L),

конк([ _, _, _], L1).

2 вариант: конк([ _, _, _],L2),[ _, _, _], L).

3) Определить отношение последний(EL, SP) так, чтобы элемент EL являлся последним элементом списка SP.

Ответ: 1 вариант: последний(EL, SP) :- конк( _ , [EL], SP).

2 вариант: последний(EL, [First|Ost]) :- последний(EL, Ost).