Search code examples
jenareasoningjena-rules

rdf reasoning rules via Jena


I want to express this relation: if article X has author Y, and the author has the influenceFactor medium or high(3 classes: low , medium, high) then this article is regarded as highly recommended.

(?x computer-science#hasAuthor ?y)(?y computer-science#hasInfluenceFactor computer-science#High) -> (?x computer-science#isImportant computer-science#importantfactor)

is my thought right?

here is some snippet of the ontology

<owl:ObjectProperty rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#hasAuthor">
    <rdf:type rdf:resource="&owl;TransitiveProperty"/>
    <owl:propertyDisjointWith rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#isAuthorOf"/>
    <rdfs:range>
        <owl:Restriction>
            <owl:onProperty rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#hasAuthor"/>
            <owl:someValuesFrom rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#author"/>
        </owl:Restriction>
    </rdfs:range>
    <rdfs:domain>
        <owl:Restriction>
            <owl:onProperty rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#hasAuthor"/>
            <owl:someValuesFrom rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#article"/>
        </owl:Restriction>
    </rdfs:domain>
</owl:ObjectProperty>
   <owl:ObjectProperty rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#hasInfluenceFactor">
    <rdf:type rdf:resource="&owl;TransitiveProperty"/>
    <rdfs:domain rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#author"/>
    <rdfs:range rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#influenceFator"/>
</owl:ObjectProperty>
<owl:NamedIndividual rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#High">
    <rdf:type rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#influenceFator"/>
</owl:NamedIndividual>
<owl:ObjectProperty rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#isImportant">
    <rdf:type rdf:resource="&owl;TransitiveProperty"/>
    <rdfs:range rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#importantFactor"/>
    <rdfs:domain rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#influenceFator"/>
</owl:ObjectProperty>
  <owl:NamedIndividual rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#importantFactor">
    <rdf:type rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#importantFactor"/>
</owl:NamedIndividual>

sincere thanks to any viewer of my question :)


