0

I have the ontology used in the OWL API examples.

private static final String KOALA = "<?xml version=\"1.0\"?>\n"
    + "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\" xmlns:owl=\"http://www.w3.org/2002/07/owl#\" xmlns=\"http://protege.stanford.edu/plugins/owl/owl-library/koala.owl#\" xml:base=\"http://protege.stanford.edu/plugins/owl/owl-library/koala.owl\">\n"
    + "  <owl:Ontology rdf:about=\"\"/>\n"
    + "  <owl:Class rdf:ID=\"Female\"><owl:equivalentClass><owl:Restriction><owl:onProperty><owl:FunctionalProperty rdf:about=\"#hasGender\"/></owl:onProperty><owl:hasValue><Gender rdf:ID=\"female\"/></owl:hasValue></owl:Restriction></owl:equivalentClass></owl:Class>\n"
    + "  <owl:Class rdf:ID=\"Marsupials\"><owl:disjointWith><owl:Class rdf:about=\"#Person\"/></owl:disjointWith><rdfs:subClassOf><owl:Class rdf:about=\"#Animal\"/></rdfs:subClassOf></owl:Class>\n"
    + "  <owl:Class rdf:ID=\"Student\"><owl:equivalentClass><owl:Class><owl:intersectionOf rdf:parseType=\"Collection\"><owl:Class rdf:about=\"#Person\"/><owl:Restriction><owl:onProperty><owl:FunctionalProperty rdf:about=\"#isHardWorking\"/></owl:onProperty><owl:hasValue rdf:datatype=\"http://www.w3.org/2001/XMLSchema#boolean\">true</owl:hasValue></owl:Restriction><owl:Restriction><owl:someValuesFrom><owl:Class rdf:about=\"#University\"/></owl:someValuesFrom><owl:onProperty><owl:ObjectProperty rdf:about=\"#hasHabitat\"/></owl:onProperty></owl:Restriction></owl:intersectionOf></owl:Class></owl:equivalentClass></owl:Class>\n"
    + "  <owl:Class rdf:ID=\"KoalaWithPhD\"><owl:versionInfo>1.2</owl:versionInfo><owl:equivalentClass><owl:Class><owl:intersectionOf rdf:parseType=\"Collection\"><owl:Restriction><owl:hasValue><Degree rdf:ID=\"PhD\"/></owl:hasValue><owl:onProperty><owl:ObjectProperty rdf:about=\"#hasDegree\"/></owl:onProperty></owl:Restriction><owl:Class rdf:about=\"#Koala\"/></owl:intersectionOf></owl:Class></owl:equivalentClass></owl:Class>\n"
    + "  <owl:Class rdf:ID=\"University\"><rdfs:subClassOf><owl:Class rdf:ID=\"Habitat\"/></rdfs:subClassOf></owl:Class>\n"
    + "  <owl:Class rdf:ID=\"Koala\"><rdfs:subClassOf><owl:Restriction><owl:hasValue rdf:datatype=\"http://www.w3.org/2001/XMLSchema#boolean\">false</owl:hasValue><owl:onProperty><owl:FunctionalProperty rdf:about=\"#isHardWorking\"/></owl:onProperty></owl:Restriction></rdfs:subClassOf><rdfs:subClassOf><owl:Restriction><owl:someValuesFrom><owl:Class rdf:about=\"#DryEucalyptForest\"/></owl:someValuesFrom><owl:onProperty><owl:ObjectProperty rdf:about=\"#hasHabitat\"/></owl:onProperty></owl:Restriction></rdfs:subClassOf><rdfs:subClassOf rdf:resource=\"#Marsupials\"/></owl:Class>\n"
    + "  <owl:Class rdf:ID=\"Animal\"><rdfs:seeAlso>Male</rdfs:seeAlso><rdfs:subClassOf><owl:Restriction><owl:onProperty><owl:ObjectProperty rdf:about=\"#hasHabitat\"/></owl:onProperty><owl:minCardinality rdf:datatype=\"http://www.w3.org/2001/XMLSchema#int\">1</owl:minCardinality></owl:Restriction></rdfs:subClassOf><rdfs:subClassOf><owl:Restriction><owl:cardinality rdf:datatype=\"http://www.w3.org/2001/XMLSchema#int\">1</owl:cardinality><owl:onProperty><owl:FunctionalProperty rdf:about=\"#hasGender\"/></owl:onProperty></owl:Restriction></rdfs:subClassOf><owl:versionInfo>1.1</owl:versionInfo></owl:Class>\n"
    + "  <owl:Class rdf:ID=\"Forest\"><rdfs:subClassOf rdf:resource=\"#Habitat\"/></owl:Class>\n"
    + "  <owl:Class rdf:ID=\"Rainforest\"><rdfs:subClassOf rdf:resource=\"#Forest\"/></owl:Class>\n"
    + "  <owl:Class rdf:ID=\"GraduateStudent\"><rdfs:subClassOf><owl:Restriction><owl:onProperty><owl:ObjectProperty rdf:about=\"#hasDegree\"/></owl:onProperty><owl:someValuesFrom><owl:Class><owl:oneOf rdf:parseType=\"Collection\"><Degree rdf:ID=\"BA\"/><Degree rdf:ID=\"BS\"/></owl:oneOf></owl:Class></owl:someValuesFrom></owl:Restriction></rdfs:subClassOf><rdfs:subClassOf rdf:resource=\"#Student\"/></owl:Class>\n"
    + "  <owl:Class rdf:ID=\"Parent\"><owl:equivalentClass><owl:Class><owl:intersectionOf rdf:parseType=\"Collection\"><owl:Class rdf:about=\"#Animal\"/><owl:Restriction><owl:onProperty><owl:ObjectProperty rdf:about=\"#hasChildren\"/></owl:onProperty><owl:minCardinality rdf:datatype=\"http://www.w3.org/2001/XMLSchema#int\">1</owl:minCardinality></owl:Restriction></owl:intersectionOf></owl:Class></owl:equivalentClass><rdfs:subClassOf rdf:resource=\"#Animal\"/></owl:Class>\n"
    + "  <owl:Class rdf:ID=\"DryEucalyptForest\"><rdfs:subClassOf rdf:resource=\"#Forest\"/></owl:Class>\n"
    + "  <owl:Class rdf:ID=\"Quokka\"><rdfs:subClassOf><owl:Restriction><owl:hasValue rdf:datatype=\"http://www.w3.org/2001/XMLSchema#boolean\">true</owl:hasValue><owl:onProperty><owl:FunctionalProperty rdf:about=\"#isHardWorking\"/></owl:onProperty></owl:Restriction></rdfs:subClassOf><rdfs:subClassOf rdf:resource=\"#Marsupials\"/></owl:Class>\n"
    + "  <owl:Class rdf:ID=\"TasmanianDevil\"><rdfs:subClassOf rdf:resource=\"#Marsupials\"/></owl:Class>\n"
    + "  <owl:Class rdf:ID=\"MaleStudentWith3Daughters\"><owl:equivalentClass><owl:Class><owl:intersectionOf rdf:parseType=\"Collection\"><owl:Class rdf:about=\"#Student\"/><owl:Restriction><owl:onProperty><owl:FunctionalProperty rdf:about=\"#hasGender\"/></owl:onProperty><owl:hasValue><Gender rdf:ID=\"male\"/></owl:hasValue></owl:Restriction><owl:Restriction><owl:onProperty><owl:ObjectProperty rdf:about=\"#hasChildren\"/></owl:onProperty><owl:cardinality rdf:datatype=\"http://www.w3.org/2001/XMLSchema#int\">3</owl:cardinality></owl:Restriction><owl:Restriction><owl:allValuesFrom rdf:resource=\"#Female\"/><owl:onProperty><owl:ObjectProperty rdf:about=\"#hasChildren\"/></owl:onProperty></owl:Restriction></owl:intersectionOf></owl:Class></owl:equivalentClass></owl:Class>\n"
    + "  <owl:Class rdf:ID=\"Degree\"/>\n  <owl:Class rdf:ID=\"Gender\"/>\n"
    + "  <owl:Class rdf:ID=\"Male\"><owl:equivalentClass><owl:Restriction><owl:hasValue rdf:resource=\"#male\"/><owl:onProperty><owl:FunctionalProperty rdf:about=\"#hasGender\"/></owl:onProperty></owl:Restriction></owl:equivalentClass></owl:Class>\n"
    + "  <owl:Class rdf:ID=\"Person\"><rdfs:subClassOf rdf:resource=\"#Animal\"/><owl:disjointWith rdf:resource=\"#Marsupials\"/></owl:Class>\n"
    + "  <owl:ObjectProperty rdf:ID=\"hasHabitat\"><rdfs:range rdf:resource=\"#Habitat\"/><rdfs:domain rdf:resource=\"#Animal\"/></owl:ObjectProperty>\n"
    + "  <owl:ObjectProperty rdf:ID=\"hasDegree\"><rdfs:domain rdf:resource=\"#Person\"/><rdfs:range rdf:resource=\"#Degree\"/></owl:ObjectProperty>\n"
    + "  <owl:ObjectProperty rdf:ID=\"hasChildren\"><rdfs:range rdf:resource=\"#Animal\"/><rdfs:domain rdf:resource=\"#Animal\"/></owl:ObjectProperty>\n"
    + "  <owl:FunctionalProperty rdf:ID=\"hasGender\"><rdfs:range rdf:resource=\"#Gender\"/><rdf:type rdf:resource=\"http://www.w3.org/2002/07/owl#ObjectProperty\"/><rdfs:domain rdf:resource=\"#Animal\"/></owl:FunctionalProperty>\n"
    + "  <owl:FunctionalProperty rdf:ID=\"isHardWorking\"><rdfs:range rdf:resource=\"http://www.w3.org/2001/XMLSchema#boolean\"/><rdfs:domain rdf:resource=\"#Person\"/><rdf:type rdf:resource=\"http://www.w3.org/2002/07/owl#DatatypeProperty\"/></owl:FunctionalProperty>\n"
    + "  <Degree rdf:ID=\"MA\"/>\n</rdf:RDF>";

