Zaawansowany prolog Kunikowska Ewelina Grzechowski Ariel Krtkie przypomnienie

  • Slides: 65
Download presentation
Zaawansowany prolog Kunikowska Ewelina Grzechowski Ariel

Zaawansowany prolog Kunikowska Ewelina Grzechowski Ariel

Krótkie przypomnienie Term to: � stała, � zmienna, � struktura. Każdy term zapisywany jest

Krótkie przypomnienie Term to: � stała, � zmienna, � struktura. Każdy term zapisywany jest jako ciąg znaków, tworzących cztery kategorie: � duże litery: A-Z � małe litery: a-z � cyfry: 0 -9 � znaki specjalne

Krótkie przypomnienie Stałą nazywamy konkretne obiekty lub relacje. Istnieją dwa rodzaje stałych: � atomy

Krótkie przypomnienie Stałą nazywamy konkretne obiekty lub relacje. Istnieją dwa rodzaje stałych: � atomy � liczby Przykład: jas, malgosia, posiada, je Atomy składają się z: � symboli, � liter, cyfr znaku podkreślenia (zaczynamy zawsze małą literą), � dowolnych znaków, jeśli ujęte są w pojedynczy cudzysłów. Liczby: -17, 23, 99. 9, 123 e-3

Krótkie przypomnienie Zmienne mają postać atomu złożonego z liter, cyfr lub znaku podkreślenia z

Krótkie przypomnienie Zmienne mają postać atomu złożonego z liter, cyfr lub znaku podkreślenia z zastrzeżeniem, że pierwszym znakiem musi być duża litera. Czasem interesuje nas tylko czy coś jest prawdą, ale zupełnie interesuje nas co. � Jak sprawdzić, czy ktoś lubi Jasia? W takich sytuacjach możemy użyć zmiennej anonimowej zapisywanej jako jeden znak podkreślenia. lubi(_, jas).

