Semantic Web
Sieć Semantyczna — zgodnie z wizją twórcy WWW, jest to sieć zrozumiała nie tylko dla człowieka, ale również dla maszyny (programu, „agenta”):
The Web was designed as an information space, with the goal that it should be useful not only for human-human communication, but also that machines would be able to participate and help. [...] Leaving aside the artificial intelligence problem of training machines to behave like people, the Semantic Web approach instead develops languages for expressing information in a machine processable form.
„Semantic Web Road map”, Tim Berners-Lee, 1998
SW to naturalna (trwająca już) ewolucja WWW — sieć danych zamiast sieci dokumentów.
Wymaga to opracowania specjalnych metod zapisu informacji i wiedzy w sposób zrozumiały dla agentów, ale równocześnie zdatny do obsługi przez człowieka.
Kolor niebieski = rekomendacje W3C.
Schemat przedstawia aktualny „stos” rekomendacji — każda następna warstwa wykorzystuje warstwę niższą. Jednak wprowadzenie języków opisu reguł („rules”) powoduje wątpliwości co do zasadności takiego założenia. Stąd powstają pomysły rozdzielenia „stosu” na „dwie wieże” — Rules obok OWL.
Rekomendacje W3C:
RDF — zasoby „identyfikowalne”, co nie koniecznie oznacza „możliwe do pobrania”. Więc nie tylko zasoby Sieci, ale również wszelkie obiekty świata rzeczywistego.
W najnowszych opracowaniach identyfikowalne raczej za pomocą IRI, nie URI.
Never forget: only the graph is “real”, the rest is convenience!
Niestety graf RDF jest możliwy do wyrysowania tylko na jednym „poziomie”. Opis klas (RDFS, OWL) nie jest możliwy do zobrazowania na jednym grafie wraz z ich instancjami ponieważ predykat może stać się podmiotem w innym wyrażeniu (opis właściwości właściwości) co nie jest dopuszczalne w grafie.
W rekomendacjach W3C oficjalnym standardem serializacji grafu RDF jest format RDF/XML. Zgodnie z koncepcją „stosu” W3C również RDFS i OWL zapisuje się przez RDF/XML.
Sposób ten jest jednak uważany za kłopotliwy, niejednoznaczny, mało wydajny, nie obrazujący wprost trójek RDF, a ponadto trudny do używania przez człowieka. Stąd potrzeba powstania łatwiejszego formatu. Najpopularniejszy format nie oparty o XML to N3 (Notation 3) oraz jego podzbiory (np. N-Triples) i pochodne (np. Turtle). Istnieją też alternatywne formaty XML, np. TriX.
Typ MIME dla RDF/XML: application/rdf+xml
Nieoficjalne: text/rdf+n3
, application/turtle
Format RDF/XML sprawia również wiele kłopotów jako sam XML, np. nie pasuje do żadnego DTD — dopuszcza istnienie zupełnie nieprzewidywalnych elementów (tagów) definiowanych przez użytkownika a nie przez DTD.
Notacje nie XML-owe muszą być nie tylko łatwe do czytania przez człowieka ale (przede wszystkim) muszą nadal pozostać łatwe do parsowania przez program.
Notacja N3 jest również wspierana przez członków W3C. Ten „standard” zawiera znacznie więcej możliwości niż tylko zapis trójek RDF, np. ścieżki, zmienne i reguły logicznego wnioskowania.
TriX to propozycja HP Labs i Nokia.
<?xml version="1.0"?> <!DOCTYPE rdf:RDF [<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#">]> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:expet="http://example.org/pets#" xmlns:exvoc="http://example.org/vocab#"> <expet:Cat rdf:about="http://example.org/cats/PL/OP#Maurycy"> <expet:name rdf:datatype="&xsd;string">Maurycy</expet:name> <expet:breed rdf:datatype="&xsd;string">EUR</expet:breed> <expet:age rdf:datatype="&xsd;decimal">1.5</expet:age> <expet:mailbox rdf:resource="mailto:maurycy.kot@gmail.com"/> <exvoc:coinhabitants> <rdf:Bag> <rdf:li rdf:resource="http://example.org/cats/PL/OP#Kalma" /> <rdf:li rdf:resource="http://example.org/rats/PL/OP/Gomez" /> </rdf:Bag> </exvoc:coinhabitants> </expet:Cat> </rdf:RDF>
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix expet: <http://example.org/pets#> . @prefix exvoc: <http://example.org/vocab#> . @prefix : <http://example.org/cats/PL/OP#> . :Maurycy a expet:Cat ; expet:name "Maurycy" ; expet:breed "EUR" ; expet:age 1.5 ; expet:mailbox <mailto:maurycy.kot@gmail.com> ; exvoc:coinhabitants [ a rdf:Bag ; rdf:_1 <http://example.org/cats/PL/OP#Kalma> ; rdf:_2 <http://example.org/rats/PL/OP/Gomez> ] .
Podstawowe ułatwienia/skróty w notacji N3:
a
— rdf:type
;
— następna cecha tego samego podmiotu,
— następny obiekt przy tym samym podmiocie i cesze[ ]
— obiekt anonimowy, „blank node” w RDF=
— ten sam obiekt lub klasaPrzykład (kot Maurycy) ten sam co w prezentacji Sieć Semantyczna jako przyszłość WWW.
Sieć Semantyczna jest oparta na koncepcji „świata otwartego”, w którym sam fakt, że coś nie zostało powiedziane, nie oznacza jeszcze, że nie jest to prawdą. Stąd specyficzne podejście do znajdywanych informacji — założenie ich niekompletności i wnioski uzupełniające informacje zamiast błędów.
Przykład (fragment ontologii):
<owl:ObjectProperty rdf:ID="hasMother"> <rdfs:domain rdf:resource="#Person" /> <rdfs:range rdf:resource="#Woman" /> </owl:ObjectProperty> <owl:Class rdf:ID="Person"> <owl:Restriction> <owl:onProperty rdf:resource="#hasMother"/> <owl:cardinality rdf:datatype="&xsd;nonNegativeInteger">1</owl:cardinality> </owl:Restriction> </owl:Class>
<#person1> :hasMother <#woman1>
nie oznacza błędu w danych, tylko ich (chwilową) niekompletność — matka jest jeszcze nieznana.<#person1> :hasMother <#woman1>
oraz <#person1> :hasMother <#woman2>
nie oznacza sprzeczności w danych tylko prowadzi do wniosku: <#woman1> owl:sameAs <#woman2>
.Zupełnie inna sytuacja niż w przypadku „closed world” jak np. relacyjna baza danych lub model obiektowy.
<#person1>
jest typu <#Person>
oznacza (zgodnie z daną ontologią), że :hasMother
bez względu na to czy zostanie to wskazane czy nie. Najwyżej jest to wartość nieznana, ale nie można założyć, że jest to NULL
jak w bazie danych, ani zgłosić NullPointerException
jak w programowaniu obiektowym.:hasMother
pomimo owl:cardinality 1
. Powyższy wniosek owl:sameAs
(do 2003.06.26 owl:sameIndividualAs
) byłby błędny tylko wtedy gdyby zostało to wprost zaprzeczone, np. przez <#woman1> owl:differentFrom <#woman2>
. Takie wnioskowanie jest możliwe bez konieczności opisywania jawnej reguły logicznej.Podejścia „open” i „closed world” są raczej niemożliwe do równoczesnego stosowania.
Trzy teoretyczne możliwości przeszukiwania informacji zapisanej w RDF:
Pod nieobecność standardu powstały różne języki, np. RQL, RDQL, SeRQL, itd.
Nawet reguły logiczne w N3 mogą być wykorzystywane do wykonywania zapytań, np.:{?y rdfs:label "foo"} => {?y a :QueryResult}.
Sam zapis wiedzy bez możliwości jej sprawnego wyszukiwania nie ma wiele sensu. Sprawny standard języka wyszukiwania zapewne znacznie rozwój aplikacji Sieci Semantycznej — analogia do SQL-a w bazach danych.
Wyszukiwanie na poziomie syntaktycznym jest możliwe ale w bardzo ograniczonym zakresie — RDFS, a jeszcze bardziej OWL, wprowadza skomplikowane zależności miedzy klasami (hierarchie, klasy definiowane poprzez operacje zbiorowe na innych klasach), które nie wynikają wprost z trójek RDF.
SPARQL Protocol And RDF Query Language — standardowy język zapytań dla danych w RDF oraz protokół przesyłania wyników przez HTTP.
Cztery rodzaje zapytań:
SELECT
— zwraca wynik podstawienia do szablonu danych (także z wielu grafów RDF) spełniających podane zależności,CONSTRUCT
— zwraca graf RDF utworzony przez podstawienie wyników zapytania do zmiennych w szablonie,DESCRIBE
— zwraca graf RDF będący opisem zasobu wskazanego jawnie lub spełniającego podane warunki,ASK
— zwraca wartość logiczną oznaczającą czy zapytanie ma rozwiązanie, bez wskazania szczegółów.Dla zapytań SELECT
i ASK
serwis realizujący zapytania SPARQL odpowiada w formacie XML (SPARQL Query Results XML Format, Content-Type: application/sparql-results+xml
) a dla zapytań CONSTRUCT
i DESCRIBE
graf RDF zserializowany do formatu RDF/XML (Content-Type: application/rdf+xml
) lub zgodnego, np. N3 (Content-Type: text/rdf+n3
).
SPAQRL to jeszcze Working Draft. Istnieją np. niejasności co do zastosowania DESCRIBE
— oczekiwania zupełnie inne od SELECT
i CONSTRUCT
oznaczają być może potrzebę zastosowania zupełnie innego mechanizmu/języka.
Graf domyślny:
@prefix dc: <http://purl.org/dc/elements/1.1/> . <http://example.org/johny> dc:publisher "Johny"@en . <http://example.org/ala> dc:publisher "Ala" .
Graf http://example.org/johny
:
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Jan Mocny" . _:a foaf:mbox <mailto:bob@oldcorp.example.org> . _:a foaf:homepage <http://strongmen.org.pl/johny/> .
Graf http://example.org/ala
:
@prefix foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Alicja Wesoła" . _:a foaf:mbox <mailto:ala@work.example.org> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX dc: <http://purl.org/dc/elements/1.1/> SELECT ?who ?name ?mbox ?homepage WHERE { ?g dc:publisher ?who . GRAPH ?g { ?x foaf:name ?name . OPTIONAL { ?x foaf:mbox ?mbox } . OPTIONAL { ?x foaf:homepage ?homepage } } } ORDER BY ?name
who | name | mbox | homepage |
---|---|---|---|
"Ala" | "Alicja Wesoła" | mailto:ala@work.example.org | |
"Johny"@en | "Jan Mocny" | mailto:bob@oldcorp.example.org | http://strongmen.org.pl/johny/ |
<?xml version="1.0"?> <sparql xmlns="http://www.w3.org/2005/sparql-results#"> <head> <variable name="who"/> <variable name="name"/> <variable name="mbox"/> <variable name="homepage"/> </head> <results distinct="false" ordered="true"> <result> <binding name="who"><literal>Ala</literal></binding> <binding name="name"><literal>Alicja wesoła</literal></binding> <binding name="mbox"><uri>mailto:ala@work.example.org</uri></binding> <binding name="homepage"><unbound/></binding> </result> <result> <binding name="who"><literal xml:lang="en">Johny</literal></binding> <binding name="name"><literal>Jan Mocny</literal></binding> <binding name="mbox"><uri>mailto:bob@oldcorp.example.org</uri></binding> <binding name="homepage"><uri>http://strongmen.org.pl/johny/</uri></binding> </result> </results> </sparql>
Informacje dla Sieci Semantycznej już istnieją w dzisiejszym Internecie.
Podstawowe „słowniki”:
@prefix dc: http://purl.org/dc/elements/1.1/
@prefix skos: http://www.w3.org/2004/02/skos/core#
@prefix foaf: http://xmlns.com/foaf/0.1/
@prefix doap: http://usefulinc.com/ns/doap#
@prefix wn: http://xmlns.com/wordnet/1.6/
Zbiory ontologii:
Developers Guide to Semantic Web Toolkits — zestawienie bibliotek i „frameworków” dla kilkunastu języków programowania. Różnice:
Na przykład:
import com.hp.hpl.jena.rdf.model.*; import com.hp.hpl.jena.vocabulary.RDF; String nsPet = "http://example.org/pets#"; String nsVoc = "http://example.org/vocab#"; Model model = ModelFactory.createDefaultModel(); model.setNsPrefix("expet", nsPet); model.setNsPrefix("exvoc", nsVoc); Resource maurycy = model.createResource("http://example.org/cats/PL/OP#Maurycy"); maurycy.addProperty(RDF.type, model.createProperty(nsPet+"Cat")); maurycy.addProperty(model.createProperty(nsPet+"name"), "Maurycy"); maurycy.addProperty(model.createProperty(nsPet+"age"), model.createTypedLiteral(1.5)); maurycy.addProperty(model.createProperty(nsPet+"mailbox"), model.createResource("mailto:maurycy.kot@gmail.com")); Bag pets = model.createBag(); pets.add(model.createResource("http://example.org/cats/PL/OP#Kalma")); pets.add(model.createResource("http://example.org/rats/PL/OP/Gomez")); maurycy.addProperty(model.createProperty(nsVoc+"coinhabitants"), pets); model.write(System.out, "RDF/XML-ABBREV"); model.write(System.out, "N3"); model.write(System.out, "TURTLE");
public void readModel() { Model model1 = ModelLoader.loadModel(m1FileName, null, null, null, "m1", null, null); Model model2 = ModelLoader.loadModel(m2FileName, null, null, null, "m2", null, null); Model model = model1.union(model2); StmtIterator iter = model.listStatements(); while ( iter.hasNext() ) { Statement stmt = iter.nextStatement(); System.out.print(decorateNode(stmt.getSubject())); System.out.print(" "); System.out.print(decorateNode(stmt.getPredicate())); System.out.print(" "); System.out.print(decorateNode(stmt.getObject())); System.out.println(" ."); } // efekt podobny do model.write(System.out,"N-TRIPLE"); } protected String decorateNode(RDFNode node) { if ( node.isURIResource() ) return "<" + node.toString() + ">"; if ( node.isLiteral() ) return "\"" + node.toString() + "\""; if ( node.isAnon() ) return "_:" + node.toString(); return node.toString(); }
import com.hp.hpl.jena.query.*; // ARQ - A query engine for Jena, implementing SPARQL String queryStr = "PREFIX foaf: <http://xmlns.com/foaf/0.1/> " + "SELECT ?name ?nick ?mbox " + "WHERE { ?x foaf:knows ?y . ?y foaf:name ?name . " + "OPTIONAL {?y foaf:nick ?nick} . OPTIONAL {?y foaf:mbox ?mbox} . " + "FILTER regex(?name, \"man\", \"i\") } ORDER BY ?name"; Query query = QueryFactory.create(queryStr); QueryExecution qexec = QueryExecutionFactory.create(query, model); ResultSet results = qexec.execSelect(); try { while ( results.hasNext() ) { QuerySolution soln = results.nextSolution(); System.out.print(soln.getLiteral("name").getLexicalForm()); Literal nick = soln.getLiteral("nick"); if ( nick != null ) System.out.print(" \"" + nick.getLexicalForm() + "\""); System.out.print(" "); RDFNode mail = soln.get("mbox"); if ( mail != null ) System.out.print(mail.isURIResource() ? ((Resource)mail).getURI() : mail.toString()); System.out.println(); } } finally { qexec.close(); }
import com.hp.hpl.jena.reasoner.*; Model schema = ModelLoader.loadModel("schema.owl", null, null, null, "s", null, null); Model data = ModelLoader.loadModel("data.rdf", null, null, null, "d", null, null); Reasoner reasoner = ReasonerRegistry.getOWLReasoner(); reasoner = reasoner.bindSchema(schema); InfModel infmodel = ModelFactory.createInfModel(reasoner, data); Resource resSubject = infmodel.getResource(resourceID); // wszystkie wyrażenia na temat obiektu for (StmtIterator i = infmodel.listStatements(resSubject,null,null); i.hasNext(); ) { Statement stmt = i.nextStatement(); System.out.println(PrintUtil.print(stmt)); } // czy obiekt jest szukanego typu? Resource resType = infmodel.getResource(classID); if (infmodel.contains(resSubject, RDF.type, resType)) { System.out.println("Obiekt rozpoznany"); }
Jena powstała w wyniku prac HP Labs Semantic Web Research.
W Jena funkcjonuje określenie „model” w sensie grafu (repozytorium) RDF oraz „statement” w sensie trójki (wyrażenia) RDF. Takie samo (lub podobne) nazewnictwo występuje w innych pakietach, np. RAP (RDF API for PHP). Nie jest to jednak żaden standard, np. w Sesame odpowiednikiem modelu jest „repository” (storage container for RDF
).
Metody model.read()
i model.write()
przyjmują jako parametr lang
następujące stałe (wbudowane języki serializacji grafu RDF): RDF/XML
, RDF/XML-ABBREV
, N-TRIPLE
, N3
, TURTLE
, N3-PP
, N3-PLAIN
, N3-TRIPLE
.
ARQ jako jeden z nielicznych (jeszcze) frameworków obsługuje język zapytań SPARQL w pełnym zakresie zapytań (metody execSelect()
, execConstruct()
, execDescribe()
, execAsk()
klasy QueryExecution
). Ponadto rozwija się w sposób umożliwiający działanie z zapytaniami SPARQL na poziomie analogicznym jak działanie z SQL w bibliotekach obsługi baz danych, np. klasa QueryExecution.create()
przyjmuje parametr intialBinding
— efekt podobny do PreparedStatement
w JDBC API.
Podstawowe wymagania dla działania agentów Sieci Semantycznej zostały już zrealizowane:
Pozostałe problemy i plany rozwoju:
Niektóre frameworki nie wspierają wnioskowania w ogóle (jedynie odczyt/zapis/wyszukiwanie RDF), inne wspierają w ograniczonym zakresie (np. tylko RDFS, bez OWL, albo z ograniczonym OWL). Ponadto istniejące mechanizmy wnioskowania są generalnie zbyt mało wydajne do praktycznych zastosowań...
Reguły (wnioskowania) określają wyrażenia, na podstawie których będą wyprowadzane wnioski nie koniecznie wynikające bezpośrednio z ontologii (z opisu rzeczy jako takich), również arbitralnie przyjęte zasady. Mimo, że są to wyrażenia w zbiorze RDF, nie są stwierdzeniami faktów, tak jak pozostałe trójki — mówią raczej „jeżeli zachodzi jakaś zależność to zachodzi inna”, co jeszcze nie oznacza, że pierwsza z nich jest w tej chwili faktem. Faktem obowiązującym jest tylko trójka wyrażająca regułę „{coś jest jakieś} to {coś jest jakieś}”, a nie trójki zawarte w {}.
Pzykład w N3: { :thermostat :temp :high } log:implies { :heating :power "0" } .
Przykład ze zmiennymi: { ?x family:parent ?y . ?y family:brother ?z } => { ?x family:uncle ?z } .
Wprowadzenie opisu reguł może spowodować zmianę „stosu” rekomendacji W3C na „wieże”:
Dziękuję za uwagę.