Edelweiss

CoreseTutorial

Edelweiss :: DerniersChangements :: DerniersCommentaires :: ParametresUtilisateur :: Vous êtes ec2-107-22-127-92.compute-1.amazonaws.com

Corese pages: Downloads - Tutorial - Documentations - Applications - Contacts

Semantic web tutorial: RDF, RDFS and SPARQL using CORESE

updated 19/09/2007

For remarks or questions on this tutorial contact Fabien.Gandon@sophia.inria.fr

This semantic web tutorial gives a quick tour of RDF, RDFS, SPARQL, Rules and OWL using the Corese semantic web search engine. It was designed as a hand-on-keyboard introduction to the basics of RDF model, RDFS semantics for lightweight ontologies, OWL Lite semantics for lightweight ontologies, SPARQL query language for RDF graph bases and production rules for knowledge factorisation in semantic web annotation bases.

Introduction Sections: RDF, RDFS, SPARQL, OWL
Tutorial Sections: Ontologies in RDFS/XML, Annotations in RDF/XML, Querying with SPARQL, Running rules, Using OWL, Using Corese Goodies, RDFa: putting RDF in XHTML attributes, Corese API

This tutorial uses five files:

A previous version of this tutorial is available.

Rapid reminder of the basics


RDF


RDF is a triple model where every assertion is decomposed in three parts: (subject, predicate, object) for instance (tutorial.php, author, "Fabien"). The subject is URI identifying a resource. The predicate is a binary relation identified by a URI. The object is either a URI identifying a resource or a literal value. Each triple can be seen as a labelled arc and joining these arcs one obtains a graph that describes URI-identified resources and their relations.

The serialization of RDF in its XML syntax is not unique i.e. the same RDF graph may be represented in different XML forms.
For instance the following examples are equivalent:

example 1:


01
02
03
04
05
06
07
08
<rdf:Description rdf:about="http://www-sop.inria.fr/acacia/soft/corese/tutorial.php">
  <author>
    <rdf:Description rdf:about="urn://inria.fr/~fgandon">
      <firstname>Fabien</firstname>
    </rdf:Description>
  </author>
  <subject>Web</subject>
</rdf:Description>

example 2:


01
02
03
04
05
06
07
08
<rdf:Description rdf:about="http://www-sop.inria.fr/acacia/soft/corese/tutorial.php">
  <author rdf:resource="urn://inria.fr/~fgandon"  />
  <subject>Web</subject>
</rdf:Description>

<rdf:Description rdf:about="urn://inria.fr/~fgandon">
  <firstname>Fabien</firstname>
</rdf:Description>

example 3:


01
02
03
04
05
<rdf:Description rdf:about="http://www-sop.inria.fr/acacia/soft/corese/tutorial.php" subject="Web">
  <author rdf:resource="urn://inria.fr/~fgandon"  />
</rdf:Description>

<rdf:Description rdf:about="urn://inria.fr/~fgandon" firstname="Fabien" />

In these descriptions some nodes may not have a URI, they are called blank nodes; in the following example the author is a blank node.

01
02
03
04
05
06
07
<rdf:Description rdf:about="http://www-sop.inria.fr/acacia/soft/corese/tutorial.php">
  <author>
    <rdf:Description >
      <firstname>Fabien</firstname>
    </rdf:Description>
  </author>
</rdf:Description>

XML Schema datatype may be applied to literal values, here is an example with dates:

01
02
03
<rdf:Description rdf:about="urn://inria.fr/~fgandon">
  <birthdate rdf:datatype="http://www.w3.org/2001/XMLSchema#date" >1975-07-31</birthdate>
</rdf:Description>



RDFS


RDFS is a set of primitives to describe lightweight ontologies in RDF (it uses the RDF model and syntax) and for RDF (the ontologies are used to type resources and relations). RDFS allows us:

Here is an example declaring a class #Man sub class of #Person and #Male, and a property #hasMother sub property of #hasParent, and that is used between instances of the class #Human and instances of the class #Female.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<rdf:RDF xml:base="http://www.inria.fr/2007/09/11/humans.rdfs"
            xmlns:rdf ="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
            xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
            xmlns="http://www.w3.org/2000/01/rdf-schema#">
            
  <Class rdf:ID="Man">
    <subClassOf rdf:resource="#Person"/>
    <subClassOf rdf:resource="#Male"/>
    <label xml:lang="en">man</label>
    <comment xml:lang="en">an adult male person</comment>
  </Class>

  <rdf:Property rdf:ID="hasMother">
    <subPropertyOf rdf:resource="#hasParent"/>
    <range rdf:resource="#Female"/>
    <domain rdf:resource="#Human"/>
    <label xml:lang="en">has for mother</label>
    <comment xml:lang="en">to have for parent a female.</comment>
  </rdf:Property>

