76
Програмиране на Пролог Програмиране на Пролог доц. Светла Бойчева Факултет по математика и информатика СУ “Св. Климент Охридски”

Програмиране на Пролог

Embed Size (px)

DESCRIPTION

Програмиране на Пролог. доц. Светла Бойчева Факултет по математика и информатика СУ “Св. Климент Охридски”. Работа с термове. част 7. (де)композиция на терм. +Term =.. ?List ?Term =.. +List List е списък, чийто първи елемент е функтор на Term, - PowerPoint PPT Presentation

Citation preview

Page 1: Програмиране на Пролог

Програмиране на ПрологПрограмиране на Пролог

доц. Светла БойчеваФакултет по математика и информатикаСУ “Св. Климент Охридски”

Page 2: Програмиране на Пролог

Работа с термовеРабота с термове

част 7

Page 3: Програмиране на Пролог

(де)композиция на терм(де)композиция на терм+Term =.. ?List ?Term =.. +List List е списък, чийто първи елемент е функтор на Term, а останалите елементи на List са аргументите на този терм Term, т.е.

| ?- product(0, n, n-1) =.. L.L = [product,0,n,n-1]

| ?- n-1 =.. L.L = [-,n,1]

| ?- product =.. L.L = [product]

| ?- X=..[functor,arg1,arg2,arg3,arg4].X = functor(arg1,arg2,arg3,arg4) ?

Вместо този предикат може да се използват arg/3 и functor/3.

Page 4: Програмиране на Пролог

Обработка на термовеОбработка на термовеarg(?Arg, +Term, ?Value)

functor(?Term, ?Functor, ?Arity)

Page 5: Програмиране на Пролог

1 ?- T=..[f,1,2].

T = f(1, 2) ;

No

2 ?- f(X,Y)=..[f,1,2].

X = 1

Y = 2

Yes

3 ?- f(X,Y)=..L.

L = [f, X, Y]

Yes

4 ?- f(X,g(Y))=..L.

L = [f, X, g(Y)]

Yes

Page 6: Програмиране на Пролог

5 ?- T=f(1,2,g(X)),arg(2,T,V).

T = f(1, 2, g(X))

V = 2 ;

No

6 ?- T=f(1,2,g(X)),arg(3,T,V).

T = f(1, 2, g(X))

V = g(X)

Yes

7 ?- T=f(1,2,g(X)),functor(T,F,N).

T = f(1, 2, g(X))

F = f

N = 3

Yes

8 ?- functor(T,f,3).

T = f(_G339, _G340, _G341)

Yes

Page 7: Програмиране на Пролог

Обработка на термовеОбработка на термовеterm_variables(+Term, -List)

Унифицира List със списък от променливи, всяка от които

съответства на една променлива от терма Term.

Пример:

?- term_variables(a(X, b(Y, X), Z), L).

L = [G367, G366, G371]

X = G367

Y = G366

Z = G371

Page 8: Програмиране на Пролог

?- term_variables(a(X, b(Y, X), Z), L).

L = [X, Y, Z]

Yes

10 ?- term_variables(a(X, b(Y, a), X), L).

L = [X, Y]

Yes

11 ?- term_variables(sin(X), L).

L = [X]

Yes

12 ?- term_variables(sin(90), L).

L = []

Yes

13 ?- term_variables(sin(log(X)), L).

L = [X]

Yes

Page 9: Програмиране на Пролог

Обработка на термовеОбработка на термовеsetarg(+Arg, +Term, +Value) - при

преудовлетворяване свързването на аргумента се освобождава

nb_setarg(+Arg, +Term, +Value)-- при преудовлетворяване свързването на аргумента НЕ се освобождава

Page 10: Програмиране на Пролог

f(1).

f(2).

f(3).

Page 11: Програмиране на Пролог

18 ?- T=g(X,Y,1),f(Z),setarg(1,T,Z).T = g(1, Y, 1)Z = 1 ;

T = g(2, Y, 1)Z = 2 ;

T = g(3, Y, 1)Z = 3 ;

No

Page 12: Програмиране на Пролог

