Логическое программирование

Списки


Для представления списков произвольной длины используется специальная рекурсивная структура “./2” . Первый аргумент - терм любого вида; второй аргумент - другая структура “./2” или пустой список,   обозначаемый [].

Список из одного элемента - атома a:

 .(a,[]),

список из трех элементов a, b и c:

 .(a,.(b,.(c,[]))).

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

[a]

[a,b,c]

[[a,b],[a,b,c],[]]

Представление списков произвольной длины ³ 2:

.(one,.(two,X))

[one,two|X]

Символ "|" разделяет список на две части: начало списка и остаток списка; если начало списка состоит из одного элемента, то части называются голова списка и хвост списка. Если H - голова списка, а T - хвост, то список представляется термом [H|T].



Примеры унификации списков:     

Список 1

Список 2

Конкретизация переменных

[X,Y,Z]

[‘орел’,’курица’,’утка’]

X=‘орел’, Y=‘ курица’,

Z= ‘утка’

[7]

[X|Y]

X=7, Y=[]

[1,2,3,4]

[X,Y|Z]

X=1, Y=2, Z=[3,4]

[1,2]

[3|X]

нет унификации

[1|[2]]

[X|Y]

X=1, Y=[2]

Некоторые предикаты со списками

 

member(?Elem, ?List)

    Отношение выполнено, когда  Elem может быть унифицирован с одним из членов списка List.

member(A, [A|B]).

member(A, [B|C]) :-

        member(A, C).

?- member(1,[3,4,1]).

Yes

?- member(1,[[1]]).

No

?- member(X,[a,b,[c,d],[]]).

X = a ;

X = b ;

X = [c,d] ;

X = [] ;

No

?- member(5,[X,Y|Z]).

X = 5

Y = G772

Z = G776 ;

X = G760

Y = 5

Z = G776 ;

X = G760

Y = G772

Z = [5|G1240]

Yes

append(?List1, ?List2, ?List3)

    Отношение выполнено, когда список List3 унифицируется с конкатенацией списков List1 и List2.

append([], A, A).

append([A|B], C, [A|D]) :-

        append(B, C, D).

?- append([a,b],[c,d],[a,b,c,d]).

Yes

?- append([a,b],[c,d],[a,b,a,c,d]).

No

?- append([8,7,6],[1,2,3],L).

L = [8,7,6,1,2,3]

Yes

Предикат append позволяет также расщеплять список на два подсписка.


?- append(L1,L2,[a,b,c]).

L2 = [a,b,c]

L1 = [] ;

L2 = [b,c]

L1 = [a] ;

L2 = [c]

L1 = [a,b] ;

L2 = []

L1 = [a,b,c] ;

No

?- append(L1,[a,b],[c,a,b]).

L1 = [c]

Yes

?- append(L1,[a,b],L3).

L3 = [a,b]

L1 = [] ;

L3 = [G1292,a,b]

L1 = [G1292]

Yes

?- append(L1,L2,L3).

L2 = G740

L3 = G740

L1 = [] ;

L2 = G740

L3 = [G1112|G740]

L1 = [G1112]

Yes

Новое определение member

member1(X,L):-

         append(_,[X|_],L).

Это определение имеет очевидный декларативный смысл.

Добавить элемент спереди к списку

‘добавить’(X,L,[X|L]).

select(?List1, ?Elem, ?List2)

    Селектирует элемент списка List1, который унифицируется с Elem.  List2 унифицируется со списком, получаемым  из List1 после удаления выбранного элемента. Обычно используется шаблон +List1, -Elem, -List2, но может также использоваться для вставки элемента в список по шаблону

-List1, +Elem, +List2.

select([A|B], A, B).

select([A|B], C, [A|D]) :-

        select(B, C, D).

?- select([a,b,c],X,Y).

X = a

Y = [b,c] ;

X = b

Y = [a,c] ;

X = c

Y = [a,b] ;

No

?- select([a,b,c],b,X).

X = [a,c]

Yes

?- select(X,a,[b,c,d]).

X = [a,b,c,d] ;

X = [b,a,c,d] ;

X = [b,c,a,d] ;

X = [b,c,d,a] ;

No

 

Еще один вариант member

member2(X,L):-

       select(L,X,_).

delete(+List1, ?Elem, ?List2)

    Удаляет все элементы списка List1, что унифицируются с Elem и одновременно унифицирует результат с List2.

?- delete([a,b,a,c,a],a,X).

X = [b,c] ;

No


Содержание раздела