You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by Miguel Bento Alves <mb...@gmail.com> on 2013/12/06 01:20:58 UTC

call a Sparql command in a rule, is it possible?

Is it possible call a Sparql command in a rule? Can we do that with a custom
built-in function?

An example:

let's consider that I have the classes Student, Course and Lesson. Lesson is
related with Course. I have an ObjectProperty wasFailedBy that defines that
a given student fails to a given lesson (I list my schema and my data
example below). I want to define an ObjectProperty isDiligent that defines
that a given student is diligent to a given course. I consider that a given
student is diligent to a given course if he didn't fails more than a given
number of lessons (let's consider 1). I can't get this information with OWL
or OWL2 inference, I only can get with a Sparql command.

I'm thinking to define my rule in this way:

(?Student ex:isDiligent ?Course) <-
(?Student rdf:type ex:Student),
(?Course rdf:type ex:Course),
execSparql('
prefix exa: <http://www.example.org/example#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT (COUNT(1) AS ?nCount)
WHERE {   
?V1_Student ex:failsTo ?Lesson .
?Lesson exa:isLessonOf ?V2_Course .
}', ?Student, ?Course, ?NCount),
le(?NCount, 1). 

In my idea, the custom built-in function execSparql receives as parameters a
string with a Sparql command, a list of instanced variables to be replaced
inside the function and will return the result in the last variable passed
as parameter. I didn't implemented yet because I have doubts if this is the
better approach. My main doubts is:
Can I execute a Sparql command inside a custom built-in function using de
RuleContext?
Can I use a custom built-in function only to be an external access from the
rule and call the Sparql command, for instance via Web Service, to my
inference engine? Any better ideas?


<?xml version="1.0"?>


<!DOCTYPE rdf:RDF [
    <!ENTITY owl "http://www.w3.org/2002/07/owl#" >
    <!ENTITY exa "http://www.example.org/example#" >
    <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
    <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >
    <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
]>


<rdf:RDF xmlns="http://www.example.org/example#"
     xml:base="http://www.example.org/example#"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:exa="http://www.example.org/example#">
    


    <!-- 
    
////////////////////////////////////////////////////////////////////////////
///////////
    //
    // Object Properties
    //
    
////////////////////////////////////////////////////////////////////////////
///////////
     -->

<owl:ObjectProperty rdf:about="&exa;isLessonOf">
        <rdfs:label>wasFailedBy</rdfs:label>
        <rdfs:domain rdf:resource="&exa;Lesson"/>
        <rdfs:range rdf:resource="&exa;Course"/>
    </owl:ObjectProperty>


<owl:ObjectProperty rdf:about="&exa;wasFailedBy">
        <rdfs:label>wasFailedBy</rdfs:label>
        <rdfs:domain rdf:resource="&exa;Lesson"/>
        <rdfs:range rdf:resource="&exa;Student"/>
    </owl:ObjectProperty>
    
    <owl:ObjectProperty rdf:about="&exa;failsTo">
        <rdfs:label>failsTo</rdfs:label>
        <owl:inverseOf rdf:resource="&exa;wasFailedBy"/>
    </owl:ObjectProperty>
    
    
    <!-- 
    
////////////////////////////////////////////////////////////////////////////
///////////
    //
    // Classes
    //
    
////////////////////////////////////////////////////////////////////////////
///////////
     -->

   <owl:Class rdf:about="&exa;Student">
        <rdfs:label>Student</rdfs:label>
    </owl:Class>
   
   <owl:Class rdf:about="&exa;Course">
        <rdfs:label>Course</rdfs:label>
    </owl:Class>
     
   <owl:Class rdf:about="&exa;Lesson">
        <rdfs:label>Lesson</rdfs:label>
    </owl:Class>
 


    <!-- 
    
////////////////////////////////////////////////////////////////////////////
///////////
    //
    // Individuals
    //
    
////////////////////////////////////////////////////////////////////////////
///////////
     -->

    
    <owl:Thing rdf:about="&exa;Databases">
        <rdfs:label>Databases</rdfs:label>
        <rdf:type rdf:resource="&exa;Course"/>
    </owl:Thing>



    <owl:Thing rdf:about="&exa;ComputerProgramming">
        <rdfs:label>Computer Programming</rdfs:label>
        <rdf:type rdf:resource="&exa;Course"/>
    </owl:Thing>
    

<owl:Thing rdf:about="&exa;Michael">
        <rdfs:label>Michael</rdfs:label>
        <rdf:type rdf:resource="&exa;Student"/>
    </owl:Thing>

<owl:Thing rdf:about="&exa;Richard">
        <rdfs:label>Richard</rdfs:label>
        <rdf:type rdf:resource="&exa;Student"/>
    </owl:Thing>

<owl:Thing rdf:about="&exa;LessonDB1">
        <rdf:type rdf:resource="&exa;Lesson"/>
        <isLessonOf rdf:resource="&exa;Databases"/>
    <wasFailedBy rdf:resource="&exa;Michael"/>
    </owl:Thing>

<owl:Thing rdf:about="&exa;LessonDB2">
        <rdf:type rdf:resource="&exa;Lesson"/>
        <isLessonOf rdf:resource="&exa;Databases"/>
    <wasFailedBy rdf:resource="&exa;Michael"/>
    <wasFailedBy rdf:resource="&exa;Richard"/>
    </owl:Thing>
    
    <owl:Thing rdf:about="&exa;LessonCP1">
        <rdf:type rdf:resource="&exa;Lesson"/>
        <isLessonOf rdf:resource="&exa;ComputerProgramming"/>
    <wasFailedBy rdf:resource="&exa;Richard"/>
    </owl:Thing>
    
    <owl:Thing rdf:about="&exa;LessonCP2">
        <rdf:type rdf:resource="&exa;Lesson"/>
        <isLessonOf rdf:resource="&exa;ComputerProgramming"/>
        <wasFailedBy rdf:resource="&exa;Michael"/>
    <wasFailedBy rdf:resource="&exa;Richard"/>
    </owl:Thing>
    
</rdf:RDF>




Re: call a Sparql command in a rule, is it possible?

Posted by Dave Reynolds <da...@gmail.com>.
On 06/12/13 16:25, Dave Reynolds wrote:
> On 06/12/13 15:02, Miguel Bento Alves wrote:
>> Dear Dave,
>>
>> "It should be perfectly possible to develop a rule built-in function that
>> executes a SPARQL query over the underlying base graph.²
>> How I can do that? T can¹t find out.
>
> Start with
> http://jena.apache.org/documentation/inference/#RULEextensions then look
> at source code for existing builtins.
>
>> You are saying with the mechanisms of the built-in functions and not
>> using
>> built-in functions to do an external calling, correct?
>
> Sorry I can't parse that question.
>
>> Can you give me a short example?
>
> See e.g. the NoValue class.

And see RuleMap as an example of creating and wiring in a new builtin.

Dave



Re: call a Sparql command in a rule, is it possible?

Posted by Dave Reynolds <da...@gmail.com>.
On 06/12/13 15:02, Miguel Bento Alves wrote:
> Dear Dave,
>
> "It should be perfectly possible to develop a rule built-in function that
> executes a SPARQL query over the underlying base graph.²
> How I can do that? T can¹t find out.

Start with 
http://jena.apache.org/documentation/inference/#RULEextensions then look 
at source code for existing builtins.

> You are saying with the mechanisms of the built-in functions and not using
> built-in functions to do an external calling, correct?

Sorry I can't parse that question.

> Can you give me a short example?

See e.g. the NoValue class.

Dave


Re: call a Sparql command in a rule, is it possible?

Posted by Miguel Bento Alves <mb...@gmail.com>.
Dear Dave,

"It should be perfectly possible to develop a rule built-in function that
executes a SPARQL query over the underlying base graph.²
How I can do that? T can¹t find out.
You are saying with the mechanisms of the built-in functions and not using
built-in functions to do an external calling, correct?
Can you give me a short example?

Miguel

On 06/12/13 08:32, "Dave Reynolds" <da...@gmail.com> wrote:

>It should be perfectly possible to develop a rule built-in function that
>executes a SPARQL query over the underlying base graph.



Re: call a Sparql command in a rule, is it possible?

Posted by Dave Reynolds <da...@gmail.com>.
It should be perfectly possible to develop a rule built-in function that 
executes a SPARQL query over the underlying base graph.

If you need the SPARQL to also see the results of earlier forward 
deductions then that would be possible (create a dynamic union of the 
base and deductions graphs) but more dangerous. Dangerous in the sense 
that your builtin is then exposing the state of the rule processing so 
you would need to careful that the rules which use it have suitable 
guard clauses to ensure that they are only fired when it makes sense to 
issue the query.

Dave

On 06/12/13 00:20, Miguel Bento Alves wrote:
> Is it possible call a Sparql command in a rule? Can we do that with a custom
> built-in function?
>
> An example:
>
> let's consider that I have the classes Student, Course and Lesson. Lesson is
> related with Course. I have an ObjectProperty wasFailedBy that defines that
> a given student fails to a given lesson (I list my schema and my data
> example below). I want to define an ObjectProperty isDiligent that defines
> that a given student is diligent to a given course. I consider that a given
> student is diligent to a given course if he didn't fails more than a given
> number of lessons (let's consider 1). I can't get this information with OWL
> or OWL2 inference, I only can get with a Sparql command.
>
> I'm thinking to define my rule in this way:
>
> (?Student ex:isDiligent ?Course) <-
> (?Student rdf:type ex:Student),
> (?Course rdf:type ex:Course),
> execSparql('
> prefix exa: <http://www.example.org/example#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> SELECT (COUNT(1) AS ?nCount)
> WHERE {
> ?V1_Student ex:failsTo ?Lesson .
> ?Lesson exa:isLessonOf ?V2_Course .
> }', ?Student, ?Course, ?NCount),
> le(?NCount, 1).
>
> In my idea, the custom built-in function execSparql receives as parameters a
> string with a Sparql command, a list of instanced variables to be replaced
> inside the function and will return the result in the last variable passed
> as parameter. I didn't implemented yet because I have doubts if this is the
> better approach. My main doubts is:
> Can I execute a Sparql command inside a custom built-in function using de
> RuleContext?
> Can I use a custom built-in function only to be an external access from the
> rule and call the Sparql command, for instance via Web Service, to my
> inference engine? Any better ideas?
>
>
> <?xml version="1.0"?>
>
>
> <!DOCTYPE rdf:RDF [
>      <!ENTITY owl "http://www.w3.org/2002/07/owl#" >
>      <!ENTITY exa "http://www.example.org/example#" >
>      <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
>      <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >
>      <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
> ]>
>
>
> <rdf:RDF xmlns="http://www.example.org/example#"
>       xml:base="http://www.example.org/example#"
>       xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
>       xmlns:owl="http://www.w3.org/2002/07/owl#"
>       xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
>       xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>       xmlns:exa="http://www.example.org/example#">
>
>
>
>      <!--
>
> ////////////////////////////////////////////////////////////////////////////
> ///////////
>      //
>      // Object Properties
>      //
>
> ////////////////////////////////////////////////////////////////////////////
> ///////////
>       -->
>
> <owl:ObjectProperty rdf:about="&exa;isLessonOf">
>          <rdfs:label>wasFailedBy</rdfs:label>
>          <rdfs:domain rdf:resource="&exa;Lesson"/>
>          <rdfs:range rdf:resource="&exa;Course"/>
>      </owl:ObjectProperty>
>
>
> <owl:ObjectProperty rdf:about="&exa;wasFailedBy">
>          <rdfs:label>wasFailedBy</rdfs:label>
>          <rdfs:domain rdf:resource="&exa;Lesson"/>
>          <rdfs:range rdf:resource="&exa;Student"/>
>      </owl:ObjectProperty>
>
>      <owl:ObjectProperty rdf:about="&exa;failsTo">
>          <rdfs:label>failsTo</rdfs:label>
>          <owl:inverseOf rdf:resource="&exa;wasFailedBy"/>
>      </owl:ObjectProperty>
>
>
>      <!--
>
> ////////////////////////////////////////////////////////////////////////////
> ///////////
>      //
>      // Classes
>      //
>
> ////////////////////////////////////////////////////////////////////////////
> ///////////
>       -->
>
>     <owl:Class rdf:about="&exa;Student">
>          <rdfs:label>Student</rdfs:label>
>      </owl:Class>
>
>     <owl:Class rdf:about="&exa;Course">
>          <rdfs:label>Course</rdfs:label>
>      </owl:Class>
>
>     <owl:Class rdf:about="&exa;Lesson">
>          <rdfs:label>Lesson</rdfs:label>
>      </owl:Class>
>
>
>
>      <!--
>
> ////////////////////////////////////////////////////////////////////////////
> ///////////
>      //
>      // Individuals
>      //
>
> ////////////////////////////////////////////////////////////////////////////
> ///////////
>       -->
>
>
>      <owl:Thing rdf:about="&exa;Databases">
>          <rdfs:label>Databases</rdfs:label>
>          <rdf:type rdf:resource="&exa;Course"/>
>      </owl:Thing>
>
>
>
>      <owl:Thing rdf:about="&exa;ComputerProgramming">
>          <rdfs:label>Computer Programming</rdfs:label>
>          <rdf:type rdf:resource="&exa;Course"/>
>      </owl:Thing>
>
>
> <owl:Thing rdf:about="&exa;Michael">
>          <rdfs:label>Michael</rdfs:label>
>          <rdf:type rdf:resource="&exa;Student"/>
>      </owl:Thing>
>
> <owl:Thing rdf:about="&exa;Richard">
>          <rdfs:label>Richard</rdfs:label>
>          <rdf:type rdf:resource="&exa;Student"/>
>      </owl:Thing>
>
> <owl:Thing rdf:about="&exa;LessonDB1">
>          <rdf:type rdf:resource="&exa;Lesson"/>
>          <isLessonOf rdf:resource="&exa;Databases"/>
>      <wasFailedBy rdf:resource="&exa;Michael"/>
>      </owl:Thing>
>
> <owl:Thing rdf:about="&exa;LessonDB2">
>          <rdf:type rdf:resource="&exa;Lesson"/>
>          <isLessonOf rdf:resource="&exa;Databases"/>
>      <wasFailedBy rdf:resource="&exa;Michael"/>
>      <wasFailedBy rdf:resource="&exa;Richard"/>
>      </owl:Thing>
>
>      <owl:Thing rdf:about="&exa;LessonCP1">
>          <rdf:type rdf:resource="&exa;Lesson"/>
>          <isLessonOf rdf:resource="&exa;ComputerProgramming"/>
>      <wasFailedBy rdf:resource="&exa;Richard"/>
>      </owl:Thing>
>
>      <owl:Thing rdf:about="&exa;LessonCP2">
>          <rdf:type rdf:resource="&exa;Lesson"/>
>          <isLessonOf rdf:resource="&exa;ComputerProgramming"/>
>          <wasFailedBy rdf:resource="&exa;Michael"/>
>      <wasFailedBy rdf:resource="&exa;Richard"/>
>      </owl:Thing>
>
> </rdf:RDF>
>
>
>
>


Re: call a Sparql command in a rule, is it possible?

Posted by Joshua TAYLOR <jo...@gmail.com>.
On Sat, Dec 7, 2013 at 4:16 AM, Miguel Bento Alves
<mb...@gmail.com> wrote:
> Dear Joshua,
>
> The problem is that I don¹t want only to know if a given Student is
> diligent but I want to know if a given Student is diligent to a given
> Course. If you look to the data that I listed as example, Richard was
> diligent in Databases and Michael was diligent in Computer Programming
> (and Michael was not diligent in Databases and Richard was not diligent in
> Computer Programming). In the best of my knowledge, you cannot moddeled
> this in OWL2.


Ah, I did miss that subtlety in the original.  Even so, I think you
could model this if you associate the lessons with the courses.  E.g.,
you could have something like

    cs101 ^forCourse l0, l1, l2, l3, l4.
    cs102 ^forCourse l5, l6, l7, l8, l9.

   forCourse a owl:FunctionalProperty
   cs101 ≠ cs102

Then, the class of students that are diligent in a course C are

    failed max 3 ( forCourse value C )

The class of Courses for which a student S is diligent is

    ^forCourse max 3 ( ^failed value S )

You can make those queries if you've fixed C or S.  If you need a list
of all S/C pairs, though, then you're right, you'll need a SPARQL
query.
-- 
Joshua Taylor, http://www.cs.rpi.edu/~tayloj/

RE: call a Sparql command in a rule, is it possible?

Posted by Ed Swing <Ed...@sas.com>.
One possible way would be to model the data using the course as a property:

	Richard hasDatabasePerformance diligent

Or perhaps the diligence is the property:

	Richard performedDiligently Databases


-----Original Message-----
From: Miguel Bento Alves [mailto:mbentoalves@gmail.com] 
Sent: Saturday, December 07, 2013 4:17 AM
To: users@jena.apache.org
Subject: Re: call a Sparql command in a rule, is it possible?

Dear Joshua,

The problem is that I don¹t want only to know if a given Student is diligent but I want to know if a given Student is diligent to a given Course. If you look to the data that I listed as example, Richard was diligent in Databases and Michael was diligent in Computer Programming (and Michael was not diligent in Databases and Richard was not diligent in Computer Programming). In the best of my knowledge, you cannot moddeled this in OWL2. 

Miguel


On 07/12/13 02:42, "Joshua TAYLOR" <jo...@gmail.com> wrote:

>On Thu, Dec 5, 2013 at 7:20 PM, Miguel Bento Alves 
><mb...@gmail.com> wrote:
>> I consider that a given
>> student is diligent to a given course if he didn't fails more than a 
>>given  number of lessons (let's consider 1). I can't get this 
>>information with OWL  or OWL2 inference, I only can get with a Sparql 
>>command.
>
>I realize that the main thread here "how to execute a SPARQL query from 
>a rule builtin", but I would point out that you _can_ express this in 
>OWL2 (though I don't know whether Jena's OWL rules could handle it). 
>For instance, if John has failed two courses and you've added this to 
>your data:
>
>  john failed csci102
>  john failed csci103
>  john failed only {csci102, csci103}
>
>then you can infer that john in a member of the class
>
>  failed max 2 courses
>
>You don't even need to assert that the courses are distinct;  the 
>"failed only { ... }" axiom puts an upper bound on the number of 
>courses failed.
>
>--
>Joshua Taylor, http://www.cs.rpi.edu/~tayloj/





Re: call a Sparql command in a rule, is it possible?

Posted by Miguel Bento Alves <mb...@gmail.com>.
Dear Joshua,

The problem is that I don¹t want only to know if a given Student is
diligent but I want to know if a given Student is diligent to a given
Course. If you look to the data that I listed as example, Richard was
diligent in Databases and Michael was diligent in Computer Programming
(and Michael was not diligent in Databases and Richard was not diligent in
Computer Programming). In the best of my knowledge, you cannot moddeled
this in OWL2. 

Miguel


On 07/12/13 02:42, "Joshua TAYLOR" <jo...@gmail.com> wrote:

>On Thu, Dec 5, 2013 at 7:20 PM, Miguel Bento Alves
><mb...@gmail.com> wrote:
>> I consider that a given
>> student is diligent to a given course if he didn't fails more than a
>>given
>> number of lessons (let's consider 1). I can't get this information with
>>OWL
>> or OWL2 inference, I only can get with a Sparql command.
>
>I realize that the main thread here "how to execute a SPARQL query
>from a rule builtin", but I would point out that you _can_ express
>this in OWL2 (though I don't know whether Jena's OWL rules could
>handle it). For instance, if John has failed two courses and you've
>added this to your data:
>
>  john failed csci102
>  john failed csci103
>  john failed only {csci102, csci103}
>
>then you can infer that john in a member of the class
>
>  failed max 2 courses
>
>You don't even need to assert that the courses are distinct;  the
>"failed only { ... }" axiom puts an upper bound on the number of
>courses failed.
>
>-- 
>Joshua Taylor, http://www.cs.rpi.edu/~tayloj/



Re: call a Sparql command in a rule, is it possible?

Posted by Joshua TAYLOR <jo...@gmail.com>.
On Thu, Dec 5, 2013 at 7:20 PM, Miguel Bento Alves
<mb...@gmail.com> wrote:
> I consider that a given
> student is diligent to a given course if he didn't fails more than a given
> number of lessons (let's consider 1). I can't get this information with OWL
> or OWL2 inference, I only can get with a Sparql command.

I realize that the main thread here "how to execute a SPARQL query
from a rule builtin", but I would point out that you _can_ express
this in OWL2 (though I don't know whether Jena's OWL rules could
handle it). For instance, if John has failed two courses and you've
added this to your data:

  john failed csci102
  john failed csci103
  john failed only {csci102, csci103}

then you can infer that john in a member of the class

  failed max 2 courses

You don't even need to assert that the courses are distinct;  the
"failed only { ... }" axiom puts an upper bound on the number of
courses failed.

-- 
Joshua Taylor, http://www.cs.rpi.edu/~tayloj/

Re: call a Sparql command in a rule, is it possible?

Posted by Martynas Jusevičius <ma...@graphity.org>.
Miguel,

not exactly sure, but maybe SPIN rules could help you?
http://spinrdf.org/spin.html#spin-rules

Martynas

On Fri, Dec 6, 2013 at 1:20 AM, Miguel Bento Alves
<mb...@gmail.com> wrote:
> Is it possible call a Sparql command in a rule? Can we do that with a custom
> built-in function?
>
> An example:
>
> let's consider that I have the classes Student, Course and Lesson. Lesson is
> related with Course. I have an ObjectProperty wasFailedBy that defines that
> a given student fails to a given lesson (I list my schema and my data
> example below). I want to define an ObjectProperty isDiligent that defines
> that a given student is diligent to a given course. I consider that a given
> student is diligent to a given course if he didn't fails more than a given
> number of lessons (let's consider 1). I can't get this information with OWL
> or OWL2 inference, I only can get with a Sparql command.
>
> I'm thinking to define my rule in this way:
>
> (?Student ex:isDiligent ?Course) <-
> (?Student rdf:type ex:Student),
> (?Course rdf:type ex:Course),
> execSparql('
> prefix exa: <http://www.example.org/example#>
> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
> SELECT (COUNT(1) AS ?nCount)
> WHERE {
> ?V1_Student ex:failsTo ?Lesson .
> ?Lesson exa:isLessonOf ?V2_Course .
> }', ?Student, ?Course, ?NCount),
> le(?NCount, 1).
>
> In my idea, the custom built-in function execSparql receives as parameters a
> string with a Sparql command, a list of instanced variables to be replaced
> inside the function and will return the result in the last variable passed
> as parameter. I didn't implemented yet because I have doubts if this is the
> better approach. My main doubts is:
> Can I execute a Sparql command inside a custom built-in function using de
> RuleContext?
> Can I use a custom built-in function only to be an external access from the
> rule and call the Sparql command, for instance via Web Service, to my
> inference engine? Any better ideas?
>
>
> <?xml version="1.0"?>
>
>
> <!DOCTYPE rdf:RDF [
>     <!ENTITY owl "http://www.w3.org/2002/07/owl#" >
>     <!ENTITY exa "http://www.example.org/example#" >
>     <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
>     <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >
>     <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
> ]>
>
>
> <rdf:RDF xmlns="http://www.example.org/example#"
>      xml:base="http://www.example.org/example#"
>      xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
>      xmlns:owl="http://www.w3.org/2002/07/owl#"
>      xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
>      xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>      xmlns:exa="http://www.example.org/example#">
>
>
>
>     <!--
>
> ////////////////////////////////////////////////////////////////////////////
> ///////////
>     //
>     // Object Properties
>     //
>
> ////////////////////////////////////////////////////////////////////////////
> ///////////
>      -->
>
> <owl:ObjectProperty rdf:about="&exa;isLessonOf">
>         <rdfs:label>wasFailedBy</rdfs:label>
>         <rdfs:domain rdf:resource="&exa;Lesson"/>
>         <rdfs:range rdf:resource="&exa;Course"/>
>     </owl:ObjectProperty>
>
>
> <owl:ObjectProperty rdf:about="&exa;wasFailedBy">
>         <rdfs:label>wasFailedBy</rdfs:label>
>         <rdfs:domain rdf:resource="&exa;Lesson"/>
>         <rdfs:range rdf:resource="&exa;Student"/>
>     </owl:ObjectProperty>
>
>     <owl:ObjectProperty rdf:about="&exa;failsTo">
>         <rdfs:label>failsTo</rdfs:label>
>         <owl:inverseOf rdf:resource="&exa;wasFailedBy"/>
>     </owl:ObjectProperty>
>
>
>     <!--
>
> ////////////////////////////////////////////////////////////////////////////
> ///////////
>     //
>     // Classes
>     //
>
> ////////////////////////////////////////////////////////////////////////////
> ///////////
>      -->
>
>    <owl:Class rdf:about="&exa;Student">
>         <rdfs:label>Student</rdfs:label>
>     </owl:Class>
>
>    <owl:Class rdf:about="&exa;Course">
>         <rdfs:label>Course</rdfs:label>
>     </owl:Class>
>
>    <owl:Class rdf:about="&exa;Lesson">
>         <rdfs:label>Lesson</rdfs:label>
>     </owl:Class>
>
>
>
>     <!--
>
> ////////////////////////////////////////////////////////////////////////////
> ///////////
>     //
>     // Individuals
>     //
>
> ////////////////////////////////////////////////////////////////////////////
> ///////////
>      -->
>
>
>     <owl:Thing rdf:about="&exa;Databases">
>         <rdfs:label>Databases</rdfs:label>
>         <rdf:type rdf:resource="&exa;Course"/>
>     </owl:Thing>
>
>
>
>     <owl:Thing rdf:about="&exa;ComputerProgramming">
>         <rdfs:label>Computer Programming</rdfs:label>
>         <rdf:type rdf:resource="&exa;Course"/>
>     </owl:Thing>
>
>
> <owl:Thing rdf:about="&exa;Michael">
>         <rdfs:label>Michael</rdfs:label>
>         <rdf:type rdf:resource="&exa;Student"/>
>     </owl:Thing>
>
> <owl:Thing rdf:about="&exa;Richard">
>         <rdfs:label>Richard</rdfs:label>
>         <rdf:type rdf:resource="&exa;Student"/>
>     </owl:Thing>
>
> <owl:Thing rdf:about="&exa;LessonDB1">
>         <rdf:type rdf:resource="&exa;Lesson"/>
>         <isLessonOf rdf:resource="&exa;Databases"/>
>     <wasFailedBy rdf:resource="&exa;Michael"/>
>     </owl:Thing>
>
> <owl:Thing rdf:about="&exa;LessonDB2">
>         <rdf:type rdf:resource="&exa;Lesson"/>
>         <isLessonOf rdf:resource="&exa;Databases"/>
>     <wasFailedBy rdf:resource="&exa;Michael"/>
>     <wasFailedBy rdf:resource="&exa;Richard"/>
>     </owl:Thing>
>
>     <owl:Thing rdf:about="&exa;LessonCP1">
>         <rdf:type rdf:resource="&exa;Lesson"/>
>         <isLessonOf rdf:resource="&exa;ComputerProgramming"/>
>     <wasFailedBy rdf:resource="&exa;Richard"/>
>     </owl:Thing>
>
>     <owl:Thing rdf:about="&exa;LessonCP2">
>         <rdf:type rdf:resource="&exa;Lesson"/>
>         <isLessonOf rdf:resource="&exa;ComputerProgramming"/>
>         <wasFailedBy rdf:resource="&exa;Michael"/>
>     <wasFailedBy rdf:resource="&exa;Richard"/>
>     </owl:Thing>
>
> </rdf:RDF>
>
>
>