Convert primitive class to defined class Using OWL Api or Jena api

1.1k views Asked by At

I am using OWL API and Jena API.

I need to convert a primitive class to a defined class.

I'm using Protege, I want to do this:

(I'm new in stackoverflow and I can not post pictures, but I put the links.)

I have a class "TestClassInstan" that is a subclass of "TestClass" and has a restriction "hasURL" as shown in Fig [one]:

[one]https://fbcdn-sphotos-c-a.akamaihd.net/hphotos-ak-ash3/1526873_1383572248568109_2144507550_n.jpg https://fbcdn-sphotos-c-a.akamaihd.net/hphotos-ak-ash3/1526873_1383572248568109_2144507550_n.jpg

I want to convert this class and this properties to defined class. And then have this result, a defined class with the propertis equivalent, as shown in Fig [two]:

[two] https://fbcdn-sphotos-g-a.akamaihd.net/hphotos-ak-ash3/1488649_1383580128567321_1363049007_n.jpg enter image description here

Thank you for your help.

2

There are 2 answers

7
Joshua Taylor On BEST ANSWER

The pictures in the question are a bit hard to head, so to be clear, in the first, there are two axioms

TestClassInstan subClassOf (hasURL value "http")
TestClassInstan subClassOf TestClass

You're looking to remove these two axioms and replace them with a single axiom

TestClassInstan equivalentClass (TestClass and (hasURL value "http"))

Ignazio's answer has already shown how you can do this using the OWLAPI. This answer will show how to do it using Jena. The OntClass and OntModel interfaces actually provide just about all the methods that you'll need. The only tricky bit might be constructing the RDFList of classes that make up the intersection, though it's not hard in this example (it's just the list of the original superclasses of TestClassInstan). Here's Java code that accomplishes the conversion. This also include reconstructing the ontology in code, since you didn't provide actual ontology code. It's not necessary for the answer, but it might be helpful, and it makes this code stand on its own.

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.RDFList;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;

public class ConvertSubclassesToEquivalentIntersection {
    final static String NS = "https://stackoverflow.com/a/21001185/1281433/";

    public static void main(String[] args) {
        // Get the original model, and show it (just for good measure, so 
        // that we can compare them).
        final OntModel model = createOriginalModel();
        model.write( System.out, "RDF/XML-ABBREV" );

        // Get the class that we want to convert.
        OntClass testClassInstan = model.createClass( NS+"TestClassInstan" );

        // To create an intersection class, we need an RDFList of the 
        // superclasses, and we can make one of those from the superclass
        // iterator.
        final RDFList superclasses = model.createList( testClassInstan.listSuperClasses( true ));
        testClassInstan.addEquivalentClass( model.createIntersectionClass( null, superclasses ));

        // We still need to remove those superclasses though.
        for ( ExtendedIterator<OntClass> sups = testClassInstan.listSuperClasses( true ); sups.hasNext(); ) {
            testClassInstan.removeSuperClass( sups.next() );
        }

        // Write out the new model.  You can write to a file instead of System.out, 
        // of course, and that's what you'd do to save the model back to a file.
        model.write( System.out, "RDF/XML-ABBREV" );
    }

    /**
     * <p>Recreate the original ontology that had the following axioms (and
     * appropriate class and property declarations):</p>
     * <pre>
     * TestClassInstan subClassOf TestClass
     * TestClassInstan subClassOf (hasURL value "http")
     * </pre>  
     * @return the ontology model
     */
    private static OntModel createOriginalModel() { 
        final OntModel model = ModelFactory.createOntologyModel( OntModelSpec.OWL_DL_MEM );

        final OntClass testClass = model.createClass( NS+"TestClass" );
        final OntClass testClassInstan = model.createClass( NS+"TestClassInstan" );
        testClassInstan.addSuperClass( testClass );

        final OntProperty hasURL = model.createDatatypeProperty( NS+"hasURL" );
        final OntClass hasURLValueHttp = model.createHasValueRestriction( null, hasURL, model.createLiteral( "http" ));
        testClassInstan.addSuperClass( hasURLValueHttp );

        return model;
    }
}

The original ontology is:

<rdf:RDF
    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/a/21001185/1281433/TestClass"/>
  <owl:Class rdf:about="https://stackoverflow.com/a/21001185/1281433/TestClassInstan">
    <rdfs:subClassOf>
      <owl:Restriction>
        <owl:hasValue>http</owl:hasValue>
        <owl:onProperty>
          <owl:DatatypeProperty rdf:about="https://stackoverflow.com/a/21001185/1281433/hasURL"/>
        </owl:onProperty>
      </owl:Restriction>
    </rdfs:subClassOf>
    <rdfs:subClassOf rdf:resource="https://stackoverflow.com/a/21001185/1281433/TestClass"/>
  </owl:Class>
</rdf:RDF>

original ontology

And the converted ontology is:

<rdf:RDF
    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/a/21001185/1281433/TestClass"/>
  <owl:Class rdf:about="https://stackoverflow.com/a/21001185/1281433/TestClassInstan">
    <owl:equivalentClass>
      <owl:Class>
        <owl:intersectionOf rdf:parseType="Collection">
          <owl:Restriction>
            <owl:hasValue>http</owl:hasValue>
            <owl:onProperty>
              <owl:DatatypeProperty rdf:about="https://stackoverflow.com/a/21001185/1281433/hasURL"/>
            </owl:onProperty>
          </owl:Restriction>
          <owl:Class rdf:about="https://stackoverflow.com/a/21001185/1281433/TestClass"/>
        </owl:intersectionOf>
      </owl:Class>
    </owl:equivalentClass>
  </owl:Class>
</rdf:RDF>

after conversion

3
Ignazio On

In the OWL API, there is no need for any special conversion to turn a primitive concept in a defined one. Simply add the axioms that define your class. For example, if A is your class, and you want to define it as equivalent to an existential restriction like some r C, you just create an axiom:

Set<OWLClassExpression> arguments=new HashSet<OWLClassExpression>();
arguments.add(A);
arguments.add(dataFactory.getOWLObjectSomeValuesFrom(r, C);
OWLAxiom axiom = dataFactory.getOWLEquivalentClassesAxiom(arguments);

and add this axiom to the ontology. A will now be a defined concept.

Note: the code above will not modify the ontology file. To save the ontology, use

ontologyManager.saveOntology(ontology)