Search code examples
jenaowlontology

support of owl:maxQualifiedCardinality and owl:minQualifiedCardinality restrictions by APACHE Jena Ont model


I am using APACHE Jena ONT model to parse RDF/XML OWL files and process them. With the current ONT model, restrictions with owl:maxQualifiedCardinality and owl:minQualifiedCardinality are not recognized in the ONT model. I also looked into the Restriction interface of org.apache.jena.ontology package and found that these restrictions are not supported, instead owl:minCardinality and owl:maxCardinality are supported. I am wondering now if there is a way that Jena ONT model can also consider these restrictions : owl:maxQualifiedCardinality, owl:minQualifiedCardinality

I will be happy if you can let me know your experience w.r.t. handlinge such restrictions and processing their data with Jena ont model

<owl:Class rdf:about="http://test#Numeric">
    <rdfs:subClassOf rdf:resource="http://test#Characteristic"/>
    <rdfs:subClassOf>
        <owl:Restriction>
            <owl:onProperty rdf:resource="http://test#hasUnit"/>
            <owl:maxQualifiedCardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">1</owl:maxQualifiedCardinality>
            <owl:onClass rdf:resource="http://test#Scale"/>
        </owl:Restriction>
    </rdfs:subClassOf>
    <rdfs:label>Numeric</rdfs:label>
</owl:Class>

Solution

  • Apache Jena ontology API (org.apache.jena.ontology.OntModel) does not support OWL2 DL. You can take a look at the Jena-based alternative (i.e. ONT-API). This is another jena interface special for OWL-2, which supports such things as owl:maxQualifiedCardinality

    Example:

        OntModel m = OntModelFactory.createModel();
        m.setID("http://test");
        OntObjectProperty property = m.createObjectProperty("http://test#hasUnit");
        OntClass clazz = m.createOntClass("http://test#Numeric");
        clazz.addLabel("Numeric", null);
        clazz.addSuperClass(m.createOntClass("http://test#Characteristic"))
                .addSuperClass(m.createObjectMaxCardinality(property, 1,
                        m.createOntClass("http://test#Scale")));
    
        StringWriter sw = new StringWriter();
        m.write(sw, "rdf/xml");
        System.out.println(sw);
    
        // another way to create OntGraphModel:
        InputStream in = new ByteArrayInputStream(sw.toString().getBytes(StandardCharsets.UTF_8));
        OntModel reloaded = OntManagers.createONT().loadOntologyFromOntologyDocument(in).asGraphModel();
        int cardinality = reloaded.ontObjects(OntClass.ObjectMaxCardinality.class)
                .mapToInt(OntClass.CardinalityRestrictionCE::getCardinality)
                .findFirst().orElseThrow(IllegalStateException::new);
        System.out.println(cardinality);
    

    The Output:

    <rdf:RDF
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns:owl="http://www.w3.org/2002/07/owl#"
        xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
      <owl:Ontology rdf:about="http://test"/>
      <owl:Class rdf:about="http://test#Characteristic"/>
      <owl:Class rdf:about="http://test#Scale"/>
      <owl:Class rdf:about="http://test#Numeric">
        <rdfs:subClassOf>
          <owl:Restriction>
            <owl:onClass rdf:resource="http://test#Scale"/>
            <owl:maxQualifiedCardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger"
            >1</owl:maxQualifiedCardinality>
            <owl:onProperty>
              <owl:ObjectProperty rdf:about="http://test#hasUnit"/>
            </owl:onProperty>
          </owl:Restriction>
        </rdfs:subClassOf>
        <rdfs:subClassOf rdf:resource="http://test#Characteristic"/>
        <rdfs:label>Numeric</rdfs:label>
      </owl:Class>
    </rdf:RDF>
    
    1
    

    And if you think that the original Jena Ontology API is more convenient, you can pass the graph back to org.apache.jena.ontology.OntModel interface:

    OntModel jena = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM, reloaded);
            jena.write(System.out, "rdf/xml");