get OWL restrictions on classes using Jena

邮差的信 提交于 2019-11-29 20:43:06

问题


Using the pizza ontology, I want to be able to look up all the toppings for American pizza. If I open the ontology in Protégé, I can see that American pizza has the following restrictions:

hasTopping some MozerellaTopping
hasTopping some TomatoTopping

How can I get the same information programatically through Jena?


回答1:


Here's my solution. I've just printed out the strings you ask for, but hopefully you can see from this how to use the Jena OntAPI to traverse an ontology graph and pick out the things you're interested in.

package examples;
import java.util.Iterator;
import com.hp.hpl.jena.ontology.*;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Resource;

public class PizzaExample
{
    /***********************************/
    /* Constants                       */
    /***********************************/
    public static String BASE = "http://www.co-ode.org/ontologies/pizza/pizza.owl";
    public static String NS = BASE + "#";

    /***********************************/
    /* External signature methods      */
    /***********************************/

    public static void main( String[] args ) {
        new PizzaExample().run();
    }

    public void run() {
        OntModel m = getPizzaOntology();
        OntClass american = m.getOntClass( NS + "American" );

        for (Iterator<OntClass> supers = american.listSuperClasses(); supers.hasNext(); ) {
            displayType( supers.next() );
        }
    }

    /***********************************/
    /* Internal implementation methods */
    /***********************************/

    protected OntModel getPizzaOntology() {
        OntModel m = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM );
        m.read( BASE );
        return m;
    }

    protected void displayType( OntClass sup ) {
        if (sup.isRestriction()) {
            displayRestriction( sup.asRestriction() );
        }
    }

    protected void displayRestriction( Restriction sup ) {
        if (sup.isAllValuesFromRestriction()) {
            displayRestriction( "all", sup.getOnProperty(), sup.asAllValuesFromRestriction().getAllValuesFrom() );
        }
        else if (sup.isSomeValuesFromRestriction()) {
            displayRestriction( "some", sup.getOnProperty(), sup.asSomeValuesFromRestriction().getSomeValuesFrom() );
        }
    }

    protected void displayRestriction( String qualifier, OntProperty onP, Resource constraint ) {
        String out = String.format( "%s %s %s",
                                    qualifier, renderURI( onP ), renderConstraint( constraint ) );
        System.out.println( "american pizza: " + out );
    }

    protected Object renderConstraint( Resource constraint ) {
        if (constraint.canAs( UnionClass.class )) {
            UnionClass uc = constraint.as( UnionClass.class );
            // this would be so much easier in ruby ...
            String r = "union{ ";
            for (Iterator<? extends OntClass> i = uc.listOperands(); i.hasNext(); ) {
                r = r + " " + renderURI( i.next() );
            }
            return r + "}";
        }
        else {
            return renderURI( constraint );
        }
    }

    protected Object renderURI( Resource onP ) {
        String qName = onP.getModel().qnameFor( onP.getURI() );
        return qName == null ? onP.getLocalName() : qName;
    }
}

Which produces the following output:

american pizza: some pizza:hasTopping pizza:MozzarellaTopping
american pizza: some pizza:hasTopping pizza:PeperoniSausageTopping
american pizza: some pizza:hasTopping pizza:TomatoTopping
american pizza: all pizza:hasTopping union{  pizza:MozzarellaTopping pizza:TomatoTopping pizza:PeperoniSausageTopping}



回答2:


Now (with Apache Jena 3.x.x) there is (still, as for Jena2) one possible problem with org.apache.jena.ontology.OntModel and pizza.owl in that Jena OntAPI supports only OWL1, while pizza is OWL2 ontology.

Although, for the example above it doesn't matter ('Existential Quantification' restrictions looks identically both for OWL1 and OWL2, and Jena API can process it), in general case you can't use OntModel for processing ontology just as easily. As an option there is an alternative that called ru.avicomp.ontapi.jena.model.OntGraphModel from ONT-API. It is based on the same principles as a Jena OntModel, but it is strongly for OWL2 and it is not InfModel (at time of writing). Maybe it would be helpful for someone.

An example of usage (getting only object-some-values-from restrictions for a class):

    String web = "https://raw.githubusercontent.com/avicomp/ont-api/master/src/test/resources/ontapi/pizza.ttl";
    // create an OWL2 RDF-view (Jena Model):
    OntGraphModel m = ru.avicomp.ontapi.jena.OntModelFactory.createModel();
    // load pizza ontology from web
    m.read(web, "ttl");
    // find class and property
    OntClass clazz = m.getOntClass(m.expandPrefix(":American"));
    OntNOP prop = m.getObjectProperty(m.expandPrefix(":hasTopping"));
    // list and print all some values from restrictions with desired property
    clazz.superClasses()
            .filter(c -> c.canAs(OntCE.ObjectSomeValuesFrom.class))
            .map(c -> c.as(OntCE.ObjectSomeValuesFrom.class))
            .filter(c -> prop.equals(c.getProperty()))
            .map(x -> x.getValue())
            .forEach(System.out::println);

The output:

http://www.co-ode.org/ontologies/pizza/pizza.owl#PeperoniSausageTopping(OntClass)
http://www.co-ode.org/ontologies/pizza/pizza.owl#TomatoTopping(OntClass)
http://www.co-ode.org/ontologies/pizza/pizza.owl#MozzarellaTopping(OntClass)


来源:https://stackoverflow.com/questions/7779927/get-owl-restrictions-on-classes-using-jena

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!