Proceduralny prolog
Transkrypt
Proceduralny prolog
Proceduralny prolog Instrukcje warunkowe Ważną różnicą pomiędzy prologiem, a innymi językami jest możliwość wielokrotnego definiowania procedur pod innymi warunkami. writename(1) :- write('One'). writename(2) :- write('Two'). writename(3) :- write('Three'). writename(X) :- X<1, write('Out of range'). writename(X) :- X>3, write('Out of range'). Co oznacza : jeśli parametr = 1 wypisz „One” … jeśli parametr mniejszy od 1 wypisz „Out of range” jeśli parametr większy od 3 wypisz „Oute of range” Inna wersja programu warunkowego: writename(1) :- write('one'). writename(2) :- write('Two'). writename(3) :- write('Three'). writename(_) :- write('Out of range'). Problem Istnieje możliwość zwrócenia dwóch wartości np. dla 3 => ”Three” oraz „Out of range”. Jak temu zapobiec ? Operator Cut writename(1) :-!, write('One'). writename(2) :-!, write('Two'). writename(3) :-!, write('Three'). writename(_) :- write('Out of range'). Dodanie '!' powoduje przerwanie procesu 'backtracking' – innymi słowy spełnienie jednego warunku uniemożliwia spełnienie innego. Rodzaje Cut: writename(1) :- !, write('One'). writename(2) :- !, write('Two'). writename(3) :- !, write('Three'). writename(X) :-X<1, !, write('Out of range'). writename(X) :-X>3, write('Out of range'). Green Cut – ogranicza ilość zwracanych rezultatów Red Cut – jest to Green Cut z dodatkowym ograniczeniem możliwości wyboru. writename(1) :-!, write('One'). writename(2) :-!, write('Two'). writename(3) :-!, write('Three'). writename(_) :- write('Out of range'). Zoptymalizowane warunki. Jak widać jest to podział czysto koncepcyjny. Innym sposobem otrzymania tylko jednego rezultau jest once(). Instrukcja IF-THEN-ELSE Goa11 ->Goal2;Goal3. Co oznacz: If Goal1 then Goal2; else Goal3; writename(X) :- X = 1 -> write('one');write('note one'). Wymuszanie prawdy lub fałszu Fałsz make_fail(Goal):- write(Goal),!,fail. Prawda make_succeed(X,Y):- X<Y, write(X),write(' mniejsze od '),write(Y),!. make_succeed(_,_). Predykt repeat typewriter :- repeat, get0(Char), Char = 122. Program kończy się po wprowadzeniu 'z'. Predykt repeate działa do momentu osiągnięcia true. Zatem test_rep:- repeat,write('*'),fail. Jest nieskończoną pętlą. Rekuranecja – wywoływanie procedury przez samą siebie suma(I) :- I < 10, !. suma(I) :- I > 100, !. suma(I) :S is I+I, write(I), write(' '), write(S),nl, NewI is I+1, suma(NewI). Zoptymalizowana wersia rekurencji Tail recursion Inny przykład test_rec1(N) :- N>100,!. test_rec1(N) :- write(N),nl, NewN is N+1, test_rec1(NewN). Jest to rodzaj rekursji która odwołuje się do samej siebie na samym końcu. Dzięki temu na stosie nie odkładane są dodatkowe informacje. W działaniu przyponima pętle. Indeksowanie w prologu Dzięki indeksowaniu prolog omija niepasujące predykty w bazie danych , wybieraj ąc od razu szukane. a(b). a(c). d(e). d(f). Zapytanie „?-d(f) „ wybierze od razu d(f). Zmienne w prologu nie nie są globalne. Predykty są globalne. Zatem w obrębie jednego modułu nazwy predyktów są unikalne. Dokumentacja / komentarze %- komentarz '+' - parametr który powinnien być zdefiniowany '-' -parametr który zostanie zdefiniowany dopiero przez predykt '?' - parametr który może ale nie musi być zdefiniowany W pierwszej linii opis parametrów. %Squere(+X,-S) … => implementacja predyktu