Avtomatsko vračanje in negacija
Iz E-študij, proste zakladnice študentskega znanja
Vsebina |
Avtomatsko vračanje
Prolog shranjuje vse poti, ki jih je prehodil, na Stack, ta podatek je potreben za avtomatsko vračanje. S preiskovanjem v globino ta Stack eksponentno raste z vsakim korakom v globino.
Rez
Rez prvič takoj uspe, pri avtomatskem vračanju pa povzroči neuspeh nadrejenega cilja.
Rez v prologov program zapišemo kot klicaj:
proc():- ~~~, ~~~, ! ~~~, ~~~.
Primer
p :- a,b,c. p :- d.
b :- e,!,f. b :- g.
a. e. d. g. %dejstva so definirana kot resnična
?- p.
call> p
call> a
exit> a % dejstvo
call> b
call> e
exit> e %dejstvo
call> !
exit> ! %rez prvič takoj uspe
call> f
%fail>f
redo> !
fail> !
fail> b
redo> a
fail> a %ne more še enkrat uspeti
redo> p
call> d
exit> d %dejstvo
exit> p
yes
Ustavitev ob prvi rešitvi
Iskanje samo prve rešitve, če vemo, da je možna samo ena rešitev in nočemo, da se prolog samodejno vrača.
element1(X,[X|_]):- !. element1(X,[_|Sez]) :- element1(X,Sez).
?- element1(f(X),[f(1),g(2),h(3),f(4),f(5),h(6)]). X = 1; no
Iskanje maksimalnega elementa
max_pocasni([X],X). max_pocasni([X|Rep],X):- max_pocasni(Rep,Max), Max =< X. max_pocasni([X|Rep],Max):- max_pocasni(Rep,Max), Max > X.
Algoritem lahko izboljšamo tako, da uporabimo rez.
max([X],X). max([X|Rep],Max) :- max(Rep,Max), Max >= X, !. max([X|_],X).
If then else v prologu
if_then_else(P,Q,_) :- P,!,Q. if_then_else(_,_,R) :- R.
ali
if_then_else(P,Q,R) :- P,!,Q;R.
Zapis max na if_then_else način:
max([X],X). max([X|Rep],Max1) :- max(Rep,Max), if_then_else(Max>=X, Max1=Max, Max1=X).
Kombinacija s proceduro call
p :- a, b, call((c,d,!,e)), f, g.
Kombinacija s fail
Fail nikoli ne uspe, ker ga po konvenciji ne smemo nikoli definirati.
Ta operacija povzroči takojšnji neuspeh nadrejenega cilja:
!,fail
Do fail sprosti Stack, ko pride do rezultata izračuna P.
do_fail(P) :- call((P,!,fail)). do_fail(_).
Negacija
Uspela negacija dokaže samo to, da Prolog NI uspel dokazati da je stvar resnična, kar še ni dokaz da cilj ni resničen.
not(Cilj) :- call(Cilj),!,fail. %če cilj uspe, negacija ne sme uspeti not(_). %drugače ni uspel, zato negacija uspe
not(otrok(_,X)). %no
not(C) :- if_then_else(C,fail,true).
ni_element(_,[]). ni_element(X,[Y,R]) :- X \== Y, ni_element(X,R).
Predpostavka zaprtega sveta
Kar prolog lahko dokaže je resnično, vse ostalo je neresnično.
?- not(pameten(uporabnik)). yes
Prolog ni uspel dokazati, da je nedefiniran uporabnik pameten.