</rdf:RDF>

Then using this ontology (with the namespace http://www.inria.fr/2007/09/11/humans.rdfs#) one could declare that #Lucas is a #Man and that his mother is #Laura. Here are three examples of possible serialization:

01
02
03
04
05
06
07
08
09
<rdf:RDF xmlns:rdf ="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
  xmlns="http://www.inria.fr/2007/09/11/humans.rdfs#"
  xml:base="http://www.inria.fr/2007/09/11/humans.rdfs-instances" >

<rdf:Description rdf:ID="Lucas">
 <rdf:type rdf:resource="http://www.inria.fr/2007/09/11/humans.rdfs#Man"/>
 <hasMother rdf:resource="#Laura"/> 
</rdf:Description>

or

01
02
03
04
05
<rdf:Description rdf:ID="Lucas">
 <hasMother rdf:resource="#Laura"/> 
</rdf:Description>

<Man rdf:about="#Lucas" />

or

01
02
03
<Man rdf:ID="Lucas">
   <hasMother rdf:resource="#Laura"/>
</Man>

The semantics of RDFS would then allows us to infer that #Lucas is a #Person and a #Male, that #Laura is a Female and a #Human and also that (#Lucas, #hasParent, #Laura).


SPARQL


SPARQL is a query language for RDF i.e. a language to query triple stores. In its most usual form it uses the clause SELECT WHERE. The WHERE clause uses a triple syntax with question marks to prefix variables e.g. to retrieve instances of persons one could use the pattern ?x rdf:type humans:Person

The SPARQL output is a graph serialized in RDF/XML or a binding serialized in XML. Here is an example of SPARQL query. It retrieves the students of a university which web site is httpwww.mit.edu or httpwww.stanford.edu. It requests their name and
optionally their firstname if available. These students must be older than 21. The result will be sorted by their names and only the first twenty results are requested.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
PREFIX tutor: <http://inria.fr/2007/tutorial.rdfs>
SELECT ?student ?name ?firstname
WHERE {
 ?student tutor:isStudentOf ?univ .
 {
   {
    ?univ tutor:siteweb <http//www.mit.edu> .
   }
   UNION
   {
    ?univ tutor:siteweb <http//www.stanford.edu> .
   }
 }
 ?student tutor:name ?name .
 OPTIONAL { ?student tutor:firstname ?firstname . }
 ?student tutor:age ?age .
 FILTER ( ?age > 21 )
} 
ORDER BY ?name
LIMIT 20


When used in the SELECT clause, the keyword DISTINCT prevents redundancy in the results.

In the Filter we can use comparators (<, >, =, <=, >=, !=), tests (isURI(), isBLANK(), isLITERAL(), BOUND()), regular expressions, characteristics of values (LANG(), DATATYPE(), STR()), casting operators, etc.


OWL


OWL extends RDFS with additional predicates to characterise properties and classes.

For instance one may declare that a property is symmetric e.g.:

01
02
03
04
<owl:SymmetricProperty rdf:ID="sibling">
  <rdfs:domain rdf:resource="#Animal" />
  <rdfs:range rdf:resource="#Animal" />
</owl:SymmetricProperty>


or may restrict the use of a property for certain classes e.g.:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<owl:ObjectProperty rdf:ID="hasParent">
  <rdfs:domain rdf:resource="#Animal" />
  <rdfs:range rdf:resource="#Animal" />
</owl:ObjectProperty>     

<owl:Class rdf:ID="Human">
  <rdfs:subClassOf rdf:resource="#Animal" />
  ...
  <rdfs:subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#hasParent" />
      <owl:allValuesFrom rdf:resource="#Human" />
    </owl:Restriction>
  </rdfs:subClassOf>
  ...
</owl:Class>


For an exhaustive introduction see the OWL Overview.


Ontologies in RDFS/XML


Use your favourite text editor to open the file human_2007_09_11.rdfs containing a small ontology coded in RDFS and using the XML syntax of RDF

Question 1: looking at the top of the file, can you tell what is the namespace associated with this ontology? What mechanism is used to declare the namespace?

Answer
The xml:base declaration is used to attach the namespace http://www.inria.fr/2007/09/11/humans.rdfs# to the vocabulary defined in
this lightweight ontology in RDFS. In addition, the value of the xml:base uses a constant defined as an entity in the doctype:
ENTITY humans "http://www.inria.fr/2007/09/11/humans.rdfs"
It often surprises people not to find an # at the end of the xml:base, but this is normal since the process when parsing such a file is to take every ID and transform it into base#ID.


Question 2: have a look at the XML structure of the file and find the different uses of the XML tagging system (open and close tags, standalone tags)

Answer
Examples:
01
02
03
<Class rdf:ID="Woman">
   <subClassOf rdf:resource="#Person"/>
 </Class>


Question 3: study the use of the following tags Class, Property, label, comment, range, domain, subClassOf, subPropertyOf and attributes ID, resource.
In which namespaces are they defined?

Answer
Class, label, comment, range, domain, subClassOf, subPropertyOf are defined in the rdfs namespace http://www.w3.org/2000/01/rdf-schema#.
Property and the attributes ID and resource are defined in the rdf namespace http://www.w3.org/1999/02/22-rdf-syntax-ns#


Question 4: according to the signatures (range and domain) of the properties age and hasBrother what are the types of the resources that can be linked by them?

Answer
age has no restriction and thus can link any type of resources.
hasBrother is restricted to Animal for its domain and to Male for its range.
Thus subjects of an instance of the property hasBrother will be typed as instances of Animal and objects of an instance of the property hasBrother will be typed as instances of Male.


Question 5: look at the beginning of the file and draw the subgraph of the hierarchy containing the classes Animal, Man and Woman

Answer
www-sop.inria.fr/acacia/soft/corese/answer5.jpg


Annotations in RDF/XML


Use you favourite text editor to open the file human_2007_09_11.rdf containing a small set of annotations describing people and using the previous ontology.

Question 1: what is the namespace associated with the instances created by the annotations of this file?

Answer
The xml:base declaration is used to attach the namespace http://www.inria.fr/2007/09/11/humans.rdfs-instances# to every local instance created in this file. The value of the xml:base uses the constant humans defined as an entity in the doctype and concatenates -instances


Question 2: what is the namespace of the ontology used by these annotations and how is-it associated with the tags of this XML file?

Answer
The namespace is http://www.inria.fr/2007/09/11/humans.rdfs# and is associated using the declaration of a default namespace
xmlns = "&humans;#" where &humans; is an entity defined in the doctype.


Question 3: looking at the file, what do we know about John?

Answer
His name is John, his shoesize is 14, his shirtsize is 12, his trouserssize is 44, his age is 37, his spouse is Jennifer, he is the father of
Mark, he is a child of David, Alice considers him as a friend.


Question 4: propose as many ways as possible to declare that a person (e.g. "Stephen") exists.

Answer
examples:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<Person rdf:about="#Stephen"/> or <Person rdf:about="#Stephen"></Person>

<Person rdf:ID="Stephen"/> or <Person rdf:ID="Stephen"></Person>

<rdf:Description rdf:ID="Stephen">    <!-- or idem with rdf:about -->
  <rdf:type rdf:resource="&humans;#Person"/>
 </rdf:Description>

<rdf:Description rdf:ID="Stephen"> <!-- or idem with rdf:about -->
  <hasSpouse rdf:resource="#Laura"/>  <!-- using a typed domain -->
 </rdf:Description>

<rdf:Description rdf:ID="Laura">
  <hasSpouse rdf:resource="#Stephen"/>  <!-- using a typed range -->
 </rdf:Description>

<Man rdf:about="#Stephen"/>   <!-- using inheritance and idem with rdf:ID -->



Querying with SPARQL

In this art we use the standalone version of the search engine Corese distributed as one executable ".jar" file. To run this file you need java 1.5 or above on your machine. Depending on the configuration of your operating system, double-clicking on the file might be enough to start the simplified interface. Otherwise open a shell window move to the directory where the .jar file is and use the command java -jar -Dfile.encoding=UTF8 <NAME OF THE FILE.jar> to start the application ; this command also has the advantage to ensure the JVM is using UTF8 encoding.

You should obtain one window with two tabs:

www-sop.inria.fr/acacia/soft/corese/screenshot1_tutorial_2_3_0.jpg

www-sop.inria.fr/acacia/soft/corese/screenshot2_tutorial_2_3_0.jpg

This is a simplified interface used for testing, debugging and teaching. The "Loading and messages" tab allows you to load Ontologies in RDFS/XML, annotations in RDF/XML, rules in a XML/SPARQL-like format, and check errors while loading these files. The "Queries and bindings" tab allows you
to write SPARQL queries and visualize the result.

Using the first tab, load the ontology humans.rdfs and then load the annotations human_2007_09_11.rdf.
Normally you shouldn't see any error message and you can move to the "Queries and bindings" tab and start writing queries.

Question 1: what does the following query retrieve? Look at the first answers.
01
02
03
04
05
SELECT ?x ?t
WHERE
{
 ?x rdf:type ?t
}


Answer
This query asks for every typed resource with its type.
Also note that Corese knows five default namespaces with their prefixes rdf, rdfs, owl, xsd and cos:
01
02
03
04
05
 rdf     "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 rdfs    "http://www.w3.org/2000/01/rdf-schema#"
 owl     "http://www.w3.org/2002/07/owl#"
 xsd     "http://www.w3.org/2001/XMLSchema#"
 cos     "http://www.inria.fr/acacia/corese#"



Question 2: adapt the previous query to retrieve all the classes.

Answer
01
02
03
04
05
SELECT ?x
WHERE
{
 ?x rdf:type rdfs:Class
}



Question 3: write a new query to extract all the subsumption links between classes (subClassOf).

Answer
01
02
03
04
05
SELECT ?x ?y
WHERE
{
 ?x rdfs:subClassOf ?y
}



Question 4: what does the following query retrieve? Translate this query in plain English.
01
02
03
04
05
06
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT *
WHERE
{
 ?x humans:hasSpouse ?y
}


Answer
Retrieve all the married couples.


Question 5: constrain the previous query to build two queries to retrieve only males and their spouses.

Answer
So far we haven't used unions or symmetrical relations therefore we have two possible queries:
01
02
03
04
05
06
07
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT *
WHERE
{
 ?x humans:hasSpouse ?y .
 ?x rdf:type humans:Male
}

01
02
03
04
05
06
07
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT *
WHERE
{
 ?x humans:hasSpouse ?y .
 ?y rdf:type humans:Male
}


Question 5b: The first query retrieves only one answer but if you declare that Lucas has for father Karl then an additional answer appears (add this new fact to the annotation file, use "reset all" in the "Loading and messages" tab, reload the ontology and the annotations, run your query again). Why is thats ?

Answer
The first query retrieves only one answer because only one ?x with a spouse was typed as male.
As soon as you use the hasFather relation on Lucas and Karl, Karl is typed as Male and becomes an answer.
01
02
03
<Man rdf:ID="Lucas">
  <hasFather rdf:resource="#Karl"/>
</Man>


Question 6: retrieve resources of which we know at least one parent.

Answer
01
02
03
04
05
06
07
08
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT ?x
WHERE
{
 { ?y humans:hasChild ?x }
 UNION
 { ?x humans:hasParent ?y }
}


Question 6b: Some appear twice because we found their two parents can you avoid these duplicates?

Answer
SELECT distinct ?x


Question 7: retreive persons with their age if it is known.

Answer
01
02
03
04
05
06
07
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT ?person ?age
WHERE
{
 ?person rdf:type humans:Person
 OPTIONAL { ?person humans:age ?age }
}



Question 8: identify adults in the base (hint: in france you are an adult when you are over 18).

Answer
01
02
03
04
05
06
07
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT ?x
WHERE
{
 ?x humans:age ?age
 FILTER ( xsd:integer(?age) >= 18 )
}


The casting function xsd:integer(...) is compulsory when the annotations did not type the value of age as a numeric value. By default every value is just a literal.


Question 9: modifying the query in question 9 ask if Mark is an adult.
Mark's URI is http://www.inria.fr/2007/09/11/humans.rdfs-instances#Mark

Answer
01
02
03
04
05
06
07
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
ASK
WHERE
{
 <http://www.inria.fr/2007/09/11/humans.rdfs-instances#Mark> humans:age ?age
 FILTER ( xsd:integer(?age) >= 18 )
}



Question 10: look for all the Lecturers and request their types. How come they have several types?

Answer
01
02
03
04
05
06
07
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT ?x ?t
WHERE
{
  ?x rdf:type humans:Lecturer .
  ?x rdf:type ?t 
}

Laura was multi-instantiated as a lecturer, a researcher, a person, a female.


Question 11: retrieve all the instances that are both Male and Person.
Explain the results such as Jack and Pierre. Why were they retreived?

Answer
01
02
03
04
05
06
07
08
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT ?x ?t
WHERE
{
 ?x rdf:type humans:Male .
 ?x rdf:type humans:Person .
 ?x rdf:type ?t
}

Jack and Pierre were declared as instances of Man which is a common subclass of Male and Person (multiple inheritances).


Question 12: retrieve all the instances of Lecturers or Researchers.

Answer
01
02
03
04
05
06
07
08
09
10
11
12
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT distinct ?person
WHERE
{
 {
  ?person rdf:type humans:Lecturer
 }
 UNION
 {
  ?person rdf:type humans:Researcher
 }
}



Question 13: query the base to get all the researchers and then all the non researchers.</p>

Answer
01
02
03
04
05
06
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT ?x
WHERE
{
 ?x rdf:type humans:Researcher
}


and

01
02
03
04
05
06
07
08
09
10
11
12
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT ?x
WHERE
{
 ?x rdf:type humans:Person
 OPTIONAL
 {
   ?x rdf:type ?t
   FILTER ( ?t = humans:Researcher )
 }
 FILTER ( ! bound( ?t ) )
}


A typical mistake is to use type negation:
01
02
03
04
05
06
07
08
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT ?x
WHERE
{
 ?x rdf:type humans:Person
 ?x rdf:type ?t
 FILTER ( ?t != humans:Researcher )
}


In the context of multi-instantiation you will also retrieve researchers if they have other types
ex: David, Gaston and Laura are retrieved because they have been declared as Researchers and Persons.

Note: in an open world, negation as failure only works as far as your knowledge goes.
Maybe there is an annotation out there on the web which says that Karl is a researcher, and the fact that you just don't know it yet does not mean it is not true.


Question 14: ask for instances of the relation hasAncestor. How comes you have results while this property is not used in the annotations (check the content of the annotations in human_2007_09_11.rdf).

Answer
01
02
03
04
05
06
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT ?x ?y 
WHERE
{
 ?x humans:hasAncestor ?y
}

hasAncestor is super-property of hasParent which itself is a super-property of hasFather and hasMother.
Therefore instances of these subproperties are also retrieved.


Question 15: find the different meanings of the word "size" (hint: it is a label).

Answer
01
02
03
04
05
06
07
08
09
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT *
WHERE
{
  ?t rdfs:label "size"@en .
  ?t rdfs:label ?le .
  ?t rdfs:comment ?ce .
  FILTER ( lang(?le) = 'en' && lang(?ce) = 'en' )
}

Answers: size, shoe size, trousers size, shirt size.


Question 16: find synonyms of the word "person".

Answer
01
02
03
04
05
06
07
08
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT * 
WHERE
{
  ?t rdfs:label "person"@en .
  ?t rdfs:label ?syn .
  FILTER ( ?syn != "person"@en && lang(?syn) = 'en' )
}

Answers: human, human being.


Question 17: ask for the translation of "shoe size" in French.

Answer
01
02
03
04
05
06
07
08
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT ?lf 
WHERE
{
  ?t rdfs:label "shoe size"@en .
  ?t rdfs:label ?lf .
  FILTER ( lang(?lf) = 'fr' )
}

Answer: pointure


Question 18: ask everything about Laura and use the ontology to get the english labels of the properties.

Answer
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT *
WHERE
{
  ?laura humans:name "Laura" .
  ?type rdfs:label ?l .
  {
   {
    ?laura rdf:type ?type
   }
   UNION
   {
    {
     ?laura ?type ?with
    }
    UNION
    {
     ?from ?type ?laura
    }
   }
  }
  FILTER ( lang(?l) = 'en' )
}



Question 19: use the describe clause to obtain a describtion of Laura.

Answer
01
DESCRIBE <http://www.inria.fr/2007/09/11/humans.rdfs-instances#Laura>


Or

01
02
03
04
05
06
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
DESCRIBE ?laura
WHERE
{
  ?laura humans:name "Laura" .
}



Question 20: construct all the triples asserting Man instances using known men and known male persons.

Answer
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
CONSTRUCT 
{
 ?x rdf:type humans:Man
}
WHERE
{
 {
  ?x rdf:type humans:Man
 }
  UNION
 {
  ?x rdf:type humans:Male .
  ?x rdf:type humans:Person
 }
}

Man is a common subclass of Male and Person, thus all instances of Man are both Male and Person, but here we construct the inverse relation: all instances of Male and Person are also instances of Man.


Question 21: retrieve all the persons whose name contains "ar", using the function regex(STRING, PATTERN).

Answer
01
02
03
04
05
06
07
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT * WHERE
{
 ?x rdf:type humans:Person .
 ?x humans:name ?name .
 FILTER ( regex(?name, '.*ar.*') )
}



Running rules


Use your favourite editor to open the file human_2007_09_11.rul.
The principle of these rules is very simple:
01
02
03
04
05
06
07
08
09
10
<cos:rule>

    <cos:if>
      ... a condition ...
    </cos:if>
      
    <cos:then>
      ... a conclusion ...
    </cos:then>

</cos:rule> 



Question 1: what does the unique rule contained in human_2007_09_11.rul do?

Answer
It defines the class Man based on the sex (Male) and the specie (Person)
of a being: each time an instance is both a Male and a Person this rule
will assert it is a Man.


Question 2: before running the rules, write and run a query to retrieve the instances of Man and check the result.

Answer
01
02
03
04
05
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT ?x WHERE
{
  ?x rdf:type humans:Man
}

Load the rules and then check the result running the query again;
you should now have 7 Men.


Question 3: adapting the previous rule, add a new rule to define the class Woman. Check the result before and after loading the rules.

Answer
Rule:
01
02
03
04
05
06
07
08
09
10
11
12
13
<cos:rule>
    <cos:if>
      PREFIX humans: &lt;&humans;&gt;
       {
        ?x rdf:type humans:Female .
        ?x rdf:type humans:Person
       }
    </cos:if>
  
    <cos:then>
      { ?x rdf:type humans:Woman }
    </cos:then>
</cos:rule>

Query:
01
02
03
04
05
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT ?x WHERE
{
  ?x rdf:type humans:Woman
}



Question 4: propose a rule defining the symmetry of the property hasSpouse and check the result with a query before and after loading the rule.

Answer
Rule:
01
02
03
04
05
06
07
08
09
10
<cos:rule>
    <cos:if>
	   PREFIX humans: &lt;&humans;&gt;
      { ?y humans:hasSpouse ?x }
    </cos:if>
      
    <cos:then>
      { ?x humans:hasSpouse ?y }
    </cos:then>
</cos:rule>

Query:
01
02
03
04
05
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT distinct ?x ?y WHERE
{
 ?x humans:hasSpouse ?y
}

Note: when using OWL (Lite) in Corese a SymmetricProperty? can be declared directly without using a rule ; see next section.


Question 5: can you think of a way to declare that hasChild and hasParent are inverse properties? Check the result.
It takes two rules:

Answer
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<cos:rule>
    <cos:if>
      PREFIX humans: &lt;&humans;&gt;
      { ?x humans:hasChild ?y }
    </cos:if>
      
    <cos:then>
      { ?y humans:hasParent ?x }
    </cos:then>
</cos:rule>

<cos:rule>
    <cos:if>
	PREFIX humans: &lt;&humans;&gt;
      { ?y humans:hasParent ?x }
    </cos:if>
      
    <cos:then>
      { ?x humans:hasChild ?y }
    </cos:then>
</cos:rule>

Query:
01
02
03
04
05
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT distinct ?x ?y WHERE
{
 ?x humans:hasChild ?y
}

or
01
02
03
04
05
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT distinct ?x ?y WHERE
{
 ?y humans:hasParent ?x
}

Note: when using OWL (Lite) in Corese the inverse of a property can be declared directly without using a rule ; see next section.



Question 6: propose a rule defining the transitivity of the property hasAncestor and check the result with a query before and after loading the rule.

Answer
Rule:
01
02
03
04
05
06
07

08
09
10
11
<cos:rule>
    <cos:if>
	PREFIX humans: &lt;&humans;&gt;
      { ?x humans:hasAncestor ?y .
      ?y humans:hasAncestor ?z }
    </cos:if>
      
    <cos:then>
      { ?x humans:hasAncestor ?z }
    </cos:then>
</cos:rule>

Query:
01
02
03
04
05
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT distinct ?x ?y WHERE
{
 ?x humans:hasAncestor ?y
}

Note: when using OWL (Lite) in Corese a TransitiveProperty? can be declared directly without using a rule ; see next section.



Question 7: propose a rule defining the property <TT>hasFather</TT> from the property hasParent and check the result with a query before and after loading the rule.

Answer
Rule:
01
02
03
04
05
06
07
08
09
10
11
<cos:rule>
    <cos:if>
      PREFIX humans: &lt;&humans;&gt;
      { ?y humans:hasParent ?x .
      ?x rdf:type humans:Male }
    </cos:if>
      
    <cos:then>
      { ?y humans:hasFather ?x }
    </cos:then>
</cos:rule>

Query:
01
02
03
04
05
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT distinct ?x ?y WHERE
{
 ?x humans:hasFather ?y
}



Question 8: declare a new class Adult in the ontology and define it with a rule (hint: in france you are an adult when you are over 18). Check the result with a query.

Answer
Declaration:
01
<Class rdf:ID="Adult" />

Or for a more complete version...
01
02
03
04
05
06
07
<Class rdf:ID="Adult">
  <subClassOf rdf:resource="#Animal"/>
  <label xml:lang="en">adult</label>
  <comment xml:lang="en">any mature animal.</comment>
  <label xml:lang="fr">adulte</label>
  <comment xml:lang="fr">un animal ayant atteint la maturité.</comment>
</Class>

Rule:
01
02
03
04
05
06
07
08
09
10
11
12
<cos:rule>
    <cos:if>
     PREFIX humans: &lt;&humans;&gt;
     { ?x rdf:type humans:Person .
     ?x humans:age ?age .
     FILTER ( xsd:integer(?age) &gt;= 18 ) }
    </cos:if>
      
    <cos:then>
      { ?x rdf:type humans:Adult }
    </cos:then>
</cos:rule>

Query:
01
02
03
04
05
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT ?x WHERE
{
  ?x rdf:type humans:Adult
}



Using OWL

For this part of the tutorial you will no longer use the rule file i.e. reset Corese and load only rdfs and rdf files ; don't load the rules during this section.

Question 1: At the top of the ontology add the namespace for OWL using the prefix "owl".

Answer
xmlns:owl ="http://www.w3.org/2002/07/owl#"


Question 2: Using property characteristics of OWL Lite declare that hasSpouse and hasFriend are symmetric and test the result with a query before and after you made the change.

Answer
Add these lines to the ontology.
01
02
<owl:SymmetricProperty rdf:about="#hasFriend" />
<owl:SymmetricProperty rdf:about="#hasSpouse" />

Use the following queries to test the result:
01
02
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT * WHERE {  ?x humans:hasSpouse ?y }

and
01
02
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT * WHERE {  ?x humans:hasFriend ?y }



Question 3: Using property characteristics of OWL Lite declare that hasAncestor is symmetric and test the result with a query before and after you made the change.

Answer
Add these lines to the ontology.
01
<owl:TransitiveProperty rdf:about="#hasAncestor" />

Use the following queries to test the result:
01
02
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT * WHERE {  ?x humans:hasAncestor ?y }



Question 4: Using property characteristics of OWL Lite declare that hasChild is inverse of hasParent and test the result with a query before and after you made the change.

Answer
Add this property in the declaration of hasChild:
01
02
03
04
<rdf:Property rdf:ID="hasChild">
 <owl:inverseOf rdf:resource="#hasParent"/>
 ...
</rdf:Property> 


Use the following queries to test the result:
01
02
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT * WHERE { ?x humans:hasParent ?y }



Question 5: Using the predicate "disjoint with" declare that the classes Male and Female are disjoints. Test this by creating an instance that is both a Man and a Woman.

Answer
Add this property in the declaration of Male:
01
02
03
04
<Class rdf:ID="Male">
   <owl:disjointWith rdf:resource="#Female"/>
   ...
</Class>


Add this annotation:
01
<Man rdf:ID="Jennifer" />

Load the files and after seeing the error remove the annotation.


Question 6: Using the predicate "intersection of" declare that the class Professor is the intersection of the class Researcher and the class Lecturer.

Answer
Add this declaration:
01
02
03
04
05
06
<owl:Class rdf:ID="Professor">
  <owl:intersectionOf rdf:parseType="Collection">
    <owl:Class rdf:about="#Researcher" />
    <owl:Class rdf:about="#Lecturer" />
  </owl:intersectionOf> 
</owl:Class>


Use the following queries to test the result:
01
02
03
04
05
06
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT ?x ?t
WHERE
{
 ?x rdf:type humans:Professor .
 ?x rdf:type ?t 
}



Question 7: Using the predicate "union of" declare that the class Academic is the union of the class Researcher and the class Lecturer.

Answer
Add this declaration:
01
02
03
04
05
06
<owl:Class rdf:ID="Academic">
  <owl:unionOf rdf:parseType="Collection">
    <owl:Class rdf:about="#Researcher" />
    <owl:Class rdf:about="#Lecturer" />
  </owl:unionOf>
</owl:Class>


Use the following queries to test the result:
01
02
03
04
05
06
07
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT ?x ?t
WHERE
{
 ?x rdf:type humans:Academic .
 ?x rdf:type ?t 
}



Question 8: Using the restriction allValuesFrom declare that all the spouses of a man must be women and that all the spouses of a woman must be men. Then test on the base.

Answer
Modify the Man and Woman classes:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<Class rdf:ID="Man">
  ...
  <subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#hasSpouse" />
      <owl:allValuesFrom rdf:resource="#Woman" />
    </owl:Restriction>
  </subClassOf>
  ...
</Class>

<Class rdf:ID="Woman">
  ...
  <subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#hasSpouse" />
      <owl:allValuesFrom rdf:resource="#Man" />
    </owl:Restriction>
  </subClassOf>
  ...
</Class>


Use the following queries to test the result:
01
02
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT * WHERE { ?x rdf:type humans:Woman }

and
01
02
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT * WHERE { ?x rdf:type humans:Man }



Question 9: Using the restriction someValuesFrom declare that the parent of a person must include a woman. Load the modified schema and see the resulting warnings when running the rule engine.

Answer
Modify the class "Person":
01
02
03
04
05
06
07
08
09
10
<Class rdf:ID="Person">
  ...
  <subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#hasParent" />
      <owl:someValuesFrom rdf:resource="#Female" />
    </owl:Restriction>
  </subClassOf>
  ...
</Class>


NB: Since this is internally implemented as rules you must hit the run rules button after you loaded the ontologies and the annotations. You will then see the errors in the "Loading and messages" panel.


Using Corese Goodies


For this section, keep the modified RDFS file, but remove the modification of Person of the ninth question since it generates warnings.

Question 1: what does the following query retrieve? Translate this query in plain English.
01
02
03
04
05
06
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT ?x ?y count(?x) as ?count 
WHERE
{
 ?x humans:hasFriend ?y
} GROUP BY ?y

Answer
This query retrieves for each person GROUP BY ?y all the persons who declared him/her as a friend and counts them count(?x) as ?count.
Example: for Alice three persons declared her as a friend (Laura, Eve and Jack).


Question 2: what does the following query retrieve? Translate this query in plain English.
01
02
03
04
05
06
07
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT MORE * WHERE 
{
 ?x rdf:type humans:Man
 ?x humans:hasSpouse ?spouse
 ?x rdf:type ?type
}

Answer
This query retrieves a man, his type and his spouse but allowing approximation i.e. logically false answer but semantically close; here William is an approximate answer because he is declared as Person and not Man.


Question 3: what is the difference with using DISTINCT or DISTINCT SORTED in the following query?
01
02
03
04
05
06
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
SELECT DISTINCT SORTED ?n1 ?n2 WHERE
{
 ?x1 humans:name ?n1 filter(regex(?n1, '^J'))
 ?x2 humans:name ?n2 filter(regex(?n2, '^J'))
}

Answer
With DISTINCT SORTED, we consider the binding set (n1, n2), without ordering/variable affectation i.e. (x=a, y=b) is equal to (x=b, y=a) and we only one of them.

Question 4: what does the following query retrieve? Translate this query in plain English.
01
02
03
04
05
06
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
select more * where
{
 SCORE ?s1 { ?x humans:hasSpouse ?y . ?y rdf:type humans:Man }
 SCORE ?s2 { ?x humans:hasAncestor ?y2 . ?y2 rdf:type humans:Woman }
}

Answer
This query retrieves spouses of men and descendant of women allowing for approximation of both patterns and providing the quality of the approximation separately for both patterns.

Question 5: what does the following query retrieve? Translate this query in plain English.
01
02
03
04
05
06
PREFIX humans: <http://www.inria.fr/2007/09/11/humans.rdfs#>
select * where
{
 ?x direct::humans:hasAncestor ?y
 ?x ?p ?y
} GROUP BY ?x ?y

Answer
This query retrieves ancestors but ignores its transitive nature and provides only the directly asserted triples using hasAncestor or a sub property.


RDFa: putting RDF in XHTML attributes


Open the XHTML file provided with this tutorial in a web browser to see it is a normal web page.

Question 1: in addition to the RDFS file and the RDF file load the XHTML file provided with this tutorial. Run the following query to check that a new person was added to the base.
01
02
03
04
05
06
07
PREFIX humans: 
DESCRIBE ?x WHERE
{
 ?x humans:name ?name .
 ?x ?p ?y
 FILTER ( regex(?name, '.*Greg.*') )
}

Answer
The XHTML file contains attributes embedding RDF in the web page: first the namespace of the ontology is declared (xmlns:humans) then Greg's URI is declared (about="...") as well as his type (instanceof="humans:Man") his name (property="humans:name"), his age (property="humans:age") and a parent (link rel="humans:hasParent" href="...").


Question 2: add a shirtsize of 12 for Greg and check the result reusing the query in question 1.

Answer
Add this into the <div> element:
01
My shirt size is <span property="humans:shirtsize">12</span>



Question 3: declare Harry is the father of Greg and check the result reusing the query in question 1.

Answer
Add this into the <div> element:
01
<link rel="humans:hasFather" href="http://www.inria.fr/2007/09/11/humans.rdfs-instances#Harry"/>


Suggestion: create your own RDFa web page and use additional schemas for instance FOAF


Corese API


Corese API is described here: API
Il n'y a pas de commentaire sur cette page. [Afficher commentaires/formulaire]