Аргументы L1,L2,L3 обозначают списки, Е - некоторый элемент списка (тип элементов списка произволен), N - порядковый номер элемента в списке.
1. append (L1, L2, L3): список L3 является слиянием (конкатенацией) списков L1 и L2;
2. reverse (L1, L2): L2 - перевернутый список L1;
3. delete_first (E, L1, L2): список L2 получен из L1 исключением первого вхождения объекта Е;
4. delete_all (E, L1, L2): L2 - это список L1, из которого удалены все вхождения Е;
5. delete_one (E, L1, L2): L2 - список L1, в котором исключен один элемент Е (исключается какое-то одно вхождение Е в список L1);
6. no_doubles (L1, L2): L2 - это список, являющийся результатом удаления из L1 всех повторяющихся элементов;
7. sublist (L1, L2): L1 - любой подсписок списка L2, т.е. непустой отрезок из подряд идущих элементов L2;
8. number (E, N, L): N - порядковый номер элемента E в списке L;
9. sort (L1, L2): L2 - отсортированный по неубыванию список чисел из L1.
Исходный код:
domains
ilist=integer*
predicates
append(ilist,ilist,ilist).
reverse(ilist,ilist).
delete_first(integer,ilist,ilist).
delete_all(integer,ilist,ilist).
member(integer,ilist).
no_doubles(ilist,ilist).
sublist(ilist,ilist).
all_sublists(ilist).
number(integer,ilist,integer).
n(integer,ilist,integer,integer).
sort(ilist,ilist).
insert(integer,ilist,ilist).
clauses
%append
append([],B,B). %esli pervii spisok pustoi, to rezultat - vtoroi spisok
append([H|Tail],B,[H|NewTail]):-append(Tail,B,NewTail). %esli ne pustoi, to rekursivno soedinyaem
%hvost pervogo spiska so vtorim spiskom i poluchaem tem samim hvost itogovogo spiska
%reverse
reverse([],[]). %esli spisok pustoi, to otvet takze pustoi spisok
reverse([H|Tail],Ans):-reverse(Tail,RTail),append(RTail,[H],Ans).%esli ne pustoi, to rekursivno perevorachivaem
%hvost etogogo spiska, i slivaem etot perevernutii hvost so spiskom, sostoyashim iz golovi nachalnogo spiska
%delete_first
delete_first(_,[],[]). %kakoi-bi element ni udalyalsya, esli spisok pustoi, to rezultatom budet pustoi spisok
delete_first(E,[E|Tail],Tail):-!. %esli pervii element spiska - iskomii, to otvetom budet hvost spiska.
%I vipolnayem otsechenie, chtobi ne bilo popitok vipolnit tretie pravilo, esli vipolnilos vtoroe
delete_first(E,[H|Tail],[H|NewTail]):-delete_first(E,Tail,NewTail).%iz-za otsecheniya syuda popadaem
%tolko esli pervii element ne raven iskomomu, togda on ostaetsya na meste, i rekursivno vizivaetsya poisk v hvoste
%delete_all
delete_all(_,[],[]). %pervoe i tretie pravilo takie ze, kak i v predidushem predikate
delete_all(E,[E|Tail],NewTail):-!,delete_all(E,Tail,NewTail).%esli pervii element spiska iskomii,
%to vse to ze samoe, chto i v predidushem predikate, tolko eshe rekursivno prosmatrivaem hvost
delete_all(E,[H|Tail],[H|NewTail]):-delete_all(E,Tail,NewTail).
%no_doubles
%vspomogatelnii predikat member(E,L), proveryayushii prinadlezit li element E spisku L
member(H,[H|_]). %esli element raven golove spiska, to rezultat polozitelnii
member(X,[_|Tail]):-member(X,Tail). %esli element vstrechaetsya v hvoste spiska, to rezultat polozitelnii
no_doubles([],[]).%esli spisok pustoi, to otvet takze pustoi spisok
no_doubles([H|Tail],NewTail):-no_doubles(Tail,NewTail),member(H,NewTail),!.%rekursivno obrabativaem hvost,
%dalee proveryaem vstrechaetsya li pervii element spiska v rezultate obrabotki hvosta.
%Esli vstrechaetsya, to ego v otvet pomeshat ne nado. Ispolzuem otsechenie, chtobi esli pervii element vstrechaetsya
%v novom hvoste, to ne vipolnyalos bi tretie pravilo
no_doubles([H|Tail],[H|NewTail]):-no_doubles(Tail,NewTail).%esli ze element ne vstrchaetsya,to ostavlayem ego vmeste s novim hvostom
%sublist
sublist(_,[]).%podspiskom lyubogo spiska yavlyaetsya pustoi spisok
sublist(A,B):-append(Begin,_,A),append(_,B,Begin),not(B=[]).%pri pomoshi append vibiraetsya
%proizvolnaya gjdposledovatelnost spiska. Proverka, chtobi B<>[] proizvoditsya potomu chto
%esli bi eto ne proizvodilos, to takoi otvet bi nahodilsya neskolko raz. Poetomu on prosto
%vinesen v otdelnoe pravilo, chtobi vivestis tolko raz
%vspomogatelnii predikat, chtobi vivesti vse podspiski
all_sublists(A):-sublist(A,B),write(B),nl,fail.%nahodim podspisok, vivodim ego, i zavershaem predikat neudachei,
%chtobi iskalis drugie
all_sublists(_).%posle togo, kak naidutsya vse podspiski, predikat zavershitsya udachno
%number
%vspomogatelnii predicat, trerii parametr - nomer tekushego elementa
n(E,[E|_],N,N).%esli pervii element tekushego podspiska iskomii, to otvetom yavlyaetsya nomer tekushego elementa, te trerii parametr
n(E,[_|Tail],I,N):-I1=I+1,n(E,Tail,I1,N).%ili perehodim k poisku v hvoste, uvelichiv na 1 nomer tekushego elementa
number(E,L,N):-n(E,L,1,N).%vizivaem vspomogatelnii predicat, zadav nomer tekushego elementa ravnim 1
%sort
%sortirovka proizvoditsya metodom vstavki
%insert - vspomogatelnii predicat, vstavlyayushii element v otsortirovannii spisok na nuznoe mesto
insert(E,[],[E]).%esli spisok pust, to otvetom budet spisok iz odnogo elementa
insert(E,[H|Tail],[E,H|Tail]):-E<=H,!.%esli vstavlyaemii elelment menshe pervogo elementa spiska, to on stavitsya na pervoe mesto
insert(E,[H|Tail],[H|NewTail]):-insert(E,Tail,NewTail).%syuda popadaem tolko esli vstavlyaemii predicat bolshe
%pervogo elementa spiska. Togda rekursivno vstavlyaem eog v hvost
sort([],[]). %rezultatom sortirovki pustogo spiska budet pustoi spisok
sort([H|Tail],S):-sort(Tail,STail),insert(H,STail,S). %sortiruem hvost i vstavlyaem pervii element spiska na nuznoe mesto
goal
%prosto pokazivaem rabotu vseh sozdannih predicatov
append([1,2,3,4,5],[6,7,8,9,10],L),write(L),nl,nl,nl,
reverse([1,2,3,4,5],R),write(R),nl,nl,nl,
delete_first(5,[1,2,3,4,5,5,6,7],D),write(D),nl,nl,nl,
delete_all(5,[1,2,3,4,5,5,6,7],D1),write(D1),nl,nl,nl,
no_doubles([1,1,2,3,3,4,5,5],N),write(N),nl,nl,nl,
all_sublists([1,2,3]),nl,nl,nl,
number(5,[7,6,5,4,3,2,1],M),write(M),nl,nl,nl,
sort([5,3,7,1,9],S),write(S),nl,nl,nl.
|