Kunikowska Ewelina Grzechowski Ariel

Slides:



Advertisements
Podobne prezentacje
Tablice 1. Deklaracja tablicy
Advertisements

Programowanie wizualne PW – LAB6 Wojciech Pieprzyca.
Schemat blokowy M START KONIEC
Równanie różniczkowe zupełne i równania do niego sprowadzalne
Wzorce.
Grażyna Mirkowska PJWSTK 15 listopad 2000
Programowanie w języku Visual Basic
Wykład 6 Najkrótsza ścieżka w grafie z jednym źródłem
PROGRAMOWANIE STRUKTURALNE
MS Access 2003 Kwerendy Paweł Górczyński.
20/09/ Języki programowania 1 Piotr Górczyński Kreator form.
Liczby Pierwsze - algorytmy
Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 8: Wykorzystanie procedur i funkcji © Jan Kaczmarek.
Macierze Maria Guzik.
Elementy kombinatoryki
Liczby całkowite.
Język ANSI C Operacje we/wy
Dr Anna Kwiatkowska Instytut Informatyki
Wprowadzenie do programowania w języku Turbo Pascal
AWK Zastosowania Informatyki Wykład 1 Copyright, 2003 © Adam Czajka.
Podstawy programowania
Podstawy programowania II Wykład 2: Biblioteka stdio.h Zachodniopomorska Szkoła Biznesu.
ADRESOWANIE WZGLĘDNE I BEZWZGLĘDNE Ćwiczenia
Pliki tekstowe. Operacje na plikach. mgr inż. Agata Pacek.
Andrzej Jędryczkowski Nie da się napisać większego programu bez podziału go na części zwane podprogramami. Podprogram to wyróżniona część programu.
© A. Jędryczkowski – 2006 r. © A. Jędryczkowski – 2006 r.
Poznaj bliżej program Microsoft Office Word 2007
TABLICE C++.
Definicja pliku tekstowego Operacje wykonywane na plikach tekstowych
Pliki Pojęcie i rodzaje plików Definicja typu plikowego Operacje wykonywane na plikach elementowych.
Pliki tekstowe – A. Jędryczkowski © 2007 Turbo Pascal umożliwia wykorzystanie w programach plików tekstowych. Pliki takie zawierają informację niezakodowaną
ANNA BANIEWSKA SYLWIA FILUŚ
Elementy Rachunku Prawdopodobieństwa i Statystyki
Systemy wspomagania decyzji
Systemy wejścia i wyjścia Michał Wrona. Co to jest system wejścia i wyjścia? Pobierania informacji ze źródeł danych, zdolnych przesyłać sekwencje bajtów,
Łódź, 3 października 2013 r. Katedra Analizy Nieliniowej, WMiI UŁ Podstawy Programowania Programy różne w C++
XML – eXtensible Markup Language
Systemy liczbowe.
Przekazywanie parametrów do funkcji oraz zmienne globalne i lokalne
MICROSOFT Access TWORZENIE MAKR
ZWIĄZKI MIĘDZY KLASAMI KLASY ABSTRAKCYJNE OGRANICZENIA INTERFEJSY SZABLONY safa Michał Telus.
Wykład 10 typ zbiorowy rekurencja.
PL/SQL – dalsza wędrówka
Projektowanie stron WWW
ZAPIS BLOKOWY ALGORYTMÓW
ALGORYTMY Co to jest algorytm ? Cechy algorytmu Budowa algorytmów
Excel Filtrowanie Funkcje bazodanowe
Algorytmy- Wprowadzenie do programowania
Krakowski Piotr, Woliński Radosław, Kowalski Piotr, Machowski Michał.
Warstwowe sieci jednokierunkowe – perceptrony wielowarstwowe
Listy Listy w Prologu mogą przechowywać dane dowolnego typu [alpha,beta,gamma,delta] [1,2,3] Sama lista również może zawierać listę: [[a,list,within],a,list]
Rozdział IV Wyrażenia proceduralne algorytmów Grzegorz Gacek Patryk Gajewski.
Wstęp do programowania Wykład 10 Programowanie w logice.
„Filtry i funkcje bazodanowe w EXCELU”
 Formuła to wyrażenie algebraiczne (wzór) określające jakie operacje ma wykonać program na danych. Może ona zawierać liczby, łańcuchy znaków, funkcje,
