Built-in Predicates Wbudowane predykaty Bartłomiej Sarzalski, Mateusz Chojnacki – Prolog 3
Entering New Clauses Standardowymi predykatami do wczytywania programów są: consult i reconsult ?- consult('lists.pro'). otwiera plik lists.pro i wczytuje klauzule z pliku do pamięci Prologa ? reconsult('lists.pro'). Ponowne wczytanie klauzuli do pamięci i automatyczne zastąpienie starych definicji
Entering New Clauses Jeżeli chcemy wczytać kilka plików do pamięci, możemy napisać: ?- ['file1.pro',file2.pro',file3.pro']. Jest to jednoznaczne z klauzulą ?- consult(file1.pro), consult(file2.pro), consult(file3.pro).
Success and Failure W normalnym toku wykonywania programu Prolog, cel się powiódł jeżeli jest zadowalający, i nie powiódł się jeżeli jest nie zadowalający. Istnieją dwa predykaty, które ułatwiają nam sprecyzować kiedy cel jest zadowalający a kiedy nie. true i fail
Success and Failure true Ten cel zawsze jest zadowalający – nie jest wymagany, istnieje dla wygody. fail Ten cel zawsze jest nie zadowalający. Jest użyteczny w dwóch przypadkach – w ‘cut fail’ kombinacji, czyli jeżeli wykonanie przechodzi do tego punktu, wtedy można porzucić próbę osiągnięcia tego celu oraz w przypadku kiedy chcesz użyć fail aby inny cel mógł przejść przez wszystkie rozwiązania .
Success and Failure ?- event(X, Y), phh(Y), fail. Wydrukuje wszystkie wydarzenia z bazy danych, używając event i phh – wtedy zwróci fail.
Classifying Terms Klasyfikacja termów Jeśli definiujemy predykaty, które potem mają być użyte z szerokim wachlarzem argumentów, potrzebne jest rozróżnienie w definicji, co z poszczególnymi rodzajami argumentami możemy zrobić. Np. Chcemy odróżnić przetwarzanie atomu od przetwarzania liczby. Do tego używamy predykatów: var(x) nonvar(x) atom(x) number(x) atomic(x)
Classifying Terms Klasyfikacja termów var(x) Cel var(x) nie zawodzi, jeśli x jest zmienną nieukonkretnioną. Przykładowy dialog wygląda tak: ?- var(x). yes ?- var(23). no ?- x = y, y = 23, var=(x).
Classifying Terms Klasyfikacja termów nonvar(x) Cel nonvar(x) nie zawodzi, jeśli x jest zmienną ukonkretnioną. Przykładowy dialog wygląda tak: nonvar(x) :- var(x), !, fail. nonvar(_).
Classifying Terms Klasyfikacja termów atom(x) Cel atom(x) nie zawodzi, jeśli x jest atomem Prologu. Przykładowy dialog wygląda tak: ?- atom(23). No ?- atom(gruszki). Yes ?- atom(‘/us/chris/pl.123’). ?- atom(‘’to jest łańcuch’’). ?- atom(x). ?- atom(ksiazka(bronte.w_w.X)). no
Classifying Terms Klasyfikacja termów number(x) Cel number(x) nie zawodzi, jeśli X jest liczbą atomic(x) Cel atom(x) nie zawodzi, jeśli X jest liczbą lub atomem. Predykat atomic można zdefiniować przy użyciu atom unumber: atomic(X) :- atom(X). atomic(X) :- number(X).
Treating Clauses as Terms Przetwarzanie klauzuli jako termów Prolog umożliwia programiście modyfikowanie programu (klauzuli używanych do spełnienia celów). Jest to tym prostsze, że na klauzule można spojrzeć jako na zwykłe struktury Prologu. Prolog zawiera predykaty wbudowane, które pozwalają programiście: Tworzyć strukturę reprezentującą klauzulę w bazie danych, Dodawać do bazy danych klauzulę zapisaną jako taka struktura, Usuwać z bazy danych klauzulę zapisaną jako taka struktura
Treating Clauses as Terms Przetwarzanie klauzuli jako termów Predykaty służące do badania i modyfikacji klauzul listing(A) Większość systemów Prologu pozwala podejrzeć załadowane klauzule, choć standard tego nie wymaga. Typowym rozwiązaniem jest użycie predykatu listing; spełnienie celu listing(A), gdzie zmienna A jest ukonkretniona atomem, wypisuje wszystkie klauzule o nazwie A. Użycie predykatu pozwala wykryć błędy w programie.
Treating Clauses as Terms Przetwarzanie klauzuli jako termów Na przykład w poniższym dialogu stwierdzamy, że predykat reverse nie został zdefiniowany prawidłowo ?- [test] test cosulted yes ?- reverse([a,b,c,d].X). no ?- listing(reverse). reverse([],[]). reverse([_44|_45],_38) :- reverse(_45, 47), appenD(_47,[_44]._38). Okazuje się, że nieprawidłowo zapisano atom append (appenD)
Treating Clauses as Terms Przetwarzanie klauzuli jako termów clause(X,Y) Spełnienie celu clause powoduje, że X i Y dopasowywane są do głowy i treści klauzuli z bazy danych. X musi być ukonkretniona przynajmniej na tyle, aby znany był główny funktor klauzuli. Jeżeli żadne klauzule nie zostaną znalezione, cel zawodzi.
Treating Clauses as Terms Przetwarzanie klauzuli jako termów asserta(X), assertz(X) Predykaty asserta i assertz pozwalają dodać do bazy danych dowe klauzule. Oba działają tak samo, tyle że asserta dodaje klauzule na początek bazy danych, a assertz na koniec.
Treating Clauses as Terms Przetwarzanie klauzuli jako termów retract(X) Predykat wbudowany retract umożliwia programowi usuwanie klauzuli z bazy danych. Predykat ten ma jeden argument odpowiadający termowi, którego klauzule są szukane. Term musi być ukonkretniony w dostatecznym stopniu aby można było określić klauzuę.
Handling Files Obsługa plików open(X,Y,Z) Cel ten otwiera plik o nazwie X(atom). Jeśli Y ma wartość read, plik jest otwierany do czytania, w przeciwnym razie jest otwierany do pisania. close(X) Predykat używany do zamknięcia strumienia o nazwie X. Strumień staje się niedostępny
Handling Files Obsługa plików set_input(X) Ustawia bieżący strumień wejściowy na strumień wskazany przez X. set_output(X) Ustawia bieżący strumień wyjściowy na strumień wskazany przez X. current_input(X) Cel jest uzgodniony, jeśli nazwa bieżącego strumienia pasuje do X, a zawodzi w przeciwnym razie. current_output(X) Cel jest uzgodniony, jeśli nazwa bieżącego strumienia wyjściowego pasuje do X, a zawodzi w przecinwym razie
Input and output Predykaty pozwalające odczytywać i zapisywać znaki i termy. get_char(X) Cel get_char(X) nie zawodzi jeśli X można dopasować do następnego znaku z bieżącego strumienia wejściowego. read(X) Cel ten odczytuje następny term z bieżącego strumienia wejściowego, następnie dopasowuje ten term do X. Odczytywany term musi być zakończony kropką
Input and output atom_chars(A, L) pozwala nam rozbić ciąg znaków na tablice pojedyńczych elementów lub z pojedyńczych znaków stworzyć ciąg np.: atom_chars(apple,X). X=[a,p,p,l,e] atom_chars(X,[a,p,p,l,e]) X=apple
Input and output number_chars(A,L) pozwala nam rozbić liczbe na tablice pojedyńczych cyfr lub z pojedyńczych cyfr stworzyć liczbe np.: number_chars(123.5,X). X=['1','2','3','.','5'] number_chars(X,['1','2','3']) X=123
Input and output put_char(X) Cel put(X) wypisuje do bieżącego strumienia wyjściowego znak X. Jeśli argument X nie jest ukonkretniony, występuje błąd. nl Wypisuje do bieżącego strumienia wyjściowego sekwencję powodującą przejście do nowego wiersza. write(X) Cel write(X) powoduje zapisanie termu X do bieżącego strumienia wyjściowego. op(X,Y,Z) Cel op pozwala zadeklarować operator o priorytecie X, położeniu i łączności określonych argumentem Y i o nazwie Z. Położenie i łączność wyrażane są jednym z poniższych atomów: fx fy xf yf xfx xfy yfx yfy
Watching Prolog at Work Badanie działania Prologu trace Wynikiem uzgodnienia trace jest włączenie dokładnego raportowania wykonania programu. notrace Uzgodnienie celu notrace powoduje wyłączenie dokładnego raportowania wykonania programu. spy P Predykatu spy używa się, jeśli konieczne jest zwrócenie dokładniejszej uwagi na cele zawierające wybrane predykaty. debugging Pozwala sprawdzić jakie punkty śledzenia zostały ustawione. nodebugging Powoduje usunięcie wszystkich punktów śledzenia.
Comparing Terms Porównywanie termów X+Y daje nam sume X i Y X-Y daje nam różnice X i Y X*Y daje nam iloczyn X i Y X/Y daje nam iloraz X i Y w postaci float X//Y daje nam iloraz X i Y w postaci int XmodY daje nam reszte z dzielenia X i Y X=:=Y sprawdzenie czy X i Y mają te same numeryczne wartości X=\=Y sprawdzenie czy X i Y mają różne numeryczne wartości X<Y sprawdzenie czy wartość X jest mniejsza od wartości Y X>Y sprawdzenie czy wartość X jest większa od wartości Y X>=Y sprawdzenie czy wartość X jest większa bądź równa wartości Y X=<Y sprawdzenie czy wartość X jest mniejsza bądź równa wartości Y
Comparing Terms Porównywanie termów Oto przykłady niezawodzących porównań dowolnych termów: ?- q(X) @< f(X,Y). ?- f(2,b) @< f(a,A). ?- 123 @< 124. ?- 123.5 @< 2. X @< Y Predykat nie zawodzi, jeśli jego lewy argument jest mniejszy od argumentu prawego przy takim uporządkowaniu, jakie opisano powyżej. X @> Y Predykat nie zawodzi, jeśli jego lewy argument jest większy od argumentu prawego przy takim uporządkowaniu, jakie opisano powyżej. X @<=Y Predykat nie zawodzi, jeśli jego lewy argument jest mniejszy od argumentu prawego przy takim uporządkowaniu, jakie opisano powyżej lub oba argumenty są takie same. X @>= Y Predykat nie zawodzi, jeśli jego lewy argument jest większy od argumentu prawego przy takim uporządkowaniu, jakie opisano powyżej lub oba arguenty są takie same