14 ?- T=f(X,Y,1),setarg(1,T,5).

T = f(5, Y, 1)

Yes15 ?- T=f(X,X,1),setarg(1,T,5).

T = f(5, X, 1)

Yes16 ?- T=f(X,Y,1),setarg(1,T,5),setarg(2,T,2).

T = f(5, 2, 1)

Yes

Page 13: Програмиране на Пролог

Изпълнение на цел Изпълнение на цел GoalGoalTimes Times на брой пътина брой пъти !!! !!!

((има проблем)има проблем)succeeds_n_times(Goal, Times) :- Counter = counter(0), ( Goal, arg(1, Counter, N0), N is N0 + 1, nb_setarg(1, Counter, N), fail ; arg(1, Counter, Times) ).

Page 14: Програмиране на Пролог

Определяне вида на термОпределяне вида на терм

var(X). - удовлетворява се, ако X е свободна променлива

nonvar(X). - удовлетворява се, ако X е свързана променлива

Page 15: Програмиране на Пролог

7 ?- nonvar(X),X=5.

No

8 ?- X=5,nonvar(X).

X = 5

Yes

3 ?- X=5,var(X).

No

4 ?- var(14323).

No

5 ?- var(fdhhgdsj).

No6 ?- nonvar(X).

No

Page 16: Програмиране на Пролог

numbervars(?Term,+N,?M)

Унифицира всяка от променливите на терма

Term със специален терм, така че write(Term)

(или writeq(Term)) отпечатват тези променливи като

