2

I have stumbled upon another problem...

I want to achieve something similar to this: enter image description here

I wanted to do so using RDFList, adding the necessary properties in to the list and then call method createUnionClass (or createIntersectionClass) and combine it together. Then, the result of this method would be added to particular ontClass with addSuperClass().

Is this wrong? I have started with something really simple, like:

RDFList rdfList = ontModel.createList();
rdfList.addProperty(ExampleResource1);
rdfList.addProperty(ExampleResource2); 
UnionClass uc = ontModel.createUnionClass(null, rdfList);
ExampleClass.addSuperClass(uc);

But the result was not the subClassOf the union of both stated before, but only subClassOf nil.

Any help would be appreciated.

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
Hawk
  • 392
  • 4
  • 24
  • 1
    It's very hard to read the text in your image. Can you post it as text please? `createUnionClass` needs, unsurprisingly, and as the documentation says, a list of resources denoting the classes of the union. If Protégé accepted the input you've shown, then evidently you've defined classes ExampleResource1 and ExampleResource2 (but resource suggests individual in an OWL context, so this is sort of a poor name choice). `uc` would be the class `ExResource1 or ExResouce2`, and you'd add the axiom `ExampleClass subClassOf (ExResource1 or ExResource2)`. What was your actual output? – Joshua Taylor Dec 13 '13 at 13:33
  • "I have stumbled upon another problem...", this question seems like the prosecution of a previous one.. – dendini Dec 13 '13 at 15:44

1 Answers1

2

Creating this in Jena is a little bit tricky because support for the qualified cardinality restrictions is an OWL2 feature, and Jena has limited support for OWL2:

Jena Ontology API

Note that, at present, the Jena ontology API has only limited support for OWL2's qualified cardinality restrictions (i.e. cardinalityQ, minCardinalityQ and maxCardinalityQ). Qualified cardinality restrictions are encapsulated in the interfaces CardinalityQRestriction, MinCardinalityQRestriction and CardinalityQRestriction. OntModel also provides methods for creating and accessing qualified cardinality restrictions. Since they are not part of the OWL 1.0 language definition, qualified cardinality restrictions are not supported in OWL ontologies. Qualified cardinality restrictions were added to the OWL 2 update. OWL2 support in Jena will be added in due course.

You might also see response that I posted to the Jena mailing list about a similar question, Re: Owl maxCardinality restriction.

You can come pretty close with the following Java code, though. 3. is the code that we'd like to be able to write, but we end up having to use 3a. instead. You could go and start digging around in RDF serialization and thereby get yourself a genuine qualified restriction. I've shown how you can do that in a related question: How to add qualified cardinality in JENA.

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;
import com.hp.hpl.jena.rdf.model.RDFNode;

public class UnionClassExample {
    public static void main(String[] args) throws FileNotFoundException, IOException {
        String NS = "https://stackoverflow.com/q/20561994/1281433/";
        OntModel model = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM );
        model.setNsPrefix( "so", NS );

        OntClass a = model.createClass( NS+"A" );
        OntClass b = model.createClass( NS+"B" );
        OntClass c = model.createClass( NS+"C" );

        OntProperty p = model.createObjectProperty( NS+"p" );
        OntProperty q = model.createObjectProperty( NS+"q" );

        // 1. B or C
        OntClass b_or_c = model.createUnionClass( null, model.createList( new RDFNode[] { b, c } ));

        // 2. p only (B or C)
        OntClass p_only_b_or_c = model.createAllValuesFromRestriction( null, p, b_or_c );

        // 3. q exactly 1 C
        // OntClass q_exactly_1_C = model.createCardinalityQRestriction( null, q, 1, c );

        // 3a. q exactly 1
        OntClass q_exactly_1 = model.createCardinalityRestriction( null, q, 1 );

        // (2) and (3a)
        OntClass _2_and_3a = model.createIntersectionClass( null, model.createList( new RDFNode[] { p_only_b_or_c, q_exactly_1 } ));

        // a subClassOf ((p only (B or C)) and (q exactly 1))
        a.addSuperClass( _2_and_3a );

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

Output:

<rdf:RDF
    xmlns:so="https://stackoverflow.com/q/20561994/1281433/"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
  <owl:Class rdf:about="https://stackoverflow.com/q/20561994/1281433/A">
    <rdfs:subClassOf>
      <owl:Class>
        <owl:intersectionOf rdf:parseType="Collection">
          <owl:Restriction>
            <owl:allValuesFrom>
              <owl:Class>
                <owl:unionOf rdf:parseType="Collection">
                  <owl:Class rdf:about="https://stackoverflow.com/q/20561994/1281433/B"/>
                  <owl:Class rdf:about="https://stackoverflow.com/q/20561994/1281433/C"/>
                </owl:unionOf>
              </owl:Class>
            </owl:allValuesFrom>
            <owl:onProperty>
              <owl:ObjectProperty rdf:about="https://stackoverflow.com/q/20561994/1281433/p"/>
            </owl:onProperty>
          </owl:Restriction>
          <owl:Restriction>
            <owl:cardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#int"
            >1</owl:cardinality>
            <owl:onProperty>
              <owl:ObjectProperty rdf:about="https://stackoverflow.com/q/20561994/1281433/q"/>
            </owl:onProperty>
          </owl:Restriction>
        </owl:intersectionOf>
      </owl:Class>
    </rdfs:subClassOf>
  </owl:Class>
</rdf:RDF>

Loaded into Protégé:

enter image description here

Community
  • 1
  • 1
Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
  • Thank you very much, it pretty much answers everything I needed to know... My mistake was in initializing the RDFList. Better documentation and some code examples of it would help a lot. – Hawk Dec 16 '13 at 12:39
  • @Hawk I think your RDFList initialization was fine; you weren't adding elements to it correctly though. You should have been using [RDFList#add(RDFNode)](http://jena.apache.org/documentation/javadoc/jena/com/hp/hpl/jena/rdf/model/RDFList.html#add(com.hp.hpl.jena.rdf.model.RDFNode)) to add elements (although if you have them in advance, the array syntax that I used can be pretty convenient, too). – Joshua Taylor Dec 16 '13 at 13:07
  • @Hawk Although, since you start with an empty RDFList, you well might want to use [RDFList#cons](http://jena.apache.org/documentation/javadoc/jena/com/hp/hpl/jena/rdf/model/RDFList.html#cons(com.hp.hpl.jena.rdf.model.RDFNode)) as `RDFList list = model.creatList(); list = list.cons(i1); list = list.cons(i2); ...`. – Joshua Taylor Dec 16 '13 at 13:09