Spojrzenie na bazy danych oczami logika pozwala jednolicie opisać szereg używanych pojęć. Do opisu relacyjnych baz danych używa się zwykle rachunku predykatów bez symboli funkcyjnych.
Fakty zapisane w wierszach tabel reprezentuje się literałami, np. Ojciec(Jan,Piotr)
gdzie pierwszy symbol (Ojciec) odpowiada nazwie tabeli, a pozostałe zawartości pewnego wiersza w tej tabeli.
Taki sposób opisu obejmuje również najprostsze realizacje baz danych, np. gdy fakty przechowuje się w postaci pojedynczej listy, wczytywanej do pamięci z pliku podczas ładowania bazy danych i zapisywanej na pliku przy zamykaniu bazy.
Tak więc reprezentacją relacji Zwierzaki:
gatunek | imię | waga |
Papuga | Kropka | 3,50 |
Papuga | Lulu | 5,35 |
Papuga | Hipek | 3,50 |
Lis | Fufu | 6,35 |
Krokodyl | Czako | 75,00 |
będą następujące literały
Zwierzak(Papuga,Kropka,3.50) |
Zwierzak(Papuga,Lulu,5.35) |
Zwierzak(Papuga,Hipek,3.50) |
Zwierzak(Lis,Fufu,6.35) |
Zwierzak(Krokodyl,Czako,75.00) |
(dla nazwy relacji w rachunku predykatów użyjemy liczby pojedynczej, bo jest naturalniejsza).
W relacyjnych bazach danych obowiązuje założenie o zamkniętości świata.
Przyjmuje się, że jeśli fakt nie znajduje się w odpowiedniej tabeli w bazie danych, to nie zachodzi (jest fałszywy). Inaczej mówiąc, jeśli wiersz
nie znajduje się w relacji , to zachodzi
Mówiąc potocznie, jeśli czegoś nie wiem, to powinienem przyjąć, że nie jest to prawdziwe. W przeciwnym razie odpowiedzi na zapytanie SELECT w SQL musiałyby się kończyć frazą ,,… i być może jeszcze coś, o czym nie wiem”.
Dla bazy danych z podaną przed chwilą relacją Zwierzaki będzie więc spełnione (na przykład):
Zwierzak(Papuga,Czako,2.00) |
i wiele innych zanegowanych literałów.
Założenie o zamkniętości dziedziny (a właściwie dziedzin) mówi, że nie istnieją inne ,,obiekty” niż występujące w tabelach bazy danych.
Nie ma innych indywiduów niż te znajdujące się w bazie danych. Inaczej mówiąc, nie ma innych stałych niż te, które występują w wierszach bazy danych.
Założenie to spełniają systemy ograniczające niejawnie swoją dziedzinę ,,referencji”. Przykład: algebra relacji (bo wszelkie wyrażenia powstają przez składanie relacji początkowych).
W relacyjnych bazach danych używających SQL założenia tego nie spełniają oczywiście liczby całkowite i rzeczywiste. Zwykle natomiast spełniają je napisy, np. nie ima innych nazw zwierzaków niż te podane w tabeli Zwierz.
Indywidua (stałe) o różnych nazwach są różne. Inaczej mówiąc, nie ma aksjomatów równościowych dla stałych.
W naszej przykładowej bazie
Zwierzak(Papuga,Kropka,3.50) |
Zwierzak(Papuga,Lulu,5.35) |
Zwierzak(Papuga,Hipek,3.50) |
Zwierzak(Lis,Fufu,6.35) |
Zwierzak(Krokodyl,Czako,75.00) |
zachodzi
Zwierzak(Krokodyl,Fufu,6.35)
ponieważ zakładamy, że zachodzi
Krokodyl Lis
Do zapisywania zapytań będziemy używać formuł zawierających zmienne.
Ograniczymy się do formuł prostych.
Zapytania mają wtedy postać wzorców — struktur podobnych do faktów, mogących jednak zawierać zmienne.
Zmiennymi będą symbole poprzedzone znakami zapytania, np. Ojciec(Jan,?x)
jest zapytaniem o wszystkie dzieci Jana.
Odpowiedź na zapytanie składa się z bezpośrednio wyszukanych faktów pasujących do zapytania oraz z faktów wyprowadzonych przy użyciu reguł.
Klauzulą nazywać będziemy formułę postaci
lub też równoważnie
Wyrażenia nazywać będziemy poprzednikami (lub przesłankami, zaś wyrażenia następnikami lub wnioskami klauzuli.
Klauzule bez poprzedników, zawierające tylko jeden następnik bez zmiennych
służą do reprezentowania faktów.
Klauzule bez następników
reprezentują negację poprzedników i mogą służyć do zapisywania ograniczeń (więzów poprawności). Stan bazy danych jest legalny, jeśłi nie jest spełniona koniunkcja poprzedników, np. Ojciec(?x,?y) Matka(?x,?y) .
Taka klauzula mająca tylko jeden poprzednik bez zmiennych zapisuje jawnie negację faktu, np. Ojciec(Jan,Piotr) .
oznacza, że Jan nie jest ojcem Piotra.
Klauzula o pojedynczym następniku
służy w dedukcyjnych bazach danych do definiowania relacji R.
Jak zobaczymy dalej, pełna definicja relacji może wymagać kilku klauzul.
W relacyjnych bazach danych klauzule takie (tak jak i następne) służą do zapisywania ograniczeń.
Klauzule postaci
wyrażają wiedzę niekompletną: wiemy, że spełniony jest jeden lub więcej następników, ale nie wiemy który.
Przykład: Student(Jan,Matematyka) Student(Jan,Biologia)
Klauzulą o pełnej postaci
można interpretować jako warunkowe informacje o niekompletnej wiedzy.
Można też ich używać jako ograniczeń, np. aby zapisać, że każdy ma co najwyżej dwoje rodziców użyjemy
Rodzic(?p,?a) Rodzic(?q,?a) Rodzic(?r,?a) (?p = ?q) (?p = ?r) (?q = ?r)
Klauzula pusta, czyli klauzula bez poprzedników i następników, oznacza fałsz.
Klauzula taka nie powinna nigdy wystąpić w niesprzecznej bazie danych.
W dedukcyjnych bazach danych dopuszcza się tylko niektóre rodzaje klauzul z programowania w logice.
Nakłada sie dodatkowe ograniczenia.
Brak symboli funkcyjnych.
Tylko jeden następnik.
Takie dedukcyjne bazy danych określa się jako definite.
Zmienna z konkluzji reguły musi wystąpić w jej treści.
Zapewnia to spełnienie założenia o zamkniętości dziedziny.
Jako predykaty obliczalne dozwolona tylko arytmetyka.
Zauważmy, że formalnie narusza to założenie o zamkniętości dziedziny.
Jednym z takich rozszerzeń relacyjnych baz danych jest Datalog.
W Datalogu klauzule zapisujemy jako reguły.
Każdy predykat jest
albo ekstensjonalny: zdefiniowany wyłącznie przez fakty zapisane w bazie danych,
albo intensjonalny: zdefiniowany wyłącznie przez reguły.
Reguły mają nieco zmienioną postać zapisu następnik <- poprzednik AND ...
przy czym zarówno następnik jak i poprzedniki mają postać wzorców, na przykład P(?x,?y,?z) <- Q(?x,?y,?z) AND x > 10
Ponieważ takie reguły, podobnie jak klauzule, odpowiadają implikacjom z logiki, posiadają one zarówno interpretację logiczną jak i proceduralną.
Na przykład regule
Dziadek(?x,?z) <- Ojciec(?x,?y) AND Ojciec(?y,?z)
odpowiada implikacja Ojciec() Ojciec() Dziadek()
Jeśli reguła nie zawiera poprzedników, to jej następnik jest zawsze spełniony.
Podobnie jak fakty, reguły przechowuje się także w bazie danych.
Reguła pasuje do zapytania, jeśli jej konkluzja pasuje do zapytania.
Znajdowanie odpowiedzi na zapytanie przy użyciu reguł polega na znalezieniu reguł pasujących do zapytania i dla każdej z nich wyszukanie w sposób spójny (tzn. tak, żeby wartości zmiennych były zgodne) odpowiedzi na podzapytania powstałe z przesłanek (czyli rekursja :-) i złożenie otrzymanych wyników, podstawiając otrzymane wartości zmiennych na zmienne w konkluzji.
Ostateczną odpowiedzią na zapytanie jest lista wyszukanych faktów (dla reguł będą to konkretyzacje ich konkluzji).
Pozwalają otrzymywać odpowiedzi wymagające domknięcia przechodniego.
Przykład:
Mamy tabelę Zawiera(obiekt,składnik,ile) dotyczącą pojazdów (np. rowerów, sanek itp.) podającą obiekty i ich bezpośrednie składowe.
Chcemy otrzymać informację o wszystkich częściach wchodzących w skład obiektu 'rower'.
Zawiera
obiekt | składnik | ile |
---|---|---|
rower | koło | 2 |
koło | piasta | 1 |
koło | obręcz | 1 |
obręcz | szprycha | 20 |
koło | opona | 1 |
rower | rama | 1 |
rama | siodełko | 1 |
rama | kierownica | 1 |
Definicja w Datalogu
Czesci(?calosc,?czesc) <- Zawiera(?calosc,?czesc,?_). Czesci(?calosc,?czesc) <- Zawiera(?calosc,?skladnik,?_) AND Czesci(?skladnik,?czesc).
i samo zapytanie
Czesci('rower',?co) ?
W odróżnieniu od programowania w logice w Datalogu nie używa się nawracania.
Budowa odpowiedzi odbywa się bottom-up: rozpoczynamy od pustej relacji Czesci i iteracyjnie dodajemy do niej wszystkie wiersze, które w tym momencie można otrzymać z reguł.
Optymalizacja: w kążdym kroku używam reguł tylko dla wierszy dodanych w poprzednim kroku.
Zauważmy, że jest to typowy algorytm wyznaczania minimalnego punktu stałego (tzw. minimalnego modelu).
Z otrzymanej ekstensji relacji wybieramy tylko wiersze pasujące do zapytania.
Rozpoczynam od pustej tabeli Czesci.
Krok 1: z pierwszej reguły dodaję do niej wiersze <'rower','koło'>, <'koło','piasta'>, <'koło','obręcz'>, <'obręcz','szprycha'>, <'koło','opona'>, <'rower','rama'>, <'rama','siodełko'>, <'rama','kierownica'>.
Krok 2: używając drugiej reguły dodaję wiersze <'rower','piasta'>, <'rower','obręcz'>, <'rower','opona'>, <'rower','siodełko'>, <'rower','kierownica'>, <'koło','szprycha'>.
Krok 3: używając drugiej reguły dodaję wiersz <'rower','szprycha'>.
Krok 4: ponieważ żadna reguła nie produkuje już nowych wierszy, kończę iterację i wybieram wiersze <'rower','koło'>, <'rower','rama'>, <'rower','piasta'>, <'rower','obręcz'>, <'rower','opona'>, <'rower','siodełko'>, <'rower','kierownica'>, <'rower','szprycha'>.
Zapytania rekurencyjne w SQL-3 definiuje się konstrukcją
WITH [RECURSIVE] R(...) AS
zapytanie używające R
SELECT ...;
Można tak zdefiniować kilka pomocniczych relacji wzajemnie rekurancyjnych.
Zapiszemy nasze zapytanie z Datalogu w SQL
WITH RECURSIVE Czesci(calosc,czesc) AS (SELECT obiekt,skladnik FROM Zawiera) UNION (SELECT obiekt,czesc FROM Zawiera, Czesci WHERE skladnik = calosc) SELECT czesc FROM Czesci WHERE calosc = 'rower';
W poprzednikach reguł Datalogu można poprzedzać predykaty negacją NOT.
Taki literał jest spełniony, jeśli ta negacja jest prawdziwa dla tego predykatu w minimalnym modelu.
Aby można to było sprawdzać, program z negacjami musi być stratyfikowalny: reguły predykatów intensjonalnych dzielimy na warstwy tak, by
Definicja predykatu nie była w wyższej warstwie, niż jego wykorzystanie w definicjach innych predykatów.
Negacja predykatu występowała w wyższej warstwie niż jego definicja.
Minimalne punkty stałe wyznaczamy kolejno poczynając od najniższej warstwy.
Podobne ograniczenie na poprawność rekursji z negacją obowiązuje w SQL-3.
Treść automatycznie generowana z plików źródłowych LaTeXa za pomocą oprogramowania wykorzystującego LaTeXML.
strona główna | webmaster | o portalu | pomoc
© Wydział Matematyki, Informatyki i Mechaniki UW, 2009-2010. Niniejsze materiały są udostępnione bezpłatnie na licencji Creative Commons Uznanie autorstwa-Użycie niekomercyjne-Bez utworów zależnych 3.0 Polska.
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego.
Projekt współfinansowany przez Ministerstwo Nauki i Szkolnictwa Wyższego i przez Uniwersytet Warszawski.