Рассмотрим простой и очень полезный предикат 'присоединить'. Его основное назначение - соединить два списка в один. Согласование с базой знаний целевого утверждения 'присоединить'(X,Y,Z) должно заканчиваться удачей в том случае, когда Z представляет собой соединение двух списков X и Y. Например, следующее целевое утверждение является истинным:
? - 'присоединить'([a,b,c],[3,2,1],[a,b,c,3,2,1]).
yes
а целевое утверждение
? - 'присоединить'([а,в,с],[3,2,1],Z),write(Z).
позволяет получить новый список Z=[a,b,c,3,2,1] в результате объединения двух исходных списков [a,b,c] и [3,2,1].
Кроме основного назначения существует еще множество других применений этого предиката, например, таких как разделение списка, всеми возможными способами, удаление начального или остаточного сегмента списка, разделение списка по заданному элементу.
Чтобы разработать предикат для некоторого отношения, нужно составить утверждения базы знаний, совокупность которых полностью описывает это отношение. На практике при определении отношения над списками нужно поступать следующим образом: выбрав один из аргументов этого отношения, составить высказывания относительно различных вариантов этого аргумента. Эти варианты должны покрывать все различные виды списков, которые могут появляться в качестве данного аргумента этого отношения.
Для отношения 'присоединить'(Х,Y,Z) выберем первый аргумент Х. Полностью определим это отношение, задав одно утверждение для всех случаев, когда Х пустой список [], и второе - для всех случаев, когда Х непустой список, представленный шаблоном [Х1|L1].
Когда Х=[], Y и Z всегда совпадают. Любой список, присоединенный к пустому списку, дает тот же самый список. Это можно представить с помощью следующего факта.
'присоединить'([],Y,Y). (1)
Смысл второго утверждения:
'присоединить'([Х1|L1],Y,[Х1|L3]):-'присоединить'(L1,Y,L3). (2)
можно описать словами следующим образом:
Первый элемент Х1 первого списка Х всегда будет и первым элементом третьего списка, т.е. если Х=[Х1|L1], то Z=[Х1|L3].
Хвост L3 третьего аргумента Z всегда будет представлять результат присоединения второго аргумента Y к хвосту L1 первого списка Х. Для выполнения этой операции присоединения Y к L1 необходимо использовать предикат 'присоединить'.
Так как при каждом обращении к правилу удаляется голова списка, являющегося первым аргументом, то постепенно этот список будет исчерпан и станет пустым, так что произойдет выход на первое граничное условие.
Таким образом, утверждения
'присоединить'([],Y,Y).
'присоединить'([Х1|L1],Y,[Х1|L3]):- 'присоединить'(L1,Y,L3).
полностью определяют отношение 'присоединить' и представляют логическую программу для данного отношения.
|