如何使用Jena API将资源与其他资源相关联

时间:2013-09-13 21:35:22

标签: java jena ontology owl

我创建了一个包含两个类的本体,第一个名为Father,第二个是名为Son的子类。我想使用Jena为类父设置以下条件

  

只有儿子。
有一些儿子。

然后我会对班级Son做同样的事情:

  

确实有一些父亲。

我的第二个问题是我不知道如何使用Jena将类Son的实例与类Father相关联。我知道使用Protégé操纵我的课程是可能的,但我想探索耶拿。

1 个答案:

答案 0 :(得分:5)

你想要做的事情在耶拿并不是很困难,但听起来有一些关于OWL的困惑。给定两个类 B C ,如果 B C 的子类,则意味着每个都是 B 也是 C

这是真的
  

(1)父亲subClassOf Son

因为每个父亲也是别人的儿子,所以

是不正确的
  

(2)Son subClassOf Father

因为不是每个儿子都是父亲。你所描述的限制也没有多大意义。可以使用基数限制来断言某个类的每个实例与某个特定属性的确切(或至少,或最多)某个特定数量的另一个类的实例相关。因此,您可能会说

  

(3)Son subClassOf(hasFather恰好是1个父亲)

断言Son的每个实例都与父的一个实例相关。你也可以说每个父亲必须至少有一个孩子(我在这里使用孩子,而不是儿子,因为孩子也可以是女儿)

  

(4)父亲subClassOf(hasChild some Child)

但如果你只是为男性造型,我想你可以说

  

(5)父亲subClassOf(hasSon some Son)

  

(6)父亲subClassOf(hasSon min 1 Son)

让我们创建一个包含Son和Father类以及公理(1),(3)和(5)的OntModel。然后我们将添加一个父亲AbrahamLincoln的实例,以及Son,RobertToddLincoln的实例,以及他们之间的适当关系:

  (7)RobertToddLincoln有父亲AbrahamLincoln   (8)AbrahamLincoln有Son Robert ToddLincoln

现在,我们实际上会立即遇到一个问题:量化的基数限制是OWL2的一部分,但不是OWL1的一部分,Jena还不支持OWL2。幸运的是,在这种情况下,我们可以解决这个问题,但是说儿子只有父亲作为父亲,并且儿子只有一个父亲:

  

(3'a)Son subClassOf(hasFather only Father)
  (3'b)Son subClassOf(hasFather恰好是1)

您最终得到的代码是:

import com.hp.hpl.jena.ontology.Individual;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.rdf.model.ModelFactory;

public class FatherSonOntology {
    public static void main(String[] args) {
        final String ns = "http://example.org/";

        final OntModel model = ModelFactory.createOntologyModel( OntModelSpec.OWL_DL_MEM );
        model.setNsPrefix( "ex", ns );

        final OntClass son = model.createClass( ns+"Son" );
        final OntClass father = model.createClass( ns+"Father" );

        final OntProperty hasFather = model.createObjectProperty( ns+"hasFather" );
        final OntProperty hasSon = model.createObjectProperty( ns+"hasSon" );

        // (1) Father subClassOf Son
        son.addSubClass( father );

        // (3'a) Son subClassOf (hasFather only Father)
        son.addSubClass( model.createAllValuesFromRestriction( null, hasFather, father ));

        // (3'b) Son subClassOf (hasFather exactly 1)
        son.addSubClass( model.createCardinalityRestriction( null, hasFather, 1 ));

        // (5) Father subClassOf (hasSon min 1 Son)
        father.addSubClass( model.createSomeValuesFromRestriction( null, hasSon, son ));

        // You can create individuals of a given type using Individual#createIndividual, 
        // or with Model#createIndividual.
        final Individual abe = father.createIndividual( ns+"AbrahamLincoln" );
        final Individual rob = model.createIndividual( ns+"RobertToddLincoln", son );

        // You can add properties to individuals using Individual#addProperty, or you can 
        // use the various Model#add methods to add statements to the model.
        rob.addProperty( hasFather, abe ); // (7) 
        model.add( abe, hasSon, rob );     // (8)

        model.write( System.out, "RDF/XML-ABBREV" );
    }
}

在最后打印本体(您可以在Protégé中保存和打开以检查所有内容是否按预期显示):

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:ex="http://example.org/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
  <owl:Class rdf:about="http://example.org/Father">
    <rdfs:subClassOf>
      <owl:Class rdf:about="http://example.org/Son"/>
    </rdfs:subClassOf>
  </owl:Class>
  <owl:ObjectProperty rdf:about="http://example.org/hasSon"/>
  <owl:ObjectProperty rdf:about="http://example.org/hasFather"/>
  <owl:Restriction>
    <rdfs:subClassOf rdf:resource="http://example.org/Son"/>
    <owl:allValuesFrom rdf:resource="http://example.org/Father"/>
    <owl:onProperty rdf:resource="http://example.org/hasFather"/>
  </owl:Restriction>
  <owl:Restriction>
    <rdfs:subClassOf rdf:resource="http://example.org/Father"/>
    <owl:someValuesFrom rdf:resource="http://example.org/Son"/>
    <owl:onProperty rdf:resource="http://example.org/hasSon"/>
  </owl:Restriction>
  <owl:Restriction>
    <rdfs:subClassOf rdf:resource="http://example.org/Son"/>
    <owl:cardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#int"
    >1</owl:cardinality>
    <owl:onProperty rdf:resource="http://example.org/hasFather"/>
  </owl:Restriction>
  <ex:Son rdf:about="http://example.org/RobertToddLincoln">
    <ex:hasFather>
      <ex:Father rdf:about="http://example.org/AbrahamLincoln">
        <ex:hasSon rdf:resource="http://example.org/RobertToddLincoln"/>
      </ex:Father>
    </ex:hasFather>
  </ex:Son>
</rdf:RDF>