Krótkie przypomnienie Struktura, inaczej term złożony, to obiekt złożony z innych obiektów. Przykład: posiada(‘Ewelina’,

Krótkie przypomnienie Struktura, inaczej term złożony, to obiekt złożony z innych obiektów. Przykład: posiada(‘Ewelina’, ’prawo jazdy’).

Struktury a drzewa Zwykle łatwiej jest zrozumieć budowę struktury, gdy jest ona zapisana w

Struktury a drzewa Zwykle łatwiej jest zrozumieć budowę struktury, gdy jest ona zapisana w postaci drzewa. W drzewie tym korzeniem jest funktor, a gałęziami elementy struktury. Ponadto struktury można zagnieżdżać.

Struktury a drzewa-przykład 1

Struktury a drzewa-przykład 1

Struktury a drzewa Drzewa również mogą opisywać zmienne w strukturach, w szczególności ukazując powiązania

Struktury a drzewa Drzewa również mogą opisywać zmienne w strukturach, w szczególności ukazując powiązania między nimi. Przykład:

Listy Lista to bardzo popularna struktura danych. Definiuje się ją jako ciąg uporządkowanych(tzn. kolejność

Listy Lista to bardzo popularna struktura danych. Definiuje się ją jako ciąg uporządkowanych(tzn. kolejność ma znaczenie) elementów dowolnej długości. Elementy mogą być dowolnymi termami: � stałymi � zmiennymi � innymi strukturami

Listy w Prologu Lista w Prologu to szczególny przypadek struktury, którą można zapisać w

Listy w Prologu Lista w Prologu to szczególny przypadek struktury, którą można zapisać w formie specjalnego rodzaju drzewa. Listę pustą oznaczamy poprzez [ ], a operatorem składania list jest. Ogólnie lista w Prologu dzieli się na dwie części : pierwszy element zwany głową oraz „resztę” zwaną ogonem

Listy w Prologu – przykłady � [a, b, c] w zapisie formalnym. (a, .

Listy w Prologu – przykłady � [a, b, c] w zapisie formalnym. (a, . (b, . (c , []))) � [[1, 2], [3]] w zapisie formalnym. (. (1, . (2, [])), . (. (3, []))

Listy w Prologu – c. d. Wróćmy do kwestii głowy i ogona. W zapisie

Listy w Prologu – c. d. Wróćmy do kwestii głowy i ogona. W zapisie formalnym wygląda to następująco: . ( głowa, ogon). Zapis ten ułatwia operator | , więc wygląda to tak: [ głowa|ogon] W takim razie przykłady z poprzedniego slajdu można zapisać następująco: � [a|b|c] � [[1|2]|[3]]

Listy w Prologu – c. d. Zapis ten uwidacznia się nie tyle dla konkretnych

Listy w Prologu – c. d. Zapis ten uwidacznia się nie tyle dla konkretnych list, co dla dopasowań. Rozważmy przykładową klauzulę: polacz. Listy( G, O, [ G| O]). Klauzula ta umożliwia � połączenie list G i O (polacz. Listy(1, [2, 3], X) da wynik X=[1, 2, 3]) � rozdzielenie gotowej listy na dwie pomniejsze (polacz. Listy(X, Y, [1, 2, 3]) da wynik X=1, Y=[2, 3])

Przeszukiwanie rekurencyjne Często konieczne jest przeszukiwanie struktur w Prologu celem znalezienia pewnych informacji. Kiedy

Przeszukiwanie rekurencyjne Często konieczne jest przeszukiwanie struktur w Prologu celem znalezienia pewnych informacji. Kiedy struktury mogą mieć inne struktury jako argumenty, konieczne jest przeszukiwanie rekurencyjne

Przeszukiwanie rekurencyjne Aby zrozumieć to zagadnienie, posłużymy się przykładem. Napiszmy ‘funkcję’, która sprawdzi przynależność

Przeszukiwanie rekurencyjne Aby zrozumieć to zagadnienie, posłużymy się przykładem. Napiszmy ‘funkcję’, która sprawdzi przynależność elementu do listy. Najpierw sprawdźmy, czy poszukiwany element jest w ‘głowie’ naszej listy.

Przeszukiwanie rekurencyjne Zatem taka klauzula wygląda następująco nalezy( X, [X|_]). Jednak co w przypadku,

Przeszukiwanie rekurencyjne Zatem taka klauzula wygląda następująco nalezy( X, [X|_]). Jednak co w przypadku, gdy nasz element nie znajduje się w ‘głowie’?

Przeszukiwanie rekurencyjne Trzeba sprawdzić, czy poszukiwany element jest w ‘ogonie’. Najlepiej będzie sprawdzić, czy

Przeszukiwanie rekurencyjne Trzeba sprawdzić, czy poszukiwany element jest w ‘ogonie’. Najlepiej będzie sprawdzić, czy element jest w pierwszym elemencie ‘ogona’.

Przeszukiwanie rekurencyjne Klauzula sprawdzająca ten przypadek wygląda następująco: nalezy( X, [ _|O]) : -

Przeszukiwanie rekurencyjne Klauzula sprawdzająca ten przypadek wygląda następująco: nalezy( X, [ _|O]) : - nalezy( X, O). Zauważmy, że klauzula ta odwołuje się do samej siebie.

Przeszukiwanie rekurencyjne W takim razie cała nasza ‘funkcja’ wygląda następująco: nalezy( X, [ X|

Przeszukiwanie rekurencyjne W takim razie cała nasza ‘funkcja’ wygląda następująco: nalezy( X, [ X| _]). nalezy( X, [ _|O]) : - nalezy(X, O).

Przeszukiwanie rekurencyjne Oczywiście naszą ‘funkcję’ można wykorzystać dwojako: � zgodnie z przeznaczeniem, czyli do

Przeszukiwanie rekurencyjne Oczywiście naszą ‘funkcję’ można wykorzystać dwojako: � zgodnie z przeznaczeniem, czyli do sprawdzania, czy element należy do listy (nalezy(2, [1, 2, 3]). uzyskamy true. ) � wywołując nalezy(X, [1, 2, 3]). uzyskamy wszystkie elementy z listy [1, 2, 3] (czyli: X=1; X=2; X=3)

Przeszukiwanie rekurencyjne Istotną kwestią związaną z rekurencją jest to, czy jest ona lewostronna. Z

Przeszukiwanie rekurencyjne Istotną kwestią związaną z rekurencją jest to, czy jest ona lewostronna. Z taką sytuacją spotkamy się, jeśli reguła powoduje wywołanie takiego samego celu, jak cel, który ją wywołał. Zobaczmy to na przykładzie

Przeszukiwanie rekurencyjneprzykład Zdefiniujmy taką zależność: osoba(X) : - osoba(Y), matka(X, Y). osoba( adam). I

Przeszukiwanie rekurencyjneprzykład Zdefiniujmy taką zależność: osoba(X) : - osoba(Y), matka(X, Y). osoba( adam). I zadajmy zapytanie osoba(X). Jak łatwo zauważyć, uzyskamy pętlę w teorii nieskończoną(w praktyce skończy się nam pamięć)

Przeszukiwanie rekurencyjneprzykład Jak to naprawić? Najłatwiej będzie po prostu zamienić kolejnością klauzule, tak aby

Przeszukiwanie rekurencyjneprzykład Jak to naprawić? Najłatwiej będzie po prostu zamienić kolejnością klauzule, tak aby rekurencja miała „na czym się zawiesić”. W większości ‘programów’ fakty, takie jak osoba(adam), powinny być umieszczane przed regułami.

Przeszukiwanie rekurencyjne Jakie są predykaty, w których fakty powinny być na końcu? Jednym z

Przeszukiwanie rekurencyjne Jakie są predykaty, w których fakty powinny być na końcu? Jednym z takich predykatów jest sprawdzenie, czy podany element jest listą.

Przeszukiwanie rekurencyjne Definicja tego predykatu wygląda następująco: jest. Lista([ X| Y]) : - jest.

Przeszukiwanie rekurencyjne Definicja tego predykatu wygląda następująco: jest. Lista([ X| Y]) : - jest. Lista( Y). jest. Lista( [] ). Polega on na sprawdzeniu, czy ostatni element ‘ogona’ jest listą pustą.

Przeszukiwanie rekurencyjne Niestety ten predykat nie jest odporny na zapętlenie, tzn. jeśli wywołamy jest.

Przeszukiwanie rekurencyjne Niestety ten predykat nie jest odporny na zapętlenie, tzn. jeśli wywołamy jest. Lista(X). , to wpadniemy w pętlę. Istnieją owszem ‘ulepszenia’ tego predykatu, żeby się nie zapętlał, jednak odbywa się to kosztem osłabienia działania

Przeszukiwanie rekurencyjneprzykład polepszenia jest. Lista() mocnejest. Lista([]). mocnejest. Lista([_|_]).

Przeszukiwanie rekurencyjneprzykład polepszenia jest. Lista() mocnejest. Lista([]). mocnejest. Lista([_|_]).

Nawracanie i odcięcie Wyobraźmy sobie rekurencję jako pewnego rodzaju drzewo, tzn. każde kolejne wywołanie

Nawracanie i odcięcie Wyobraźmy sobie rekurencję jako pewnego rodzaju drzewo, tzn. każde kolejne wywołanie jej powoduje utworzenie nowego poziomu w drzewie. Jeżeli w którymś momencie osiągamy coś niepożądanego, to cofamy się w rekurencji do poziomu wyżej anulując dotychczasowe wyniki i wybieramy kolejną opcję.

Nawracanie i odcięcie Podobnie działa interpreter Prologa. Podczas działania tworzy on ‘drzewo’ w głąb.

Nawracanie i odcięcie Podobnie działa interpreter Prologa. Podczas działania tworzy on ‘drzewo’ w głąb. Jeżeli coś zawodzi, anuluje ostatni krok i wyniki z nim związane oraz wybiera następną pasującą klauzurę. Działanie to nazywamy nawrotem. Oczywiście może okazać się, że ‘piętro wyżej’ nie ma już wolnych klauzur, więc cofamy się o kolejne piętro do góry…

Nawracanie i odcięcie … i w górę … aż znajdziemy się w korzeniu i

Nawracanie i odcięcie … i w górę … aż znajdziemy się w korzeniu i nie będzie alternatywnych klauzur do rozważenia. Wówczas osiągniemy wartość false oznaczającą ‘zawód globalny’.

Nawracanie i odcięcie Jednakże dzięki nawrotowi możemy uzyskać wszystkie możliwe rozwiązania danego zapytania, np.

Nawracanie i odcięcie Jednakże dzięki nawrotowi możemy uzyskać wszystkie możliwe rozwiązania danego zapytania, np. nalezy(X, [1, 2, 3]). dzięki mechanizmowi nawrotów wyświetli wszystkie elementy listy [1, 2, 3].

Nawracanie i odcięcie Pewną kontrolę nad nawrotami daje nam bezargumentowy funktor odcięcia wyrażany za

Nawracanie i odcięcie Pewną kontrolę nad nawrotami daje nam bezargumentowy funktor odcięcia wyrażany za pomocą !. Dojście do niego powoduje, że od chwili wykorzystania w rekurencji klauzuli zawierającej owo odcięcie do chwili dojścia do niego jako podcelu zostają uznane za ostateczne, czyli nie mogą być anulowane.

Nawracanie i odcięcie Najlepiej będzie to widać na przykładzie: Załóżmy, że nasza klauzula wygląda

Nawracanie i odcięcie Najlepiej będzie to widać na przykładzie: Załóżmy, że nasza klauzula wygląda następująco: a(X) : - b(X), c(X), !, d(X). Dojście do odcięcia uniemożliwia nawrót do b(X) i c(X), zatem jeśli zawiedzie d(X), to zawiedzie całe a(X).

Typowe zastosowanie odcięcia Można je podzielić na 3 grupy 1) Kiedy chcemy poinformować, że

Typowe zastosowanie odcięcia Można je podzielić na 3 grupy 1) Kiedy chcemy poinformować, że znaleźliśmy odpowiednią regułę. 2) Kiedy chcemy poinformować, że dany cel ma zawieść bez sprawdzenia alternatywnych rozwiązań 3) Kiedy należy zaprzestać generowaniu alternatywnych rozwiązań przez nawracanie

Niebezpieczeństwa związane z odcięciem Posłużmy się przykładem. Mamy predykat stwierdzający ile rodziców ma dana

Niebezpieczeństwa związane z odcięciem Posłużmy się przykładem. Mamy predykat stwierdzający ile rodziców ma dana osoba. Z Biblii wiemy, że ile. Rodzicow( adam, 0) : - !. ile. Rodzicow( ewa, 0) : - !. Natomiast reszta ludzi: ile. Rodzicow(X, 2).

Niebezpieczeństwa związane z odcięciem Jeżeli zapytamy ile. Rodzicow( ewa, X) , otrzymamy X=0. Jeżeli

Niebezpieczeństwa związane z odcięciem Jeżeli zapytamy ile. Rodzicow( ewa, X) , otrzymamy X=0. Jeżeli zapytamy ile. Rodzicow( robert, X) , otrzymamy X=2. Jednak jeśli chcemy sprawdzić, czy Ewa ma dwoje rodziców, to zapiszemy ile. Rodzicow(ewa, 2).

Niebezpieczeństwa związane z odcięciem I tu wyskakuje zonk. Okazuje się, że Ewa ma 2

Niebezpieczeństwa związane z odcięciem I tu wyskakuje zonk. Okazuje się, że Ewa ma 2 rodziców. Dlaczego? Jest to konsekwencja sposobu przeszukiwania bazy przez Prolog. Jednak można temu zaradzić.

Niebezpieczeństwa związane z odcięciem ile. Rodzicow( adam, N) : - !, N=0. ile. Rodzicow(

Niebezpieczeństwa związane z odcięciem ile. Rodzicow( adam, N) : - !, N=0. ile. Rodzicow( ewa, N) : - !, N=0. ile. Rodzicow( X, 2). albo ile. Rodzicow( adam, 0) : - !. ile. Rodzicow( ewa, 0) : - !. ile. Rodzicow( X, 2) : - +(X= adam) , +(X= ewa).

Wejście i wyjście w Prologuwstęp Załóżmy, że mamy bazę wiedzy postaci: student(1, ’Ewelina’, 23).

Wejście i wyjście w Prologuwstęp Załóżmy, że mamy bazę wiedzy postaci: student(1, ’Ewelina’, 23). student(2, ’Robert’, 40). student(3, ‘Zuza’, 20).

Wejście i wyjście w Prologuczytanie z klawiatury Do odczytu z klawiatury służy predykat read.

Wejście i wyjście w Prologuczytanie z klawiatury Do odczytu z klawiatury służy predykat read. Do naszej bazy zdefiniujmy relację czytaj(X) : - read(D), student(D, X). , polegającą na odczytaniu numeru studenta i pokazaniu jego danych.

Wejście i wyjście w Prologuwypisywanie na ekran Do wypisywania na ekran służy predykat write.

Wejście i wyjście w Prologuwypisywanie na ekran Do wypisywania na ekran służy predykat write. Do naszej bazy zdefiniujmy relację pisz(X) : - student( X, Y), write(Y). polegającą na wypisaniu na ekran danych studenta o numerze X.

Wejście i wyjście w Prologuczytanie z pliku czytajz. Pliku : open(‘sciezka_do_pliku', read, X), current_input(W),

Wejście i wyjście w Prologuczytanie z pliku czytajz. Pliku : open(‘sciezka_do_pliku', read, X), current_input(W), set_input(X), czytaj. Kod, close(X), set_input(W). czytaj. Kod : - read(T), write(T).

Wejście i wyjście w Prologuczytanie z pliku czytajz. Pliku : open(‘sciezka_do_pliku', read, X), //otworzenie

Wejście i wyjście w Prologuczytanie z pliku czytajz. Pliku : open(‘sciezka_do_pliku', read, X), //otworzenie pliku current_input(W), //zapis strumienia wejścia do W set_input(X), //zmiana wejścia na X czytaj. Kod, //wykonanie czytaj. Kod close(X), //zamknięcie wejścia X set_input(W). //zmiana wejścia na W czytaj. Kod : - read(T), write(T).

Wejście i wyjście w Prologuczytanie z pliku Domyślnym strumieniem wejściowym jest klawiatura. Jednakże czytaj.

Wejście i wyjście w Prologuczytanie z pliku Domyślnym strumieniem wejściowym jest klawiatura. Jednakże czytaj. Kod odczytuje tylko jeden wiersz z pliku. Aby odczytywać ich więcej należy go lekko zmodyfikować. czytaj. Kod : - read(T), wykonaj(T). wykonaj( end_of_file ) : - !. wykonaj(T) : - write(T), nl, czytaj. Kod. // nl- nowa linia

Wejście i wyjście w Prologuzapis do pliku piszdo. Pliku : open(‘sciezka_do_pliku', write, X), current_output(W),

Wejście i wyjście w Prologuzapis do pliku piszdo. Pliku : open(‘sciezka_do_pliku', write, X), current_output(W), set_output(X), pisz. Kod, close(X), set_output(W). pisz. Kod : - write(T), nl.

Wejście i wyjście w Prologuzapis do pliku piszdo. Pliku : open(‘sciezka_do_pliku', write, X), //otworzenie

Wejście i wyjście w Prologuzapis do pliku piszdo. Pliku : open(‘sciezka_do_pliku', write, X), //otworzenie pliku current_output(W), //zapis aktualnego wyjścia do W set_output(X), //zmiana aktualnego wyjścia na X pisz. Kod, //wykonanie pisz. Kod close(X), //zamkniecie wyjścia X set_output(W). //zmiana wyjścia na W pisz. Kod : - write(T), nl.

Wejście i wyjście w Prologuzapis do pliku Domyślnym strumieniem wyjściowym jest ekran. Oczywiście można

Wejście i wyjście w Prologuzapis do pliku Domyślnym strumieniem wyjściowym jest ekran. Oczywiście można zmodyfikować pisz. Kod tak, aby końcem zapisu było wpisanie ‘pa’: pisz. Kod : - read(X), +(X=‘pa'), write(X), nl, flush, Pisz. Kod. //flush czyści bufor

Predykaty wbudowane możemy podzielić na kilka kategorii, m. in. : � Sukces i porażka

Predykaty wbudowane możemy podzielić na kilka kategorii, m. in. : � Sukces i porażka � Klasyfikacja termów � Wpływ na nawracanie � Równość � Wejście i wyjście � Obsługa plików � Arytmetyka � Porównanie � I wiele, wiele innych …

Predykaty wbudowane- Sukces i porażka Do tych predykatów zaliczamy: ü true – ten cel

Predykaty wbudowane- Sukces i porażka Do tych predykatów zaliczamy: ü true – ten cel nigdy nie zawodzi. Nie jest on niezbędny, gdyż klauzury i cele można tak ustawić, żeby był zbędny. Jednak dla wygody go zdefiniowano. ü fail – ten cel zawsze zawiedzie. Przydatny w parze z odcięciem albo gdy chcemy jawnie wywołać nawracanie.

Predykaty wbudowane. Klasyfikacja termów � var(X) – nie zawodzi, gdy X jest zmienną nieukonkretnioną

Predykaty wbudowane. Klasyfikacja termów � var(X) – nie zawodzi, gdy X jest zmienną nieukonkretnioną � nonvar(X) – przeciwieństwo var(X) � atom(X) – nie zawodzi, jeśli X jest atomem � number(X) – nie zawodzi, jeśli X jest liczbą � atomic(X) – nie zawodzi, jeśli X jest liczbą lub atomem

Predykaty wbudowane. Klasyfikacja termów � integer(X) – jest spełniony, jeśli X jest stałą lub

Predykaty wbudowane. Klasyfikacja termów � integer(X) – jest spełniony, jeśli X jest stałą lub zmienną całkowitą � real(X) – jest spełniony, jeśli X jest stałą lub zmienną stałoprzecinkową

Predykaty wbudowane- Wpływ na nawracanie � repeat – to dodatkowa metoda generowania wielu rozwiązań

Predykaty wbudowane- Wpływ na nawracanie � repeat – to dodatkowa metoda generowania wielu rozwiązań przez nawracanie � ! – na odcięcie można patrzeć jako na predykat wbudowany zatwierdzający pewne wybory dokonane przez interpreter.

Predykaty wbudowane. Równość � X=Y – gdy Prolog napotyka taki cel, stara się zrównać

Predykaty wbudowane. Równość � X=Y – gdy Prolog napotyka taki cel, stara się zrównać X z Y dopasowując je do siebie. Jeśli to możliwe, to cel jest uzgodniony, w przeciwnym wypadku zawodzi. � X==Y – powoduje on ‘lepsze’ zrównanie X i Y. Jeśli X==Y, to X=Y, ale nie odwrotnie.

Predykaty wbudowane- Wejście i wyjście � get_char(X) – nie zawodzi, jeśli X można dopasować

Predykaty wbudowane- Wejście i wyjście � get_char(X) – nie zawodzi, jeśli X można dopasować do następnego znaku z bieżącego strumienia wejściowego. Może być uzgodniony tylko raz! � read(X) – odczytuje term z bieżącego strumienia wejściowego i dopasowuje go do X. Musi kończyć się kropką.

Predykaty wbudowane- Wejście i wyjście � put_char(X) – wpisuje do bieżącego strumienia wyjściowego znak

Predykaty wbudowane- Wejście i wyjście � put_char(X) – wpisuje do bieżącego strumienia wyjściowego znak X � nl – wpisuje do bieżącego strumienia wyjściowego sekwencję powodującą przejście do nowego wiersza. � write(X) – powoduje zapisanie termu X do bieżącego strumienia wyjściowego.

Predykaty wbudowane. Obsługa plików � open(X, Y, Z) – otwiera plik o nazwie X.

Predykaty wbudowane. Obsługa plików � open(X, Y, Z) – otwiera plik o nazwie X. Jeśli Y jest read, to w trybie odczytu, w przeciwnym razie w trybie zapisu. Z oznacza strumień, do którego należy używać podczas odwoływania się do pliku � close(X) – używany do zamknięcia strumienia X

Predykaty wbudowane. Obsługa plików set_input(X) – ustawia bieżący strumień wejściowy na wskazany przez X

Predykaty wbudowane. Obsługa plików set_input(X) – ustawia bieżący strumień wejściowy na wskazany przez X � set_output(X) – ustawia bieżący strumień wyjściowy na wskazany przez X � current_input(X) – cel jest uzgodniony, jeśli nazwa bieżącego strumienia wejściowego pasuje do X. W przeciwnym razie zawodzi � current_output(X) - cel jest uzgodniony, jeśli nazwa bieżącego strumienia wyjściowego pasuje do X. W przeciwnym razie zawodzi �

Predykaty wbudowane. Arytmetyka �X is Y �X + Y �X - Y �X *

Predykaty wbudowane. Arytmetyka �X is Y �X + Y �X - Y �X * Y �X / Y � X mod Y Pozostawię to bez omówienia

Predykaty wbudowane. Porównanie �X =Y �X < Y �X > Y � X >=

Predykaty wbudowane. Porównanie �X =Y �X < Y �X > Y � X >= Y � X =< Y To również pozostawię bez omówienia

Predykaty wbudowane. Porównanie Zasady decydujące, które z termów są mniejsze: v Wszystkie zmienne nieukonkretnione

Predykaty wbudowane. Porównanie Zasady decydujące, które z termów są mniejsze: v Wszystkie zmienne nieukonkretnione są mniejsze od wszystkich liczb zmiennoprzecinkowych. Te natomiast są mniejsze od wszystkich liczb całkowitych, które są mniejsze od wszystkich atomów, które są mniejsze od jakichkolwiek struktur

Predykaty wbudowane. Porównanie Zasady decydujące, które z termów są mniejsze: v W przypadku dwóch

Predykaty wbudowane. Porównanie Zasady decydujące, które z termów są mniejsze: v W przypadku dwóch niepowiązanych, nieukonkretnionych zmiennych zawsze jedna z nich będzie mniejsza od drugiej v Porównywanie liczb zmiennoprzecinkowych i całkowitych odbywa się zawsze zgodnie z intuicją

Predykaty wbudowane. Porównanie Zasady decydujące, które z termów są mniejsze: v Atom jest mniejszy

Predykaty wbudowane. Porównanie Zasady decydujące, które z termów są mniejsze: v Atom jest mniejszy od innego, jeśli występuje przed nim w zwykłym porządku słownikowym v Jedna struktura jest mniejsza od drugiej, jeśli jej funktor ma mniej argumentów. v Jeśli dwie struktury mają tyle samo argumentów, to mniejsza jest ta, której funktor jest mniejszy. v Jeśli dwie struktury mają tyle samo argumentów i takie same funktory, to bada się po kolei pierwszy z pierwszym, drugi z drugim itd.

Predykaty wbudowane. Porównanie X @< Y – nie zawodzi, jeśli X jest mniejszy od

Predykaty wbudowane. Porównanie X @< Y – nie zawodzi, jeśli X jest mniejszy od Y w porządku opisanym na poprzednich slajdach. � X @> Y – nie zawodzi, jeśli X jest większy od Y w porządku opisanym na poprzednich slajdach. � X @>= Y – nie zawodzi, jeśli X jest większy lub równy Y w porządku opisanym na poprzednich slajdach. � X @=< Y – nie zawodzi, jeśli X jest mniejszy lub równy Y w porządku opisanym na poprzednich slajdach. �

Przykłady

Przykłady

Dziękujemy za uwagę

Dziękujemy za uwagę