programista w świecie RDF
O tym, że opis rzeczywistości funkcjonujący w Sieci Semantycznej może być w pewien szczególny sposób interesujący dla programisty już kiedyś wspominałem. Niestety zrobiłem to jak zwykle od środka i poza kontekstem, więc pewnie z czasem nawet ja sam zapomnę o co tam chodziło i dlaczego. Opublikowany stosunkowo niedawno tekst A Semantic Web Primer for Object-Oriented Software Developers natchnął mnie do zrewidowania sprawy i napisania bardziej uporządkowanej (no chociaż troszkę) notatki na temat porównania modelu obiektowego i modelu RDF.
ruszamy stępa — RDF
Opis zasobów (dowolnych) przy użyciu Resource Description Framework jest sam w sobie pomysłem tak prostym, że aż genialnym. Trójka {podmiot, predykat, obiekt} odzwierciedla naturalny dla człowieka sposób wypowiadania się o rzeczywistości.
- „MiMaS stworzył tę stronę” — {
http://mimas.ceti.pl/pub/mimas.rdf#mimas foaf:made http://mimas.ceti.pl/tarpit/
} - „ta strona jest zatytułowana TheTarPit” — {
http://mimas.ceti.pl/tarpit/ dc:title "TheTarPit"
} - „strona jest opublikowana na licencji CC” — {
http://mimas.ceti.pl/tarpit/ cc:licence http://creativecommons.org/licenses/by-nc-sa/2.5/
}
I tak dalej, i tak dalej. Praktycznie wszystko o wszystkim można wyrazić w postaci trójki: {zasób, cecha, wartość}. A że używa się do tego URI oraz przestrzeni nazw i typów danych rodem z XML-a zamiast języka naturalnego — cóż, taka rzeczywistość dzisiejszej informatyki...
Jednak sam RDF nie daje wiele więcej niż ciekawy sposób opisania danych jakichkolwiek w sposób przetwarzalny maszynowo, a nie wymagający stworzenia formalnego DTD. Stanowi natomiast podstawę, na której można budować konstrukcje zaawansowane, a nawet faktycznie przydatne.[1]
kłus — RDFS
Sprawy interesujące z punktu widzenia programisty zaczynają się wyżej. Na RDF oparta jest specyfikacja RDF Schema (właściwie: RDF Vocabulary Description Language) wprowadzająca pojęcia klasy i własności oraz parę wariacji na ich temat. Pojęcia te wydają się znajome, jednak wbrew pozorom nie są tak całkiem podobne do analogicznych pojęć współczesnych języków obiektowych.[2] Wszystko rozbija się o fakt, że modele opisane przez RDF (i pochodne) muszą funkcjonować w Internecie, który jest środowiskiem otwartym tak bardzo, że bardziej już chyba nie można.
Podstawowa różnica między klasami w programowaniu (czy modelowaniu raczej) obiektowym, a klasami w RDF, może być albo prosta do zrozumienia, albo całkowicie niejasna, w zależności od tego czy rozumiesz pojęcie klasy na poziomie analityczno-projektowym, czy uważasz ją tylko za konstrukcje programistyczną. W modelowaniu obiektowym klasa definiuje zbiór cech i możliwych zachowań pewnego rodzaju obiektów, czyli określa typ instancji. Jeśli obiekt jest instancją jakiejś klasy, jakiegoś typu, to oznacza, że posiada określone cechy (własności, pola) i możliwe zachowania (metody). Czyli o cechach obiektu wnioskujemy na podstawie jego klasy. To się potem wprost przenosi na programowanie — programista opisuje konstrukcję klasy wyliczając jej pola i metody. Dalej mając instancje tej klasy (obiekty) wie z całą pewnością jakiego może po nich oczekiwać zachowania.
W modelu RDF podejście do pojęcia klasy jest zupełnie inne. Definicja klasy (rdfs:Class
) i własności (rdf:Property
) nie specyfikuje szczegółów typu instancji tylko podaje sposób opisania jakiegoś dowolnego istniejącego obiektu („zasobu” w nomenklaturze RDF). Co więcej własności w RDF nie są częścią składową definicji klasy, tak jak w modelowaniu obiektowym, lecz niezależnie zdefiniowanym bytem (rdf:Property
jest instancją rdfs:Class
). Każda klasa może być opisana jako podklasa jakiejś innej. Każda własność może (choć wcale nie musi!) wskazywać jakiej klasy dotyczy i jakie mogą być jej wartości, jak również może być opisana jako podwłasność innej własności. W efekcie daje to mechanizm całkowicie odwrotny w porównaniu z modelowaniem obiektowym — klasy i własności stanowią opis cech jakie musi spełniać obiekt by należeć do danej klasy. Jeżeli obiekt ich nie spełnia — nie należy do danej klasy, jeżeli spełnia wymagania kilku klas — należy do nich wszystkich równocześnie.
W efekcie takiego podejścia do definicji klasy zupełnie inaczej wygląda również praca z instancjami obiektów czyli zasobów. Nie możemy powiedzieć tak jak w programowaniu obiektowym, że jeśli zasób jest instancją jakiejś klasy to znaczy, że ma takie a nie inne cechy, czyli wiemy o nim wszystko. Wręcz przeciwnie — dowolny zasób może być równocześnie instancją nieskończonej liczby innych klas, o których możemy wiedzieć mało albo i nic wcale. Ba, te klasy mogą nawet powstać później niż sam zasób, a i tak może on do nich należeć. Możemy za to wnioskować w kierunku przeciwnym — jeżeli definicja własności podaje jakiej klasy ona dotyczy (rdfs:domain
) to fakt, że zasób posiada jakąś własność oznacza, że należy on do tej klasy. Nie jak w programowaniu obiektowym — należy do klasy, to posiada określoną własność, tylko odwrotnie — posiada taką własność, to musi znaczyć, że należy do określonej klasy. Podobnie jeśli definicja własności podaje klasę wartości (rdfs:range
) to fakt, ze jakiś zasób jest użyty jako wartość w wyrażeniu RDF, którego predykatem jest ta własność, oznacza, że zasób ten jest instancją danej klasy.
galop — OWL
Powyższe jest jeszcze całkiem proste — komplikuje się dopiero wtedy, gdy zaczynamy korzystać z dobrodziejstw języka OWL. Web Ontology Language wprowadza do całej zabawy całkiem zaawansowane mechanizmy logiki (description logic) i umożliwia opisywanie klas modelu RDF w taki sposób, by wystarczyło to do budowania ontologii z dowolnej dziedziny pojęciowej.
Z punktu widzenia rozpatrywanych różnic względem modelowania obiektowego, najistotniejszy jest fakt, że OWL umożliwia takie zdefiniowanie klasy, że przynależność do niej obiektu jest możliwa do ustalenia dopiero po jego zaistnieniu. W programowaniu obiektowym, gdzie klasa jest typem obiektu, nie może powstać instancja klasy nieznanej lub nieistniejącej. Natomiast w OWL naturalne są klasy „opisowe”, których definicja oparta jest na aktualnych cechach obiektów. Średnio inteligentne przykłady:
wszelkie możliwe rzeczy pochodzenia polskiego znajdujące się w moim pokoju
<owl:Class rdf:ID="MyRoomPolishStuff">
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="#hasOrigin" />
<owl:hasValue rdf:resource="&country;Poland" />
</owl:Restriction>
<owl:Restriction>
<owl:onProperty rdf:resource="#locatedIn" />
<owl:hasValue rdf:resource="#MyRoom" />
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>Po polsku: wszystko co spełnia takie ograniczenia, że dla własności
hasOrigin
ma wartośćPoland
(zdefiniowana w przestrzeni nazw wskazywanej przez jakąś tam encję&country;
, mniejsza o szczegóły) oraz dla własnościlocatedIn
ma wartośćMyRoom
. Wszystkie identyfikatory zaczynające się od#
oznaczają klasy OWL zdefiniowane w tym samym pliku, mniejsza o to jak dokładnie zdefiniowane, pewnie w jakiś podobnie zakręcony sposób.... oprócz kotów
<owl:Class>
<owl:intersectionOf rdf:parseType="Collection">
<owl:Class rdf:resource="#MyRoomPolishStuff" />
<owl:Class>
<owl:complementOf>
<owl:Restriction>
<owl:onProperty rdf:resource="#species" />
<owl:hasValue rdf:resource="&pets;Cat" />
</owl:Restriction>
</owl:complementOf>
</owl:Class>
</owl:intersectionOf>
</owl:Class>Po polsku: wszystko co należy równocześnie do zdefiniowanej wcześniej klasy
MyRoomPolishStuff
oraz do klasy rzeczy, które nie są takie, że dla cechyspecies
mają wartośćCat
(z jakiegoś tam&pets;
). Całkiem uzasadnione jest spojrzenie na to jak na definicję zbioru: przekrój zbioru opisanego wcześniej jakoMyRoomPolishStuff
oraz dopełnienia zbioru rzeczy spełniających podane ograniczenie.
Bardzo trudno zdefiniować takie klasy w językach obiektowych, chociaż jak widać bardzo łatwo w OWL. Wynika to oczywiście z faktu, że OWL jest językiem zaprojektowanym do opisu ontologii i pojęć, nie obiektów jako takich. Zresztą dokładnie tak jak OWL działa nasze postrzeganie świata — np. klasa osób znajdujących się w tym pokoju: w tej chwili do niej należę, jak wyjdę to należeć przestanę. Z punktu widzenia modelowania obiektowego, obiekt mnie opisujący musiałby wtedy zmienić swój typ... dlatego w programowaniu obiektowym nie stosuje się takich klas mimo, że świetnie funkcjonują one w naszym życiu codziennym.
Z powyższego wynika również kilka mniej rzucających się w oczy (i może mniej istotnych) różnic w modelach obiektowych i RDF. Tabelkę przedstawiającą ich syntetyczne podsumowanie zawiera wspomniany test A Semantic Web Primer for Object-Oriented Software Developers. Polecam :-)
Na marginesie: fakt, że definicja klasy obiektu może być opisana na podstawie wartości jego cech, że mogą powstawać nowe klasy w czasie, oraz że obiekt może zmieniać klasę w zależności od okoliczności, wynika konieczność istnienia mechanizmów potrafiących zanalizować definicje klas OWL łącznie z ich zależnościami i hierarchiami, a następnie ustalić jak wg danej ontologii można aktualnie określić podany zasób. Narzędzia takie noszą nazwę reasoner i ... właściwie stanowią materiał na zupełnie inny wpis...
[1] Co wcale nie jest oczywiste — wiele całkiem udanych koncepcji nie ma żadnego zastosowania praktycznego, albo ich wykorzystanie w realnym świecie „nie wychodzi” tak elegancko jak to wyglądało w teorii. Zresztą cała inżynieria oprogramowania jest właściwie o tym jak mogłoby być fajnie, gdyby nie to, że wcale tak nie jest...
[2] Mówiąc o „współczesnych językach obiektowych” mam tak naprawdę na myśli języki wcale nie szczególnie obiektowe (raczej heterogeniczne) ani też nie za bardzo współczesne, tylko takie, jakie są powszechnie rozumiane pod tym hasłem — na dzisiaj jest to Java i C#, ewentualnie C++.
patrz również:
2006.05.08 | 4 komentarze |
tagi » semantic web, rdf
Komentarze
#1 | 2006.05.08 09:01 | gshegosh
W końcu udało Ci się mnie zaciekawić tematem :)
Czy na chwilę obecną istnieją jakieś używalne narzędzia, które zatwardziałemu ;) programiście pozwoliłyby pobawić się RDFem i OWLem w taki sposób, by zastąpić/uzupełnić w Javie czy C# standardowe klasy rodem z OOP?
#2 | 2006.05.08 09:20 | MiMaS
Wspomiana publikacja zawiera dodatek, w którym są zawarte linki do stron różnych narzędzi. Podejrzewam, że jako programistę zainteresuje Cię głównie kategoria „APIs” i „Code generators”.
Dodatkowo warto rozejrzeć się po stronie Developers Guide to Semantic Web Toolkits for different Programming Languages.
#3 | 2006.05.10 01:33 | Michał Kwiatkowski
Tylko dlaczego to musi wyglądać tak XMLowato? Nie lepiej byłoby pójść w kierunku składni wyznaczonej przez języki pozwalające na programowanie logiczne? Czy ktoś pomyślał już o narzędziach, które pozwalałyby tłumaczyć kod milszy dla oka i umysłu na ten nieczytelny i trudny w modyfikacji format XMLowy? Idealnie gdyby podanego przez Ciebie OWLa można było zapisać następująco:
define MyRoomPolishStuff:
has self.hasOrigin, self.locatedIn
self.Origin is #Poland
self.locatedIn is #MyRoom
Nie trzeba by nawet opisu, bo składnia stanowi tłumaczenie samo w sobie. Piszę to nie znając stojących za tym standardów, chciałbym jednak dowiedzieć się jakie przesłanki stoją za użyciem XMLa. Czy chociażby dla OWLa nie można by uczynić pewnych rzeczy prostszymi i łatwiejszymy dla ludzi, którzy mają z tego korzystać? Naprawdę potrzebna jest niższa XMLowa wastwa?
#4 | 2006.05.10 08:36 | MiMaS
Tylko dlaczego to musi wyglądać tak XMLowato?
Nie musi. Powtarzam do znudzenia: RDF jest grafem, a RDF/XML to tylko jedna z możliwych serializacji tego grafu.
Zresztą RDF/XML jest okropny pod wieloma względami, przede wszystkim trudny do przetwarzania jako ... XML. Paradoks? Nie zupełnie — polecam np. taki eksperyment: graf składający się zaledwie z 3 trójek można zapisać w RDF/XML na 30 różnych sposobów! I wszystkie poprawne. Zresztą co to za dokument XML co nie ma żadnego DTD. Niemniej jednak jest to standard podany przez W3C i nim są zapisane wszystkie specyfikacje. Dlaczego? Nie wiem — może dlatego?
W praktyce jednak bardzo często stosuje się kilka innych sposbów zapisu, bardziej user friendly — N3 i Turtle są chyba najbardziej popularne.
Uwaga: Ze względu na bardzo intensywną działalność spambotów komentowanie zostało wyłączone po 60 dniach od opublikowania wpisu. Jeżeli faktycznie chcesz jeszcze skomentować skorzystaj ze strony kontaktowej.