Liczby 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, …(i tak dalej) nazywamy liczbami naturalnymi. Tak jak z liter tworzy się słowa, tak z cyfr tworzymy liczby. Dowolną.
Temat: Tworzenie bazy danych
Liczbami naturalnymi nazywamy liczby 0,1,2,3,..., 127,... Liczby naturalne poznaliśmy już wcześniej; służą one do liczenia przedmiotów. Zbiór liczb.
Nawracanie i odcięcie Jakub Czoboda, Jezierski Aleksander, Skierkowski Paweł, Bembenista Kamil, Martynowski Witold.
PROLOG NAWRACANIE I ODCIĘCIE
Piotr Kawałek , Mateusz Śliwowski
Strumienie, Wczytywanie, Zapisywanie, Operacje na plikach
PROLOG z BLISKA Przygotowali: Konrad Daniszewski, Adam Kuliński, Konrad Poszwiński, Arkadiusz Trzciński.
Dane wejściowe/wyjściowe Wbudowane predykaty
Patryk Kłys Aleksandra dąbrowska
A closer look.
Wykonali: Jakub Gutkowski, Klaudia Belka, Damian Koncewicz
Prolog – Using Data Structures
Built-in Predicates Wbudowane predykaty
Haskell Składnia funkcji.
Zapis prezentacji:

Kunikowska Ewelina Grzechowski Ariel Zaawansowany prolog Kunikowska Ewelina Grzechowski Ariel

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 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, 123e-3

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 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’,’prawo jazdy’).

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 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ść 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 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, .(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 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]]

polaczListy( G, O, [ G| O]). Listy w Prologu – c.d. Zapis ten uwidacznia się nie tyle dla konkretnych list, co dla dopasowań. Rozważmy przykładową klauzulę: polaczListy( G, O, [ G| O]). Klauzula ta umożliwia połączenie list G i O (polaczListy(1,[2,3],X) da wynik X=[1,2,3]) rozdzielenie gotowej listy na dwie pomniejsze (polaczListy(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 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ść 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, gdy nasz element nie znajduje się w ‘głowie’?

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]) :- 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| _]). nalezy( X, [ _|O]) :- nalezy(X, O).

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 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 rekurencyjne- przykł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 rekurencyjne- przykł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 takich predykatów jest sprawdzenie, czy podany element jest listą.

Przeszukiwanie rekurencyjne Definicja tego predykatu wygląda następująco: jestLista([ X| Y]) :- jestLista( Y). jestLista( [] ). 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 jestLista(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 rekurencyjne- przykład polepszenia jestLista() mocnejestLista([]). mocnejestLista([_|_]).

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. 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ę 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. 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 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 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 Kiedy chcemy poinformować, że znaleźliśmy odpowiednią regułę. Kiedy chcemy poinformować, że dany cel ma zawieść bez sprawdzenia alternatywnych rozwiązań 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 osoba. Z Biblii wiemy, że ileRodzicow( adam, 0) :- !. ileRodzicow( ewa, 0) :- !. Natomiast reszta ludzi: ileRodzicow(X,2).

Niebezpieczeństwa związane z odcięciem Jeżeli zapytamy ileRodzicow( ewa, X) , otrzymamy X=0. Jeżeli zapytamy ileRodzicow( robert, X) , otrzymamy X=2. Jednak jeśli chcemy sprawdzić, czy Ewa ma dwoje rodziców, to zapiszemy ileRodzicow(ewa,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 ileRodzicow( adam, N) :- !, N=0. ileRodzicow( ewa, N) :- !, N=0. ileRodzicow( X, 2). albo ileRodzicow( adam, 0) :- !. ileRodzicow( ewa, 0) :- !. ileRodzicow( X, 2) :- \+(X= adam) , \+(X= ewa).

Wejście i wyjście w Prologu- wstę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 Prologu- czytanie 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 Prologu- wypisywanie 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 Prologu- czytanie z pliku czytajzPliku :- open(‘sciezka_do_pliku',read,X), current_input(W), set_input(X), czytajKod, close(X), set_input(W). czytajKod :- read(T), write(T).

Wejście i wyjście w Prologu- czytanie z pliku czytajzPliku :- 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 czytajKod, //wykonanie czytajKod close(X), //zamknięcie wejścia X set_input(W). //zmiana wejścia na W czytajKod :- read(T), write(T).

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

Wejście i wyjście w Prologu- zapis do pliku piszdoPliku :- open(‘sciezka_do_pliku',write,X), current_output(W), set_output(X), piszKod, close(X), set_output(W). piszKod :- write(T), nl.

Wejście i wyjście w Prologu- zapis do pliku piszdoPliku :- 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 piszKod, //wykonanie piszKod close(X), //zamkniecie wyjścia X set_output(W). //zmiana wyjścia na W piszKod :- write(T), nl.

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

Predykaty wbudowane 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 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ą 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 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ń 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ć 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ć 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 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. 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 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 * Y X / Y X mod Y Pozostawię to bez omówienia 

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: 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: W przypadku dwóch niepowiązanych, nieukonkretnionych zmiennych zawsze jedna z nich będzie mniejsza od drugiej 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: Atom jest mniejszy od innego, jeśli występuje przed nim w zwykłym porządku słownikowym Jedna struktura jest mniejsza od drugiej, jeśli jej funktor ma mniej argumentów. Jeśli dwie struktury mają tyle samo argumentów, to mniejsza jest ta, której funktor jest mniejszy. 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 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

Dziękujemy za uwagę 