Search code examples
rdfowlontology

Ontology design about creating subclasses with static object values


I have a question related to an ontology design. Assume that I have a Test-Student relation. Student can have one or more English tests (different types). I am writing the data point of view here so first I created the following triples (not everything might make sense, the numbers,types etc are representative). But test range and test style are always going to be the same for the student.

<http://example.org/student1_english_test>
    a       <http://example.org/EnglishTest> ;
    <http://example.org/testResult>
            "80"^^<http://www.w3.org/2001/XMLSchema#double> ;
    <http://example.org/testType>
            <http://example.org/test/TOEFL_test> ;
    <http://example.org/testRange>
            <http://example.org/1-100> ;
    <http://example.org/testStyle>
            <http://example.org/Facultative> .

However, I noticed that test range and test style were repetitive so I wanted to create TOEFL and IELTS as subclasses of English test so that I define them once with relevant properties and describe it once so that they dont repeat. Can I use directly like as follows? In that case how can I describe the values for the predicates test range and test style?

<http://example.org/student1_english_test>
    a       <http://example.org/TOEFL_test> ;

This means that if a student takes a TOEFL test then he always will be Facultative and between the range of 1-100. However, this is where I got confused. If I define them as subclasses, is it possible to define some static objects for them? Or do I have to create them as instances?

    <http://example.org/student1_english_test>
    a       <http://example.org/EnglishTest> ;
    <http://example.org/testType>
            <http://example.org/TOEFL_test> ;
    <http://example.org/testResult>
            "80"^^<http://www.w3.org/2001/XMLSchema#double> .

  <http://example.org/xxx>
     a       <http://example.org/test/TOEFL_test> ;
     <http://example.org/testStyle>
          <http://example.org/Facultative> ;
     <http://example.org#testRange>
           <http://example.org/1-100>  .

    <http://example.org/yyy>
      a       <http://example.org/test/IELTS_test> ;
      <http://example.org/testType>
              <http://example.org/Oral> ;
      <http://example.org#testRange>
              <http://example.org/1.0-4.0>.  

Solution

  • In RDF you can apply a property to anything, be it an individual or a class, but the design of your ontology (and vocabulary for that matter) depends on the conveniences you want to achieve. There are several options:

    A property of the class

    You could keep the class like <TOEFL_test> and apply specific properties to it:

    <TOEFL_test> a rdfs:Class ;
      <testStyle> <Facultative> ;
      <testRange> <1-100> .
    
    <IELTS_test> a rdfs:Class ;
      <testStyle> <Oral> ;
      <testRange> <1.0-4.0> .
    

    This is the simplest way to define it, but it is not much convenient to use: OWL cannot be used to treat a class as an individual (or vice versa), so these properties will be essentially invisible when you use the class in any way. What works however is using SPARQL, since you can write easily ?test a/<testStyle> ?style to obtain the style without having to define it on the individual.

    A statement about the class

    If you want to keep the existing definition of <testStyle> and <testRange>, you can make some specific statements about each class that adds the respective property to all individuals:

    <TOEFL_test> rdfs:subClassOf [
      a owl:Restriction ;
      owl:onProperty <testStyle> ;
      owl:hasValue <Facultative>
    ] , [
      a owl:Restriction ;
      owl:onProperty <testRange> ;
      owl:hasValue <1-100>
    ] .
    
    <IELTS_test> rdfs:subClassOf [
      a owl:Restriction ;
      owl:onProperty <testStyle> ;
      owl:hasValue <Oral>
    ] , [
      a owl:Restriction ;
      owl:onProperty <testRange> ;
      owl:hasValue <1.0-4.0>
    ] .
    

    This also lets you keep the individual test types as classes while implying information about the individual tests, but it is a bit complex and requires you to specify this each time you add a new test type.

    Using individuals

    Perhaps the best way is not to use classes at all and return to individual test types:

    <TOEFL_test>
      <testStyle> <Facultative> ;
      <testRange> <1-100> .
    
    <IELTS_test>
      <testStyle> <Oral> ;
      <testRange> <1.0-4.0> .
    
    <student1_english_test>
      <testType> <TOEFL_test> .
    

    You could still entail <testStyle> and <testRange> triples for each individual test via a property chain axiom:

    <testStyle> owl:propertyChainAxiom ( <testType> <testStyle> ) .
    <testRange> owl:propertyChainAxiom ( <testType> <testRange> ) .
    

    You don't have to write anything complicated for each test type and the relevant information can be obtained easily through both OWL and SPARQL.