0
votes

I've and OWL file and I can explore it and navigate through classes and properties but I can't retrieve correct range of ObjectProperty. This is part of my OWL file:

<owl:ObjectProperty rdf:about="&aat;aat2209_located_in">
        <rdfs:label xml:lang="en">located in</rdfs:label>
        <rdfs:label xml:lang="it">si trova in</rdfs:label>
        <rdfs:comment xml:lang="en">The property defines a relationship between places or places and things</rdfs:comment>
        <rdfs:comment xml:lang="it">La proprietà definisce la relazione tra luoghi o tra luoghi e cose</rdfs:comment>
        <rdfs:domain>
            <owl:Class>
                <owl:unionOf rdf:parseType="Collection">
                    <rdf:Description rdf:about="&dbpedia-owl;Artwork"/>
                    <rdf:Description rdf:about="&dbpedia-owl;Cave"/>
                </owl:unionOf>
            </owl:Class>
        </rdfs:domain>
        <rdfs:range>
            <owl:Class>
                <owl:unionOf rdf:parseType="Collection">
                    <rdf:Description rdf:about="&lodmt;ArchaeologicalSite"/>
                    <rdf:Description rdf:about="&dbpedia-owl;Building"/>
                </owl:unionOf>
            </owl:Class>
        </rdfs:range>
    </owl:ObjectProperty>

And this is part of my code to explore OWL file

...    
OntModel inf = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM_RULE_INF);
            InputStream in =getClass().getResourceAsStream("/"+DATA_IRI);
            inf.read(in, "");
            OntClass obj = inf.getOntClass(uri);
            ExtendedIterator<OntProperty> propIter = obj.listDeclaredProperties(false);
            if(propIter.hasNext()){
                while (propIter.hasNext()) {
                    Set<PropertyModel> properties = new HashSet<PropertyModel>();
                    final OntProperty ontProperty = (OntProperty) propIter.next();
                    ExtendedIterator<? extends OntProperty> eqProp = ontProperty.listEquivalentProperties();
                    if(eqProp.hasNext()){
                        while (eqProp.hasNext()) {
                            OntProperty property = (OntProperty) eqProp.next();
                            PropertyModel propModel = new PropertyModel();
                            propModel.setLabel(property.getLocalName());
                            propModel.setUri(property.getURI());
                            propModel.setRange(property.getRange().getLocalName());
                            properties.add(propModel);
                        }
                    }
    ...

Everytime I call property.getRange() I've this result: http://www.w3.org/2002/07/owl#Thing.

Anyone help me?

1
Properties can have multiple ranges, and owl:Thing is certainly going to be one of them for every object property. It's not an incorrect answer, then, it's just not as specific as you'd like. You can probably get the more specific answer though..Joshua Taylor
Your OWL file isn't complete. You don't need to give us all your data, but you need to give us something complete enough that we can load it in Jena. You don't have an enclosing rdf:RDF element, namespace declarations, entity declarations. It's also not minimal; we don't need the rdfs:label, etc., just the rdfs:range.Joshua Taylor
This is a part of my OWL file!Claudio Pomo
I didn't say that it's not part of your OWL file. I said that it's not complete (it's not enough for us to load into Jena), and it's not minimal (it has more information that what we need for the problem). See How to create a Minimal, Complete, and Verifiable example.Joshua Taylor

1 Answers

1
votes

It's ever so much easier if you provide complete but minimal data to work with. In this case, I've modified your data to be the following, which is complete in that it's a loadable RDF document, and minimal in that it only contains the object property declaration and the range axiom.

<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:ObjectProperty rdf:about="http://stackoverflow.com/q/24250198/1281433/aat2209_located_in">
        <rdfs:range>
            <owl:Class>
                <owl:unionOf rdf:parseType="Collection">
                    <rdf:Description rdf:about="http://stackoverflow.com/q/24250198/1281433/ArchaeologicalSite"/>
                    <rdf:Description rdf:about="http://stackoverflow.com/q/24250198/1281433/Building"/>
                </owl:unionOf>
            </owl:Class>
        </rdfs:range>
    </owl:ObjectProperty>
</rdf:RDF>

The following code loads it and shows the range(s) of the property:

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.ontology.OntResource;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;

public class RangeExample {
    public static void main(String[] args) {
        OntModel model = ModelFactory.createOntologyModel( OntModelSpec.OWL_DL_RULE_MEM_INF );
        model.read( "..../data.owl" );
        OntProperty locatedIn = model.getOntProperty( "http://stackoverflow.com/q/24250198/1281433/aat2209_located_in" );
        ExtendedIterator<? extends OntResource> ranges = locatedIn.listRange();
        while ( ranges.hasNext() ) { 
            System.out.println( ranges.next() );
        }
    }
}

The output for me is

http://www.w3.org/2002/07/owl#Thing
-3e020093:146a7247e66:-7ffb
http://www.w3.org/2000/01/rdf-schema#Resource

owl:Thing and rdfs:Resource are there because anytime you have x located_in y, you can be sure that y is an owl:Thing and an rdfs:Resource, since located_in is an object property. The other one, -3e020093:146a7247e66:-7ffb, is the identitifier of the RDF blank node that is the OWL union class expression.

Why aren't other classes returned?

Based on the following comment, it sounds like a bit more discussion is needed.

I obtain same result, but I would obtain ArchaeologicalSite and Building as result.

You asked for the range(s) of a particular object property that you declared. In OWL, a range of a property p is any class D such that "if p(x,y), then D(y)". That is, in RDF terms, if you a property p's has D as a range, then whenever there is a triple x p y, then you can also infer the triple y rdf:type D. This is the rule:

x p y     p rdfs:range D
-----------------------
   y rdf:type D

The range that you're asking about is a union class. An instance of the rule for your class would be like:

x located_in y     located_in rdfs:range (ArchaeologicalSite OR Building)
-------------------------------------------------------------------------
     y rdf:type (ArchaeologicalSite OR Building)

It would not make sense to infer that

y rdf:type ArchaeologicalSite

or that

y rdf:type Building

because that's more information than you have in x located_in y. For analogy, consider this example:

  1. You can have soup or salad for your appetizer. (The range of hasAppetizer is "soup or salad".)
  2. You had some unknown x for your appetizer.

From those, I can infer that x is either soup or salad, but I can't infer which particular one. Thus "soup or salad" is a range of hasAppetizer, but neither soup nor salad alone is.