(A + (i mod 26))(i//26)

където i се изменя от N до M-1. Именуването

на променливите става отляво надясно.

N трябва да бъде свързано с цяло число.

Ако N=0 се получават имената на променливи

A, B, ..., Z, A1, B1, и т.н.

Page 17: Програмиране на Пролог

ПримерПример 1 1

| ?- numbervars(term(X,Y,Z),28,M).

M = 31,

X = C1,

Y = D1,

Z = E1 ?

Page 18: Програмиране на Пролог

ПримерПример 1a 1a

| ?- X=5, numbervars(term(X,Y,Z),28,M).

M = 30,

X = 5,

Y = C1,

Z = D1 ?

yes

Page 19: Програмиране на Пролог

ПримерПример 1b 1b

|?- X=5,numbervars(term(X,Y,Z),0,M).

M = 2,

X = 5,

Y = A,

Z = B ?

yes

Page 20: Програмиране на Пролог

ПримерПример 1c 1c

|?- X=5,Y=7,Z=2,numbervars(term(X,Y,Z),0,M).

M = 0,

X = 5,

Y = 7,

Z = 2?

yes

Page 21: Програмиране на Пролог

КоментариКоментари

numbervars(Term,0,M). Може да се използва за преброяване на свободните(несвързани) променливи в Term.

numbervars(Term,0,0). Може да се използва за проверка дали всички променливи в Term са свързани променливи.

Page 22: Програмиране на Пролог

Приложение на езика Приложение на езика ПрологПролог

(семантични мрежи)(семантични мрежи)

Page 23: Програмиране на Пролог

Семантична мрежаСемантична мрежаanimal

flybirddaylight

albatross kiwi brown

walk

night

Kimblack_&_white

Albert

Ross

isaactive_at moving_method

isa isa

isa

isa isa

moving_method

active_at

colour

colour

Page 24: Програмиране на Пролог

isa(bird,animal).isa(albatross,bird).isa(kiwi,bird).isa(ross,albatross).isa(albert,albatross).isa(kim,kiwi).moving_method(bird,fly).moving_method(kiwi,walk).active_at(bird,daylight).active_at(kiwi,night).colour(albatross,black_&_white).colour(kiwi,brown).

moving_method(X,Method):-isa(X,SuperX),moving_method(SuperX,Method).

Page 25: Програмиране на Пролог

fact(Fact):-call(Fact),!.

fact(Fact):-Fact=..[Rel,Arg1,Arg2],isa(Arg1,SuperArg),SuperFact=..[Rel,SuperArg,Arg2],fact(SuperFact).

Page 26: Програмиране на Пролог

| ?- fact(moving_method(kim,Method)).| ?- fact(moving_method(kim,Method)).Method = walk ? Method = walk ?

| ?- fact(moving_method(albert,Method)).| ?- fact(moving_method(albert,Method)).Method = fly ? Method = fly ?

Page 27: Програмиране на Пролог

ОператориОператори

част 8

Page 28: Програмиране на Пролог

ОператориОператори

:- op(:- op(PrecedencePrecedence,,TypeType,,NameName).).

Precedence: 1 - 1200Precedence: 1 - 1200 TypeType (ляво/дясно асоциативни): (ляво/дясно асоциативни):

постфиксни:постфиксни: xf, yf xf, yf префиксни:префиксни: fx, fy fx, fy инфиксни:инфиксни: xfx, xfy, yfx xfx, xfy, yfx

Name (Name (име на оператор или списък от име на оператор или списък от имена на оператори)имена на оператори)

Page 29: Програмиране на Пролог

ОператориОператори

:- op(900,fx,if).:- op(900,fx,if).

:- op(890,xfy,then).:- op(890,xfy,then).

:- op(880,xfy,or).:- op(880,xfy,or).

:- op(870,xfy,and).:- op(870,xfy,and).

:- op(860,fx,not).:- op(860,fx,not).

Page 30: Програмиране на Пролог

ПравилаПравила

if if gives_milk(X)gives_milk(X) then then mammal(X).mammal(X).

if if has_feathers(X)has_feathers(X) and and lays_eggs(X)lays_eggs(X) then then bird(X).bird(X).

if if has_gills(X)has_gills(X) and and lays_eggs(X)lays_eggs(X) then then fish(X).fish(X).

if if bird(X)bird(X) and not and not penguin(X)penguin(X) then then flies(X).flies(X).

if if fish(X)fish(X) then then lives(X,sea).lives(X,sea).

if if mammal(X)mammal(X) or or fish(X)fish(X) or or bird(X)bird(X) then then

homeothermic(X).homeothermic(X).

if if mammal(X)mammal(X) and and can_speak(X)can_speak(X) then then human(X).human(X).

if if bird(X)bird(X) and and can_speak(X)can_speak(X) then then parrot(X).parrot(X).

Page 31: Програмиране на Пролог

:-op(800,xfy,loves).:-op(900,xfy,hates).

john loves mary.peter loves ann.mary loves paul.john loves susan.ann loves john.mary loves peter.

ann hates mary.peter hates paul.mary hates susan.

X hates Y :- Y loves X, \+ X loves Y.

Page 32: Програмиране на Пролог

Работа с динамичната Работа с динамичната база от даннибаза от данни

част 9

Page 33: Програмиране на Пролог

listing listing(term).

:- dynamic <fact1>/n1 ,<fact2>/n2, assert(<fact> ). assertz(<fact> ). asserta(<fact> ). retract(<fact>). retractall(<fact>)

Page 34: Програмиране на Пролог

:-dynamic st/1.

st(0).

my_statistics:- write('This program is executed '), st(N),write(N),write(' times.'),nl.

program(X):- write('Value '), write(X),nl, st(N), M is N+1, retract(st(N)), assert(st(M)).

Page 35: Програмиране на Пролог

Приложение на езика Приложение на езика ПрологПролог

(експертна система)(експертна система)

Page 36: Програмиране на Пролог

БазаБаза от фактиот факти

:- dynamic fact/1.:- dynamic fact/1.

fact(fact(has_feathers(tweety)has_feathers(tweety)))..

fact(fact(lays_eggs(tweety)lays_eggs(tweety)).).

fact(fact(gives_milk(milka)gives_milk(milka)).).

fact(fact(mammal(john)mammal(john)))..

fact(fact(can_speak(john)can_speak(john)).).

Page 37: Програмиране на Пролог

Прав извод (Прав извод (fforward orward chainingchaining))

ПравилаПравила

if gives_milk(X) then mammal(X).if gives_milk(X) then mammal(X).

if has_feathers(X) and if has_feathers(X) and

lays_eggs(X)then bird(X).lays_eggs(X)then bird(X).

if has_gills(X) and lays_eggs(X) if has_gills(X) and lays_eggs(X)

then fish(X).then fish(X).

if bird(X) and not penguin(X)if bird(X) and not penguin(X)

then then flies(X).flies(X).

......

fact(fact(gives_milk(X)gives_milk(X)))

ФактиФактиfact(has_feathers(tweety)).fact(has_feathers(tweety)).fact(lays_eggs(tweety)).fact(lays_eggs(tweety)).fact(gives_milk(milka)).fact(gives_milk(milka)).......

Page 38: Програмиране на Пролог

Прав извод (Прав извод (fforward orward chainingchaining))

ПравилаПравила

if gives_milk(X) then mammal(X).if gives_milk(X) then mammal(X).

if has_feathers(X) and if has_feathers(X) and

lays_eggs(X)then bird(X).lays_eggs(X)then bird(X).

if has_gills(X) and lays_eggs(X) if has_gills(X) and lays_eggs(X)

then fish(X).then fish(X).

if bird(X) and not penguin(X)if bird(X) and not penguin(X)

then then flies(X).flies(X).

......

fact(fact(gives_milk(gives_milk(milkamilka))))

ФактиФактиfact(has_feathers(tweety)).fact(has_feathers(tweety)).fact(lays_eggs(tweety)).fact(lays_eggs(tweety)).fact(gives_milk(milka)).fact(gives_milk(milka)).......

fact(fact(mmammalammal((milkamilka))))

Page 39: Програмиране на Пролог

Прав извод (Прав извод (fforward orward chainingchaining))

derive :-derive :-

derive_fact(P),derive_fact(P),

write('Derived: '),write('Derived: '),

write(P), nl,write(P), nl,

derive.derive.

derive.derive.

Page 40: Програмиране на Пролог

Прав извод (Прав извод (fforward orward chainingchaining))

derive_fact(P) :-derive_fact(P) :-

if Condition then P,if Condition then P,

ok(Condition), ok(Condition), \+\+ fact(P), fact(P),

assertz(fact(P)).assertz(fact(P)).

Page 41: Програмиране на Пролог

Прав извод (Прав извод (fforward orward chainingchaining))

ok(P) :-ok(P) :- fact(P).fact(P).

ok(P and Q) :-ok(P and Q) :- ok(P),ok(P), ok(Q).ok(Q).

ok(P or Q) :-ok(P or Q) :- ok(P);ok(P); ok(Q).ok(Q).

Page 42: Програмиране на Пролог

Прав изводПрав извод

| ?- derive. | ?- derive.

Derived: mammal(milka)Derived: mammal(milka)

Derived: bird(tweety)Derived: bird(tweety)

Derived: homeothermic(john)Derived: homeothermic(john)

Derived: homeothermic(milka)Derived: homeothermic(milka)

Derived: homeothermic(tweety)Derived: homeothermic(tweety)

Derived: human(john)Derived: human(john)

yesyes

Page 43: Програмиране на Пролог

БазаБаза от факти - черна от факти - черна дъскадъска

fact(has_feathers(tweety)).fact(has_feathers(tweety)).

fact(lays_eggs(tweety)).fact(lays_eggs(tweety)).

fact(gives_milk(milka)).fact(gives_milk(milka)).

fact(mammal(john)).fact(mammal(john)).

fact(can_speak(john)).fact(can_speak(john)).

fact(mammal(milka)).fact(mammal(milka)).

fact(bird(tweety)).fact(bird(tweety)).

fact(homeothermic(john)).fact(homeothermic(john)).

fact(homeothermic(milka)).fact(homeothermic(milka)).

fact(homeothermic(tweety)).fact(homeothermic(tweety)).

fact(human(john)).fact(human(john)).

Page 44: Програмиране на Пролог

Вход и изходВход и изход

част 10

Page 45: Програмиране на Пролог

Работа с файловеРабота с файлове

Предикатите за обработка на входни/изходни данни се изпълняват по подразбиране за текущия входно/изходен поток (I/O Stream).

Ето защо повечето такива предикати имат две версии: една, при която се работи с текущия поток друга, при която има допълнителен аргумент за

указване на потока с който се работи

Page 46: Програмиране на Пролог

Работа с файловеРабота с файлове

read(?Term)

read(+Stream,?Term)

Прочита от Stream следващия терм, който завършва с точка и го унифицира с Term. Синтаксисът на терма трябва да съответства на стандартните декларации. При достигане до края на Stream при read(Stream, Term) Term ще се унифицира с end_of_file. Следващите обръщения към read/2 за същия поток предизвикват грешка, освен в случаите когато потока е свързан с терминала.

Page 47: Програмиране на Пролог

Работа с файловеРабота с файлове

write(?Term) [ISO]

write(+Stream,?Term) [ISO]

Записва Term в потока Stream в съответствие с текущите декларации на оператора.

Page 48: Програмиране на Пролог

Работа с файловеРабота с файлове

writeq(?Term) [ISO]

writeq(+Stream,?Term) [ISO]

Подобно на write(Stream,Term), но имената на атомите и функторите се цитират, където е необходимо, за да може резултата да бъде приемлив като вход за read/2.

Page 49: Програмиране на Пролог

?- X=5, write(X).

5

?- X=5, write(x=X).

x=5

?- write('Hello World!').

Hello World!

?- X=5,Y=10, write(x=X),nl,write(y=Y).

x=5

y=10

Yes

Page 50: Програмиране на Пролог

?- read(Z).

|: 34.67.

Z = 34.67

Yes

?- read(Z).

|: Hello.

Yes

?- read(Z).

|: 'Hello!'.

Z = 'Hello!'

Yes

?- read(Z).

|: hello.

Z = hello

Yes

Page 51: Програмиране на Пролог

?- read(Z).

|: 1+2.

Z = 1+2

Yes

?- X=5,Y=10,write(X+Y).

5+10

X = 5

Y = 10

Page 52: Програмиране на Пролог

summa:-

read(X),read(Y),

Z is X+Y,

write(summa=Z).

Page 53: Програмиране на Пролог

get_char(Stream,Char) format(Text), format(Text,List). nl nl(Stream)

Page 54: Програмиране на Пролог

3 ?- format('This is a ~w ~w',[bad, boy]).This is a bad boy

Yes 4 ?- format('This is a ~w ~w',[good, girl]).This is a good girl

Yes 5 ?- format('This is a ~w ~w',[good, student]).This is a good student

Yes

Page 55: Програмиране на Пролог

open(Filename, read/write/append , Stream) current_input(Stream) current_output(Stream) set_input(Stream) set_output(Stream) close(Stream)

end_of_file

Page 56: Програмиране на Пролог

?-open(‘d:/temp/proba.txt’, read, S), set_input(S).?-open(‘d:/temp/proba.txt’, read, S), set_input(S).?-open(‘d:/temp/proba.txt’, write, S), set_output(S).?-open(‘d:/temp/proba.txt’, write, S), set_output(S).?-open(‘d:/temp/proba.txt’, append, S), set_output(S).?-open(‘d:/temp/proba.txt’, append, S), set_output(S).?-current_output(S), close(S).?-current_output(S), close(S).?-current_input(S), close(S).?-current_input(S), close(S).

Page 57: Програмиране на Пролог

read_text(Filename):-

open(Filename,read,S),

set_input(S),

display_file(S),

close(S).

display_file(S):-

read(S,X),

( X = end_of_file -> nl ;

write(X),nl,

display_file(S)).

Page 58: Програмиране на Пролог

read_text(Filename,Text):-

open(Filename,read,S),

set_input(S),

read_string(S,Text),

close(S).

Page 59: Програмиране на Пролог

read_string(S,Text):-

get_char(S,Char),

( Char = end_of_file -> Text = '' ;

name(Char,[CCode]),

read_string(S,RestText),

name(RestText,TCode),

name(Text, [CCode|TCode])).

Page 60: Програмиране на Пролог

write_text(Filename,Text):-

open(Filename, write, S),

set_output(S),

write(S,Text),

close(S).

Page 61: Програмиране на Пролог

ЗадачаЗадача

Да се напише предикат, който от зададен текстов файл да намира всички думи, които се съдържат в него и да ги записва в друг файл без повторения, като всяка дума се изписва на отделен ред.

Page 62: Програмиране на Пролог

write_list([ ]).

write_list([ X | L]):-

write(X), nl,

write_list(L).

Page 63: Програмиране на Пролог

write_text_lines(Filename,L):-

open(Filename, write, S),

set_output(S),

write_list(L),

close(S).

Page 64: Програмиране на Пролог

file_words(Input_file, Output_file):-

read_text(Input_file, Text),

tag_words(Text,WordsList),

compress(WordsList, OutList),

write_text_lines(Output_file,OutList).

Page 65: Програмиране на Пролог

ЗадачаЗадача

Да се напише предикат, който от зададен текстов файл да намира всички думи, които се съдържат в него и да ги записва в друг файл без повторения, като всяка дума се изписва на отделен ред и за нея се изписва броя на срещанията й.

Page 66: Програмиране на Пролог

count([ ],_,0).

count([X|L],X,N):-

count(L,X,K),

N is K+1.

count([Y|L],X,N):-

Y \= X,

count(L,X,N).

Page 67: Програмиране на Пролог

count_words([],[]).

count_words([X|Words],[ X/N |CW]):-

count([X|Words],X,N),

del_all(X,Words,W1),

count_words(W1,CW).

Page 68: Програмиране на Пролог

file_words_st(Input_file, Output_file):-

read_text(Input_file, Text),

tag_words(Text,WordsList),

count_words(WordsList, ResList),

sort(ResList, OutList),

write_text_lines(Output_file,OutList).

% сортирани по азбучен ред

Page 69: Програмиране на Пролог

count_words1([],[]).

count_words1([X|Words],[ N/X |CW]):-

count([X|Words],X,N),

del_all(X,Words,W1),

count_words1(W1,CW).

Page 70: Програмиране на Пролог

file_words_st(Input_file, Output_file):-

read_text(Input_file, Text),

tag_words(Text,WordsList),

count_words1(WordsList, ResList),

sort(ResList, OutList),

write_text_lines(Output_file,OutList).

% сортирани по брой срещания

Page 71: Програмиране на Пролог

Задачи•Даден е файл, който съдържа текст. Да се напише програма, която да заменя всички срещания на дадена дума от текста с друга дадена дума. Резултатът от изпълнението на програмата да се съдържа в дадения файл.

Page 72: Програмиране на Пролог

split(L,T,P,Res):- append(Prev,L2,L), append(T,Next,L2), append(P,Next,Res1), append(Prev,Res1,Res).

replace(Text,Old,New,Res):- split(Text,Old,New,TempRes),!, replace(TempRes,Old,New,Res).replace(Text,Old,New,Text).

Page 73: Програмиране на Пролог

read_string(S,Text):- get_char(S,Char), ( Char = end_of_file -> Text = '' ; name(Char,[CCode]), read_string(S,RestText), name(RestText,TCode), name(Text, [CCode|TCode])).

Page 74: Програмиране на Пролог

exchange_words(File,OldWord,NewWord):- open(File,read,S), set_input(S), read_string(S,Text), close(S), name(Text,Code), name(OldWord,COW), name(NewWord,CNW), replace(Code,COW,CNW,Res), name(NewText,Res), open(File,write,S1), set_output(S1), write(NewText), close(S1).

Page 75: Програмиране на Пролог

Задача•Даден е текстов файл, който съдържа числа (на всеки ред по едно число). Да се напише програма, която да заменя най-голямото число от файла с най-малкото. Резултатът от изпълнението на програмата да се съдържа в дадения файл.

Page 76: Програмиране на Пролог

Задачи•Даден е файл, който съдържа текст. Да се напише програма, която да изтрива всички срещания на дадена дума от текста. Резултатът от изпълнението на програмата да се съдържа в дадения файл.•Даден е файл, който съдържа текст. Да се напише програма, която по зададено естествено число K да намира всички K буквени думи от текста и да ги записва в друг файл.