I used this code (https://neo4j.com/blog/using-owl-with-neo4j/) to query the owl ontology:

OWLReasoner reasoner = reasonerFactory.createNonBufferingReasoner(ontology);
    if (!reasoner.isConsistent()) {

        logger.log(Level.INFO, "Ontology is inconsistent");
        //throw your exception of choice here
        throw new Exception("Ontology is inconsistent");
    }

    try{

        // Node thingNode = getOrCreateNodeWithUniqueFactory("owl:Thing");  

        for (OWLClass c :ontology.getClassesInSignature(true)) {
            String classString = c.toString();
            if (classString.contains("#")) {
                classString = classString.substring(
                classString.indexOf("#")+1,classString.lastIndexOf(">"));
            }
            System.out.println("classString: "+classString);

            // Node classNode = getOrCreateNodeWithUniqueFactory(classString); 

            NodeSet<OWLClass> superclasses = reasoner.getSuperClasses(c, true);

            if (superclasses.isEmpty()) {
                //classNode.createRelationshipTo(thingNode,DynamicRelationshipType.withName("isA")); 
                } else {
                for (org.semanticweb.owlapi.reasoner.Node<OWLClass>
                parentOWLNode: superclasses) {
                     OWLClassExpression parent = parentOWLNode.getRepresentativeElement();
                     String parentString = parent.toString();
                     if (parentString.contains("#")) {
                          parentString = parentString.substring(
                          parentString.indexOf("#")+1,
                          parentString.lastIndexOf(">"));
                     }

                     System.out.println("parentString: "+parentString);
                 //    Node parentNode = getOrCreateNodeWithUniqueFactory(parentString);   
                 //    classNode.createRelationshipTo(parentNode, DynamicRelationshipType.withName("isA"));  
                }
            }

            for (org.semanticweb.owlapi.reasoner.Node<OWLNamedIndividual> in
                    : reasoner.getInstances(c, true)) { 
                    OWLNamedIndividual i = in.getRepresentativeElement();
                    String indString = i.toString();
                    if (indString.contains("#")) {
                         indString = indString.substring(
                              indString.indexOf("#")+1,indString.lastIndexOf(">"));
                    }

                    System.out.println("indString: "+indString);

                //    Node individualNode = getOrCreateNodeWithUniqueFactory(indString);  
                //    individualNode.createRelationshipTo(classNode, DynamicRelationshipType.withName("isA"));  


                    for (OWLObjectPropertyExpression objectProperty:
                        ontology.getObjectPropertiesInSignature()) { System.out.println("objectProperty: "+objectProperty); 
                             for
                             (org.semanticweb.owlapi.reasoner.Node<OWLNamedIndividual>
                             object: reasoner.getObjectPropertyValues(i,
                             objectProperty)) { 
                                  String reltype = objectProperty.toString();
                                  reltype = reltype.substring(reltype.indexOf("#")+1,
                                  reltype.lastIndexOf(">"));
                                  String s =
                                  object.getRepresentativeElement().toString();
                                  s = s.substring(s.indexOf("#")+1,
                                  s.lastIndexOf(">"));

                                  System.out.println("reltype: "+reltype+" s: "+s);
                            //      Node objectNode = getOrCreateNodeWithUniqueFactory(s);
                            //      individualNode.createRelationshipTo(objectNode, DynamicRelationshipType.withName(reltype));
                             }
                       }
                       for (OWLDataPropertyExpression dataProperty:
                       ontology.getDataPropertiesInSignature()) { System.out.println("dataProperty: "+dataProperty.asOWLDataProperty()); 
                             for (OWLLiteral object: reasoner.getDataPropertyValues(
                             i, dataProperty.asOWLDataProperty())) {
                                  String reltype =
                                  dataProperty.asOWLDataProperty().toString();
                                  reltype = reltype.substring(reltype.indexOf("#")+1, 
                                  reltype.lastIndexOf(">"));
                                  String s = object.toString();

                                  System.out.println("reltype: "+reltype+" s: "+s);

                             //     individualNode.setProperty(reltype, s);
                             }
                        }

            }
        }

but I observed that it doesn't return object property values for the specified individual and object property expression.

reasoner.getObjectPropertyValues(i, objectProperty)

returns no items. Why?

I tried even with others Reasoner (HermiT, Pellet) as I read in other post, but the outcome does not change. How can I solve it?

vincentdj
  • 265
  • 2
  • 5
  • 16
  • There is no objectProperties asserted in the ontology you are using; So the reasoner find nothing, because there is nothing to find. Your code look good (a bit complicated, you will find short-cut latter). – Galigator Oct 06 '17 at 13:49
  • @Galigator With system.out before getObjectPropertyValues(i, objectProperty), I got this objectProperties: hasGender, hasHabitat, hasDegree, hasChildren. How to extract these information in order to convert them in GraphDB? – vincentdj Oct 06 '17 at 14:03
  • This is a completly different question. – Galigator Oct 06 '17 at 14:10
  • @Galigator My problem is how to extract information like hasGender, hasHabitat, hasDegree, hasChildren from owl ontology. – vincentdj Oct 06 '17 at 14:23
  • So update your problem here : https://stackoverflow.com/questions/46581663/mapping-from-owl-ontology-to-orientdb-graph-database – Galigator Oct 06 '17 at 14:42
  • @vincentdj The Koala ontology doesn't contain individuals that use any of the object properties. – UninformedUser Oct 06 '17 at 14:50
  • Possibly not the source of your issue, but you're asking for direct instances only - the true in `reasoner.getInstances(c, true)` means that indirect instances will not be found. If the individuals are inferred to be instances of a class but through an anonymous restriction, this will restrict your results. – Ignazio Oct 06 '17 at 23:49

2 Answers2

2

There is no objectProperties asserted in the ontology you are using; So the reasoner find nothing, because there is nothing to find.

Add the following code after loading your ontology, so you can test your code.

final OWLDataFactory factory = manager.getOWLDataFactory();
ontology.add(factory.getOWLObjectPropertyAssertionAxiom(factory.getOWLObjectProperty("#HelloWorldProperty"), factory.getOWLNamedIndividual("#FirstIndividual"), factory.getOWLNamedIndividual("#SecondIndividual")));
reasoner.flush();

Your code look good but a bit complicated. You could get shorter code with 'getFlattened()'

for (final OWLNamedIndividual i : reasoner.getInstances(c, true).getFlattened())
Stanislav Kralin
  • 11,070
  • 4
  • 35
  • 58
Galigator
  • 8,957
  • 2
  • 25
  • 39
  • 2
    @vincentdj The ontology doesn't contain individuals that "use" any of the object properties. – UninformedUser Oct 06 '17 at 14:51
  • @AKSW What are "hasDegree, hasGender, hasHabitat, hasChildren" in the KOALA Ontology? – vincentdj Oct 06 '17 at 14:54
  • 1
    @vincentdj They are "objectProperties declaration", there is also "assertion" but about the 'range' / 'domain' of objectProperties. – Galigator Oct 06 '17 at 14:58
  • @Galigator So, using only the code that I posted in order to map owl into graphdb, I will lose some information like these "objectProperties declaration", "assertion". It's right? – vincentdj Oct 06 '17 at 15:05
  • 2
    @vincentdj Short answer, the properties exist in the ontology schema, but are not used by any instance data. That's it. That means, there are no edges in the graph that would be useful besides the ones that give information about some features (e.g. domain/range/functionality, etc.) of the properties – UninformedUser Oct 06 '17 at 15:34
  • 2
    You could add a "dummy node" for each entity in the ontology. – UninformedUser Oct 06 '17 at 15:35
  • If I would to add an edge with objectProperty declaration as relationshipType between the range/domain nodes, how can I change the code that I posted? – vincentdj Oct 09 '17 at 14:12
0

I could not detect the objectProperties declaration and dataProperties directly from a specific instance, in this block code:

for (org.semanticweb.owlapi.reasoner.Node<OWLNamedIndividual> in
                : reasoner.getInstances(c, true)) { 
                OWLNamedIndividual i = in.getRepresentativeElement();
                String indString = i.toString();
                if (indString.contains("#")) {
                     indString = indString.substring(
                          indString.indexOf("#")+1,indString.lastIndexOf(">"));
                }

                ......

That is, I couldn't find a way to extract these information directly from i. So, I identified all them from ontology in this way:

        System.out.println("\n-> ObjectProperties: ");
        for (OWLObjectPropertyExpression objectProperty:
            ontology.getObjectPropertiesInSignature()) { 
            String object = objectProperty.toString();
            if (object.contains("#")) {
                object = object.substring(
                        object.indexOf("#")+1,object.lastIndexOf(">"));
            }
            String domain = reasoner.getObjectPropertyDomains(objectProperty, true).toString();
            if (domain.contains("#")) {
                domain = domain.substring(
                        domain.indexOf("#")+1,domain.lastIndexOf(">"));
            }
            String range =  reasoner.getObjectPropertyRanges(objectProperty, true).toString();
            if (range.contains("#")) {
                range = range.substring(
                        range.indexOf("#")+1,range.lastIndexOf(">"));
            }
            System.out.println(domain+" "+object+" "+range);
        }

        System.out.println("\n-> DataProperties: ");
        for (OWLDataProperty dataProperty:
            ontology.getDataPropertiesInSignature()) { 
            String data = dataProperty.toString();
            if (data.contains("#")) {
                data = data.substring(
                        data.indexOf("#")+1,data.lastIndexOf(">"));
            }
            String domain = reasoner.getDataPropertyDomains(dataProperty, true).toString();
            if (domain.contains("#")) {
                domain = domain.substring(
                        domain.indexOf("#")+1,domain.lastIndexOf(">"));
            }
            System.out.println(domain+" "+data);
        }

I thought to add an edge like domain->(objectProperty)->range for all objectProperties found, in order to not lose this information.

vincentdj
  • 265
  • 2
  • 5
  • 16