The purpose of this lab is to build an RDFS inference engine using a rule system.
Introduction
RDFS reasoning can be realized by a set of rules (See Figure 1). Therefore, RFDS reasoning can be implemented using a rule engine. Each RDF triple xxx yyy zzz . can be modeled as a (Datalog) fact.
triple(xxx, yyy, zzz)
The entailment patterns can be modeled as Datalog rules. For instance, entailment pattern rdfs2 said that
If S contains triples “aaa rdfs:domain xxx .” and “yyy aaa zzz .”, then S RDFS entails the triple “yyy rdf:type xxx .”
It can be captured by the following Datalog rule
triple(Y, "rdf:type", X) :- triple(A, "rdfs:domain", X),
triple(Y, A, Z).
Together with the the following facts
triple(":hasTripAdvisorRating", "rdfs:domain", ":TourismObject").
triple("i:ChickenHut", ":hasTripAdvisorRating", "3.5") .
We can compute all the entailed triples using a Datalog engine like DLV.
$ ~/bin/dlv rdfs-2-example.dlv
DLV [build BEN+ODBC/Dec 17 2012 gcc 4.2.1 (Apple Inc. build 5666) (dot 3)]
{ triple(":hasTripAdvisorRating","rdfs:domain",":TourismObject"),
triple("i:ChickenHut","rdf:type",":TourismObject"),
triple("i:ChickenHut",":hasTripAdvisorRating","3.5") }
Figure 1: RFDS Entailment Patterns
Tasks
Convert the tourism RDFS ontology into a Datalog file (“tourism.dlv”).
tourism-rdfs.ttl
@prefix : <http://example.org/term/> . @prefix i: <http://example.org/inst/> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . :Museum rdfs:subClassOf :TourismAttraction . :ArtMeseum rdfs:subClassOf :Museum . :ModernArtMuseum rdfs:subClassOf :ArtMeseum . :Landmark rdfs:subClassOf :TourismAttraction . :OutdoorSpot rdfs:subClassOf :TourismAttraction . :AmusementPark rdfs:subClassOf :TourismAttraction . :Restaurant rdfs:subClassOf :TourismObject . :Hotel rdfs:subClassOf :TourismObject . :TourismAttraction rdfs:subClassOf :TourismObject . :hasTripAdvisorRating rdfs:domain :TourismObject . :hasTripAdvisorRating rdfs:subPropertyOf :hasRating . i:Museion rdf:type :ModernArtMuseum . The TripAdvisor rating of Chicken Hut is 3.5. i:ChickenHut :hasTripAdvisorRating "3.5"^^xsd:decimal .
tourism.dlv
triple(":Museum", "rdfs:subClassOf", ":TourismAttraction") . triple(":ArtMeseum", "rdfs:subClassOf", ":Museum") . triple(":ModernArtMuseum", "rdfs:subClassOf", ":ArtMeseum") . triple(":Landmark", "rdfs:subClassOf", ":TourismAttraction") . triple(":OutdoorSpot", "rdfs:subClassOf", ":TourismAttraction") . triple(":AmusementPark", "rdfs:subClassOf", ":TourismAttraction") . triple(":Restaurant", "rdfs:subClassOf", ":TourismObject") . triple(":Hotel", "rdfs:subClassOf", ":TourismObject") . triple(":TourismAttraction", "rdfs:subClassOf", ":TourismObject") . triple(":hasTripAdvisorRating", "rdfs:domain", ":TourismObject") . triple(":hasTripAdvisorRating", "rdfs:subPropertyOf", ":hasRating") . triple("i:Museion", "rdf:type", ":ModernArtMuseum") . triple("i:ChickenHut", ":hasTripAdvisorRating", "3.5^^xsd:decimal") .
Implement rdfs2, rdfs3, rdfs5, rdfs7, rdfs9, rdfs11 in Datalog (“rdfs.dlv”)
rdfs.dlv
% RDFS2 triple(Y, "rdf:type", X) :- triple(A, "rdfs:domain", X), triple(Y, A, Z). % RDFS3 triple(Z, "rdf:type", X) :- triple(A, "rdfs:range", X), triple(Y, A, Z). % RDFS5 triple(X, "rdfs:subPropertyOf", Z) :- triple(X, "rdfs:subPropertyOf", Y), triple(Y, "rdfs:subPropertyOf", Z). % RDFS7 triple(X, B, Y) :- triple(A, "rdfs:subPropertyOf", B), triple(X, A, Y). % RDFS9 triple(Z, "rdf:type", Y) :- triple(X, "rdfs:subClassOf", Y), triple(Z, "rdf:type", X). % RDFS11 triple(X, "rdfs:subClassOf", Z) :- triple(X, "rdfs:subClassOf", Y), triple(Y, "rdfs:subClassOf", Z).
Test“tourism.dlv”and“rdfs.dlv”using DLV to check whether we can get all expected entailed triples.
dlv.mingw tourism.dlv
We can see that the output is the same as its original data.
{triple(":Museum","rdfs:subClassOf",":TourismAttraction"), triple(":TourismAttraction","rdfs:subClassOf",":TourismObject"), triple(":ArtMeseum","rdfs:subClassOf",":Museum"), triple(":ModernArtMuseum","rdfs:subClassOf",":ArtMeseum"), triple(":Landmark","rdfs:subClassOf",":TourismAttraction"), triple(":OutdoorSpot","rdfs:subClassOf",":TourismAttraction"), triple(":AmusementPark","rdfs:subClassOf",":TourismAttraction"), triple(":Restaurant","rdfs:subClassOf",":TourismObject"), triple(":Hotel","rdfs:subClassOf",":TourismObject"), triple(":hasTripAdvisorRating","rdfs:domain",":TourismObject"), triple(":hasTripAdvisorRating","rdfs:subPropertyOf",":hasRating"), triple("i:Museion","rdf:type",":ModernArtMuseum"), triple("i:ChickenHut",":hasTripAdvisorRating","3.5^^xsd:decimal")}
dlv.mingw tourism.dlv rdfs.dlv
Now we can see that we successfully get all the entailed triples using DLV.
{triple(":Museum","rdfs:subClassOf",":TourismAttraction"), triple(":Museum","rdfs:subClassOf",":TourismObject"), triple(":TourismAttraction","rdfs:subClassOf",":TourismObject"), triple(":ArtMeseum","rdfs:subClassOf",":Museum"), triple(":ArtMeseum","rdfs:subClassOf",":TourismAttraction"), triple(":ArtMeseum","rdfs:subClassOf",":TourismObject"), triple(":ModernArtMuseum","rdfs:subClassOf",":Museum"), triple(":ModernArtMuseum","rdfs:subClassOf",":TourismAttraction"), triple(":ModernArtMuseum","rdfs:subClassOf",":ArtMeseum"), triple(":ModernArtMuseum","rdfs:subClassOf",":TourismObject"), triple(":Landmark","rdfs:subClassOf",":TourismAttraction"), triple(":Landmark","rdfs:subClassOf",":TourismObject"), triple(":OutdoorSpot","rdfs:subClassOf",":TourismAttraction"), triple(":OutdoorSpot","rdfs:subClassOf",":TourismObject"), triple(":AmusementPark","rdfs:subClassOf",":TourismAttraction"), triple(":AmusementPark","rdfs:subClassOf",":TourismObject"), triple(":Restaurant","rdfs:subClassOf",":TourismObject"), triple(":Hotel","rdfs:subClassOf",":TourismObject"), triple(":hasTripAdvisorRating","rdfs:domain",":TourismObject"), triple(":hasTripAdvisorRating","rdfs:subPropertyOf",":hasRating"), triple("i:Museion","rdf:type",":Museum"), triple("i:Museion","rdf:type",":TourismAttraction"), triple("i:Museion","rdf:type",":ArtMeseum"), triple("i:Museion","rdf:type",":ModernArtMuseum"), triple("i:Museion","rdf:type",":TourismObject"), triple("i:ChickenHut",":hasTripAdvisorRating","3.5^^xsd:decimal"), triple("i:ChickenHut",":hasRating","3.5^^xsd:decimal"), triple("i:ChickenHut","rdf:type",":TourismObject")}
Analyzation
triple(":Museum", "rdfs:subClassOf", ":TourismAttraction") .
triple(":TourismAttraction", "rdfs:subClassOf", ":TourismObject") .
According to RDFS11 rule
triple(X, "rdfs:subClassOf", Z) :- triple(X, "rdfs:subClassOf", Y),
triple(Y, "rdfs:subClassOf", Z).
here X ⇒ “:Museum”, Y ⇒ “:TourismAttraction” and Z ⇒ “:TourismObject”. So we can know that
triple(":Museum", "rdfs:subClassOf", ":TourismObject") .