Други предикати от втори ред - Студопедия
Логиката от първи ред позволява количествено определяне по отделни елементи. Освен това логиката от втори ред позволява количествено определяне чрез предикати. Включването на такова разширение в логическото програмиране включва използването на правила с цели, чиито предикатни имена са променливи. Имената на предикатите стават "първокласни" обекти с данни, които могат да бъдат модифицирани и манипулирани.
Един прост пример за релация от втори ред е дали всички елементи на списък имат определено свойство. За простота се приема, че това свойство е описано като унарен предикат. Нека дефинираме релациятаhas_property(Xs.P), която е вярна, ако елемент отXsима някакво свойствоP. 17.5. Тъй като е възможно да се използват свойства на променливи в дефиницията на предикатаhas_property, това е предикат от втори ред. Пример за използване на този предикат е въпросътhas_property (Xs,male)?,проверяващ "всички хора в списъкаXs мъже ли са?".
Друг предикат от втори реде map_list(Xs.P.Ys).ТукYs епреобразуване на списъкаXsот предикатаP.Това означава, че за всеки елементXотXsима съответен елементYотYs,така чеP(X,Y)е вярно.Ysзапазва реда на елементите от списъкаXs.С помощта на предикатаmap-list,някои програми от предишни глави могат да бъдат пренаписани. Например програма 7.8, която преобразува набор от английски думи във френски думи, може да бъде изразена като предикатmap_list(Words,dict,Mots).Предикатътmap_list,, подобно на предикатаhas_property,, може лесно да се дефинира с помощта на име на променлив предикат. Това определение е дадено на фиг. 17.5.
has_property([X Xs],P) ¬ P(X),has_property(Xs,P). има_свойство([ ],P).
map_list([X Xs],P,[Y Ys]) ¬ P(X,Y), map_list(Xs,P,Ys).
Фиг. 17.5. Предикати от втори ред.
В оперативен смисъл възможността за използване на имена на променливи предикати включва динамично изграждане на цели в процеса на решаване на въпрос. При задаване на въпрос изчисленото съотношение не остава статично непроменено, а се определя динамично по време на процеса на изчисление.
В някои версии на Prolog програмистът може да използва променливи за имена на предикати и синтаксиса, показан на фиг. 17.5. Въпреки това, няма нужда от толкова сложен синтаксис. Вече съществуват инструменти, подходящи за прилагане на предикати от втори ред. Достатъчно е да използваме една основна релация, която ще наречем предикатприлагане,тя е предназначена за конструиране на цел с променлив функтор. Предикатът за прилагане се определя от множество клаузи - по една клауза за всяко име и арност на функтор. Например, за функторfooна aritynтрябва да напишете изречение
apply(foo,Xl, . .,Xn) ¬ foo(Xl, . .,Xn).
Двата предиката, дефинирани на фиг. 17.5 са представени в програма 17.8 в стандартен Пролог. Дефинициите на клаузатаapplyса дадени тук за примерите, споменати в книгата.
Предикатътapplyосигурява структурен контрол. Пълният набор отapplyклаузи може да бъде обобщен чрез използване на примитива за структурен контролuniv.Генеричният предикатapply(P,Xs)прилага предикатаPкъм списъка с аргументиXs:
apply(F,Xs) ¬ Цел =..[F Xs],Goa1.
Тази функция може да бъде обобщена, така че да може да се използва, започвайки с името на предиката, т.е. някакъв атом и завършва с член, параметризиран от променливи. Пример е заместване на стойност в списък. Ако параметризирането е разрешено, тогава релациятаSubsiitute/4в програма 9.3 може да се разглежда като пример за предикатаmap_list.А именно: предикатътmap_list(Xs, заместител (Old, New).Ys)дава същия резултат (списъкътYsсе получава чрез заместване в списъка
има_свойство(Xs, P) ¬
Всеки елемент от списъкаXsима свойствотоP.
app1y(мъжки, X) ¬ мъжки(X).
Всеки елемент от списъкаXsе във връзкаP ссъответния му елемент от списъкаYs.
map_list([X Xs],P,[Y Ys]) ¬
apply(P,X,Y), map_list(Xs,P,Ys).
Програма 17.8. Предикати от втори ред в Prolog.
XsелементСтарпо елементНов),което е съотношението, изчислено от програма 9.3. За да изпълни правилно горните действия, клаузатаapply, с незначителни промени, трябва да бъде приведена в следната форма:
P=..LI, добавяне(Ll,Xs,L2), Цел=..L2,Цел.
Използването на предикатаapplyв тялото на клаузатаmap_listводи до неефективни програми. Например, директното прилагане на релациятаSubstitute, в сравнение с прилагането на същите действия с помощта на предикатаmap_list, води до значително намаляване на броя на формираните междинни структури и опростява компилацията. Следователно предикатите от втори ред се използват най-добре във връзка със система за преобразуване на програми, която може да превежда по време на компилиранеизрази с предикати от втори ред в изрази с предикати от първи ред.
Предикатътapplyможе също да се използва за прилагане на ламбда изрази. Ламбда изразът е във форматаламбда(X. X).Израз.Ако наборът от ламбда изрази, които ще се използват, е известен предварително, те могат да бъдат наименувани. Например изразът по-горе може да бъде заменен с някакъв уникален идентификатор, да речем идентификатораfoo,и дефиниран от клаузатаapply:
apply(foo, Xl. X) ¬ Израз.
Разпространението на ламбда изрази и предикати от втори ред катоhas_propertyиmap_listе ограничено от функционални езици за програмиране като Lisp, но ние вярваме, че това се дължи на пристрастия и съществуването на много алтернативни методи за програмиране. Възможно е текущата работа за разширяване на модела на логическо програмиране с предикати от по-висок ред и за интегриране на логическо и функционално програмиране да промени картината.
Междувременно множество изрази изглежда са основните и най-полезни конструкции на високо ниво в Prolog.
Не намерихте това, което търсихте? Използвайте търсачката: