Списки на Прологе Лекция № 5 Описание [monday, tuesday, wednesday, thursday, friday, saturday, sunday] ["понедельник", "вторник", "среда", "четверг", "пятница", "суббота", "воскресенье"] [1, 2, 3, 4, 5, 6, 7] ['п', 'в', 'с', 'ч', 'п', 'с', 'в'] [] DOMAINS <имя спискового домена>=<имя домена элементов списка>* listI = integer* listR = real* listC = char* lists = string* listL = listI* /*[[1,3,7],[],[5,2,94],[–5,13]]*/ Описание [monday, 1, "понедельник"] DOMAINS element = i(integer); c(char); s(string) listE = element* [i(–15), s("Мама"),c('A'),s("мыла"),c('+'),s("раму"), i(48),c('!')] Рекурсивное описание списка [1, 2, 3] = [1|[2, 3]] = [1|[2|[3]]] = [1|[2|[3|[ ]]]] = [1,2|[3]] = [1, 2, 3|[]] Вычисление длины списка length([], 0). length([_|T], L) :– length(T, L_T), L = L_T + 1. Внешняя цель: length([1,2,3],X). Проверка принадлежности элемента списку member(X,[X|_]). member(X,[_|T]) :– member(X,T). member(2, [1, 2, 3]). member(4, [1, 2, 3]). member(X, [1, 2, 3]). member(1, X). member2(X,[X|_]). member2(X,[Y|T]):– X<>Y, member2(X,T). member3(X,[X|_]):–!. member3(X,[_|T]):– member3(X,T). Объединение двух списков conc([ ], L, L). conc([H|T], L, [H|T1]) :– conc(T,L,T1). conc([1, 2, 3], [4, 5], X) conc([1, 2, 3], [4, 5], [1, 2, 5]) conc([1, 2], Y, [1, 2, 3]) conc(X, [3], [1, 2, 3]) conc(X, Y, [1, 2, 3]) conc(L, [2|R], [1, 2, 3, 2, 4]) Варианты использования предиката conc last(L,X):– conc(_,[X],L). last2([X],X). last2([_|L],X):– last2(L,X). member4(X,L):– conc(_,[X|_],L). Соседние элементы списка neighbours(X,Y,L):– conc(_,[X,Y|_],L). neighbours2(X,Y,L):– conc(_,[X,Y|_],L); conc(_,[Y,X|_],L). Обращение списка reverse([ ],[ ]). reverse([X|T],Z):– reverse(T,S), conc(S,[X],Z). rev([H|T],L1,L2):– rev(T,[H|L1],L2). rev([ ],L,L). reverse2(L1,L2):– rev (L1,[ ],L2). palindrom(L):– reverse (L,L). Получение элемента списка по его номеру n_element([X|_],1,X). n_element([_|L],N,Y):– N1=N–1, n_element(L,N1,Y). Удаление всех вхождений заданного значения из списка delete_all(_,[],[]). delete_all(X,[X|L],L1):– delete_all (X,L,L1). delete_all (X,[Y|L],[Y|L1]):– X<>Y, delete_all (X,L,L1). delete_one(_,[],[]). delete_one(X,[X|L],L):–!. delete_one(X,[Y|L],[Y|L1]):– delete_one(X,L,L1). Сумма элементов списка summa([], 0). /* сумма элементов пустого списка равна нулю */ summa([H|T], S) :– summa(T, S_T), /* S_T - сумма элементов хвоста */ S = S_T + H. /* S - сумма элементов исходного списка */ Сумма элементов списка sum_list([],S,S). /* список стал пустым, значит в накопителе – сумма элементов списка */ sum_list([H|T],N,S) :– N_T=H+N, /* N_T - результат добавления к сумме, находящейся в накопителе, первого элемента списка */ sum_list(T,N_T,S). /* вызываем предикат от хвоста T и _T */ sum2(L,S):– sum_list(L,0,S). Среднее арифметическое элементов списка avg([],0):–!. avg(L,A):– summa(L,S), /* помещаем в переменную S сумму элементов списка */ length(L,K), /* переменная K равна количеству элементов списка */ A=S/K. /* вычисляем среднее как отношение суммы к количеству */ Минимальный элемент списка min_list([X],X). min_list([H|T],M):– min_list(T,M_T), min(H,M_T,M). Сортировка: метод прямого обмена permutation([X,Y|T],[Y,X|T]):– X>Y,!. permutation([X|T],[X|T1]):– permutation(T,T1). bubble(L,L1):– permutation(L,LL), !, bubble(LL,L1). bubble(L,L). Сортировка вставкой ins_sort([ ],[ ]). ins_sort([H|T],L):– ins_sort(T,T_Sort), insert(H,T_Sort,L). insert(X,[],[X]). insert(X,[H|T],[H|T1]):– X>H,!, insert(X,T,T1). insert(X,T,[X|T]). Сортировка выбором choice([ ],[ ]). choice(L,[X|T]):– min_list(L,X), delete_one(X,L,L1), choice(L1,T). Быстрая сортировка quick_sort([],[]). quick_sort([H|T],O):– partition(T,H,L,G), quick_sort(L,L_s), quick_sort(G,G_s), conc(L_s,[H|G_s],O). partition([],_,[],[]). partition([X|T],Y,[X|T1],Bs):– X<Y,!, partition(T,Y,T1,Bs). partition([X|T],Y,T1,[X|Bs]):– partition(T,Y,T1,Bs). Объединение отсортированных списков fusion(L1,[ ],L1):–!. fusion([ ],L2,L2):–!. fusion([H1|T1],[H2|T2],[H1|T]):– H1<H2,!, fusion(T1, [H2|T2],T). fusion(L1, [H2|T2],[H2|T]):– fusion(L1,T2,T). Сортировка слияниями splitting([],[],[]). splitting([H],[H],[]). splitting([H1,H2|T],[H1|T1],[H2|T2]):– splitting(T,T1,T2). fusion_sort([],[]):–!. fusion_sort([H],[H]):–!. fusion_sort(L,L_s):– splitting(L,L1,L2), fusion_sort(L1,L1_s), fusion_sort(L2,L2_s), fusion(L1_s,L2_s,L_s). Проверка упорядоченности списка sorted([ ]). sorted([_]). sorted([X,Y|T]):– X<=Y, sorted([Y|T]).