Solution

  • You don't need to create a rule to express your ontology, you can do it entirely in OWL. First we define an ontology based on your example, but with some new axioms. In particular, we define two new class expressions: InfluentialArticle and ImportantArticle. An influential article has high or medium impact, an important author wrote at least one influential article:

    @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
    @prefix owl: <http://www.w3.org/2002/07/owl#>.
    @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
    @prefix cs: <http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#>.
    
    # properties
    cs:hasAuthor
      a       owl:ObjectProperty ;
      rdfs:domain cs:Article ;
      rdfs:range cs:Author .
    
    cs:wrote
      a owl:ObjectPropert ;
      owl:inverseOf cs:hasAuthor .
    
    # classes
    cs:hasInfluenceFactor
      a       owl:ObjectProperty ;
      rdfs:domain cs:Article ;
      rdfs:range cs:InfluenceFactor .
    
    cs:InfluenceFactor
      owl:equivalentClass
        [a owl:Class ;
         owl:oneOf ( cs:high cs:medium cs:low )
        ].
    
    cs:Author a owl:Class.
    cs:Article a owl:Class.
    
    # axioms
    
    # an influential article has a high or medium impact
    cs:InfluentialArticle
      rdfs:subClassOf cs:Article ;
      owl:equivalentClass [
        owl:unionOf (
          [a owl:Restriction ;
           owl:onProperty cs:hasInfluenceFactor ;
           owl:hasValue cs:high]
          [a owl:Restriction ;
           owl:onProperty cs:hasInfluenceFactor ;
           owl:hasValue cs:medium
          ]
        )
      ].
    
    # an important author wrote an influential article
    cs:ImportantAuthor
      rdfs:subClassOf cs:Author ;
      owl:equivalentClass [
        a owl:Restriction ;
        owl:onProperty cs:wrote ;
        owl:someValuesFrom cs:InfluentialArticle
      ].
    
    # individuals
    
    # fred wrote a lousy paper
    cs:fred
      a cs:Author.
    cs:article1
      a cs:Article ;
      cs:hasInfluenceFactor cs:low ;
      cs:hasAuthor cs:fred.
    
    # jane wrote a good paper
    cs:jane
      a cs:Author.
    cs:article2
      a cs:Article ;
      cs:hasInfluenceFactor cs:high ;
      cs:hasAuthor cs:jane.
    

    Now we can write some Jena code to load this ontology and process it with a built-in reasoner:

    package examples;
    
    import java.util.Iterator;
    
    import com.hp.hpl.jena.ontology.*;
    import com.hp.hpl.jena.rdf.model.ModelFactory;
    import com.hp.hpl.jena.util.FileManager;
    
    public class ReasonerExample
    {
        String NS = "http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#";
    
        public static void main( String[] args ) {
            new ReasonerExample().run();
        }
    
        public void run() {
            OntModel m = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM_MICRO_RULE_INF );
            FileManager.get().readModel( m, "src/main/resources/comp-sci.ttl" );
    
            // list all authors
            System.out.println( "All authors:" );
            OntClass author = m.getOntClass( NS + "Author" );
            for (Iterator<? extends OntResource> i = author.listInstances(); i.hasNext(); ) {
                System.out.println( "  " + i.next().getURI() );
            }
    
            // list high impact authors
            OntClass importantAuthor = m.getOntClass( NS + "ImportantAuthor" );
            System.out.println( "Important authors:" );
            for (Iterator<? extends OntResource> i = importantAuthor.listInstances(); i.hasNext(); ) {
                System.out.println( "  " + i.next().getURI() );
            }
        }
    }
    

    Which gives the following output:

    All authors:
      http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#jane
      http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#fred
    Important authors:
      http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#jane
    

    Note I also fixed your names to use OWL conventions: leading capital letter for classes, lower case for everything else. I also simplified the domain and range constraints, which were a bit weird.

    Update

    Following a comment from the original poster, I translated the ontology to RDF/XML using Jena's rdfcat tool as follows:

    <rdf:RDF
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns:cs="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#"
        xmlns:owl="http://www.w3.org/2002/07/owl#"
        xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
      <owl:Class rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#Article"/>
      <owl:Class rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#Author"/>
      <owl:ObjectProperty rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#hasAuthor">
        <rdfs:domain rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#Article"/>
        <rdfs:range rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#Author"/>
      </owl:ObjectProperty>
      <owl:ObjectProperty rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#hasInfluenceFactor">
        <rdfs:domain rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#Article"/>
        <rdfs:range>
          <rdf:Description rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#InfluenceFactor">
            <owl:equivalentClass>
              <owl:Class>
                <owl:oneOf rdf:parseType="Collection">
                  <rdf:Description rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#high"/>
                  <rdf:Description rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#medium"/>
                  <rdf:Description rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#low"/>
                </owl:oneOf>
              </owl:Class>
            </owl:equivalentClass>
          </rdf:Description>
        </rdfs:range>
      </owl:ObjectProperty>
      <rdf:Description rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#ImportantAuthor">
        <rdfs:subClassOf rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#Author"/>
        <owl:equivalentClass>
          <owl:Restriction>
            <owl:onProperty>
              <owl:ObjectPropert rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#wrote">
                <owl:inverseOf rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#hasAuthor"/>
              </owl:ObjectPropert>
            </owl:onProperty>
            <owl:someValuesFrom>
              <rdf:Description rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#InfluentialArticle">
                <rdfs:subClassOf rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#Article"/>
                <owl:equivalentClass rdf:parseType="Resource">
                  <owl:unionOf rdf:parseType="Collection">
                    <owl:Restriction>
                      <owl:onProperty rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#hasInfluenceFactor"/>
                      <owl:hasValue rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#high"/>
                    </owl:Restriction>
                    <owl:Restriction>
                      <owl:onProperty rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#hasInfluenceFactor"/>
                      <owl:hasValue rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#medium"/>
                    </owl:Restriction>
                  </owl:unionOf>
                </owl:equivalentClass>
              </rdf:Description>
            </owl:someValuesFrom>
          </owl:Restriction>
        </owl:equivalentClass>
      </rdf:Description>
      <cs:Article rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#article2">
        <cs:hasInfluenceFactor rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#high"/>
        <cs:hasAuthor>
          <cs:Author rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#jane"/>
        </cs:hasAuthor>
      </cs:Article>
      <cs:Article rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#article1">
        <cs:hasInfluenceFactor rdf:resource="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#low"/>
        <cs:hasAuthor>
          <cs:Author rdf:about="http://www.semanticweb.org/aero/ontologies/2013/1/computer-science#fred"/>
        </cs:hasAuthor>
      </cs:Article>
    </rdf:RDF>