Примеры предикатов обработки списков




Списки

Список представляет собой основную структуру данных на Прологе.

Список-последовательность из произвольного числа элементов некоторого типа без ограничения на длину списка. Тип данных Список объявляется.

Domins

Списковый_тип=тип*

*Говорит, что перем. – список.

Тип_тип элементолв списка (стандартный, заданный пользователем в domains).

Domins

Int_list=integer*

Predictes

Nonderterm numbers(int_list)

Аргумент предиката-список целых чисел. Ввод списков с клавиатуры выполняется стандартным предикатом readtern.

Domains

Int_list=integer*

Predicates

Nonderterm dal (int_li nt, integer, int_list)

Nondeterm оbvab

 

Goal

Obvab.

….

В Прологе введены понятия головы и хвоста списка. Голова 1-й элемент списка, хвост-остальная часть списка. Хвост сам является спискам.

Пустой список [ ], список из одного элемента [x]

Пусть имеется список Z=[6,8], М и N – свободные переменные. Тогда передает 2 [M/N] доказательство успешно, M связывается с 6, а N- со списком из одного элемента.

Y=M+1 допустима

X=N+1 не допустима

Предикат1 Предикат2 Результат
Obrab(l) L=[1,2,3]   Obrab(l) L=[1,2,3]   Obrab(L) L=[2]   Obrab(L) L=[2]   Obrab(L) L=[]   Obrab(L) L=(1,2,3)   Obrab(x) x-свободная переменная   Obrab[H/T] H,T-свободный     Obrab[H/T] H,T-свободный     Obrab(X)X-свободная переменная     Obrab[]     Obrab[]   Успешное сопоставление X=[1,2,3]     Успешное сопоставление H=1,T=[2,3]   Успешное сопоставление H=2, T=[]     Успешное сопоставление X=2/x-целочисленная переменная, а не список Успешное сопоставление, т.к. аргументы предикатов равны(оба-пустые символы) Успешное сопоставление   Неудача, т.к. аргументы не равны

 

Общие рекомендации по составлению программ со списками:

1. В операциях со списками всегда есть рекурсия.

2. Предикаты для реализаций операций со списками обычно имеют несколько клозов. 1-ый из них относится к простейшему случаю, последующие клозы относятся к более общим случаям и имеют следующее назначение.

Если список не соответствует простейшему случаю, то следует уменьшить на 1 элемент и применить рекурсию к укороченному списку.

3. Предикаты, предназначенные для получения одного списка из другого всегда имеют не меньше 2-х аргументов. Исходный список, список-результат.

К числу основных операций со списком можно отнести:

- проверка принадлежащему списку;

Добавление элемента в список;

- удаление элемента из списка;

- присоединение списка у другому;

- вывод элементов списка на экран.

Примеры предикатов обработки списков

1. Добавление элемента в конец списка.

Если исходный список пуст, формируется список из одного элемента. В противном случае нужно отделить от исходного списка голову, добавить предикат dobav и объявляется новый.

Dobav [x,[],[x]):-!

Dlina(x,List,Lres):-List=[H/T1],dobav

(x,T,T1),Lres=[H/T1].

2. Определение длины списка

Если список пуст, длина равна нулю, иначе длина хвоста +1.

Dlina([],0):-!

Dlina(List,N):-List=[ /T],dlina (T,N1),

N=N1+1.

3. Проверка принадлежащего элемента к списку.

Переместим х-элемент, принадл. Кот. следует определить к списку L,

L-список.

prinadl (X,L):-L=[X|_],!.

prinadl (X,L):-L=[_|T], prinadl (X,T).

1-й предикат проверяет, совпадает ли элемент с головой списка, если нет, проверяется принадлежащие к хвосту.

4. Поиск max элемента списка.

Если список пуст max=0. Если список из одного элемента, равен этому элементу.

max_elem([ ],Max):-Max=0,!.

max_elem([X],Max):-Max=X,!.

max_elem([H|T],Max):-max_elem (T,M),max1 (T,H,Max).

max1(x1,x2,Max):-x1>=x2,Max=x1,!.

Max1(_,x2,Max):-Max=x2.

5. Выделение части из списка.

Podspisok (L,1,1,Res):-L=[H|_],Res=[H],!.

Podspisok (L,1,N1,Res):-L=[H|T],N21=N2-1,

Podspisok(T,1,N21,Res1),Res=[H|Res1],!.

Podspisok(L,N1,N2,Res):-L=[ |T],N11=N1-1,

N21=N2-1,PODSPISOK(T,N11,N21,Res).

Пример

Predicates

%nondeterm vyvod

nondeterm poisk(string,intrger)

nondeterm rabota(string,integer)

nondeterm proekt(string,string,integer)

goal

poisk(“Ivanov”,500).

/*vyvod.*/

clauses

/*vyvod:-write(“Familia:”),readln(F)

write(“Stoimost:”), readln (St),

poisk(F,S).*/

poisk(Fam,St):-rabota (Fam,Shift),

proekt(Shifr,Zak,Stiom),

stoim>=St

write(Shifr,” “, Zak),fail.

domains

spisok=string+

predicates

nondeterm rabota (string,spisok)

nondeterm proekt (string,string,integer)

nondeterm prinadl (string, spisok)

nondeterm poisk (string)

% nondeterm start(string)

goal

poisk (“Rubin”).

clauses

% stsrt (KK):-poisk(Zak).

poisk (Zak):-proekt (Shifr,Zak,_),

write (Shifr),nl,

rabota (Fam,Spis_Shifr),

prinadl (Shifr,Spis_shifr),

write (Fam), nl, fail.

poisk().

prinadl (X,L):-L=[X|_],!.

prinadl (X,L):-L=[_|T],

prinadl (X,T).

rabota (“Antonov”, [“P20”]),

rabota (“Ivanov”, [“P70”,”P100”,”P120”]).

rabota (“Petrov”, [“P100]”).

rabota (“Vasiliev”, [“P70”,”P120”]).

proekt (“P20”,”Rubin”,700).

proekt (“P100”,”Rubin”,1400).

proekt (“P70”,”Gorizont”,500).

proekt (“P120”,”Kristall”,1100).

После ввода “Rubin” выполняется проверка poisk. Это предикат-правило, и требуется доказать все предикаты, входящие в него.

В proekt Zak связывается с “Rubin” и обращается к proekt. Не связывающая переменная Shifr, определяет что может быть любое значение.

Проект сопоставляется успешно Shifr получает значение “P20”, оно выводится на экран. Доказательство следующего предиката rabota. Для этого выполняется сопоставление “Antonov” и Shift состоит из одного элемента – “P20”.

Он связывается и доказывается prinadl. Shift должен определить на принадлежность списка шифров rabota Антонова.

Rabota сопоставляется с “Ivanov”. Неудача, возврат к предыдущей.

По “P20” удачно завершилось одно сопоставление.

Основные типы данных

База данных на Прологе



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2019-04-30 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: