Večsmernost procedur
Iz E-študij, proste zakladnice študentskega znanja
x
|
\|/
X <- [f] -> Y
yes/no
/|\
|
X -> [f] <- Y
X -> [f] -> Y X <- [f] <- Y
pascal: Y := f(X); prolog: f(X,Y).
Večsmernost deluje le če uporabljamo osnovna prilagajanja.
brisi(Element,Seznam,Seznam1) :- stik(Sez1,[Element|Sez2],Seznam), stik(Sez1,Sez2,Seznam1).
Večsmernost ne deluje pri aritmetičnih ukazih.
?- X is 2+18/5 X = 5.6 ?- 5.6 is A+B/C no
?- X = 2+18/5. X = 2+18/5
A+B/C = 2+18/5 A =2 B = 18 C = 5
Večsmernost izgubimo tudi, če uporabljamo posebne interne procedure za preverjanje enakosti.
element(a,[b,c,X,d]). X = a
X == a. %striktna enakost no
?- X = a, X == a. X = a yes
?- X == Y. no
?- X = Y, X == Y. X = Y yes
Uporaba element s striktno enakostjo.
element_striktni(El,[El1|_]) :- El == El1. element_striktni(El,[El1|_]) :- element_striktni(El,Rep).
Nivoji enakosti
- X = Y
- X se prilagodi Y
- X == Y
- izraza X in Y sta popolnoma enaka
- X =:= Y
- vrednosti aritmetičnih izrazov X in Y sta enaki
- X is Y
- X se lahko prilagodi vrednosti aritmetičnega izraza Y
Procedura za preverjanje
Procedura naj preveri, če se lahko prilagodita brez, da bi prilagoditev izvedla.
?- se_lahko_prilag(X,a). yes
?- se_lahko_prilag(f(X),f(Y)). yes
?- se_lahko_prilag(f(X),g(X)). no
%se_lahko_prilag(X,X). %tu se prilagoditev zgodi, tega nočemo
%negacija not nikoli ne opredeli
se_lahko_prilag(X,Y):-
not(not(X=Y)).
Rez ( ! )
Če uporabimo rez, procedura ni večsmerna.
preveri(X,Pogoj,Sez) :- Rel =.. [Pogoj,X], not(Rel), %v not(Cilj) :- call(Cilj),!,fail. imamo rez element(X,Sez).
p(a). p(b). p(c). ?- preveri(a,p,[a,b,c,d]). no ?- preveri(c,p,[a,b,c,d]). yes ?- preveri(e,p,[b,c,d]). no
Ker ni večsmerna je odgovor no.
?- preveri(X,p,[a,b,c,d]). no
Če želimo dvosmerno proceduro, moramo napisati proceduro tako da Rel ni neopredeljen.
preveri_dvosmerno(X,Pogoj,Sez) :- element(X,Sez), Rel =.. [Pogoj,X], not(Rel).
?- preveri_dvosmerno(X,p,[a,b,c,d,e]). X = c; X = e; no