Skip to content

Examples

sszuev edited this page Apr 3, 2024 · 8 revisions

Table of contents:

All examples (with except of two lasts) are available in this wiki itself (just clone it).

1) Using both OWL-API (structural) and Jena (RDF graph model) interfaces together.

Basic OWL-API and Jena Model API functionality in one place. Note that the manager instance is actually com.github.owlcs.ontapi.OntologyManager, and the ontology instance is com.github.owlcs.ontapi.Ontology. The actual type of model returned by Ontology#asGraphModel() is com.github.owlcs.ontapi.jena.model.OntModel (don't confuse with org.apache.jena.ontology.OntModel).

// Getting manager:
OWLOntologyManager manager = OntManagers.createManager();

// ====================================
// Interacting using OWL-API interface:
// ====================================
// Related data-factory:
OWLDataFactory factory = manager.getOWLDataFactory();
// Creating an ontology:
OWLOntology ontology = manager.createOntology(IRI.create("first"));
// Adding sub-class-of axiom:
ontology.addAxiom(factory.getOWLSubClassOfAxiom(factory.getOWLClass("first-class"), factory.getOWLThing()));

// =====================================
// Interacting using jena-API interface:
// =====================================
Model model = ((Ontology)ontology).asGraphModel();
model.createResource("second-class").addProperty(RDFS.subClassOf, model.createResource("first-class"));

// =================
// Printing results:
// =================
System.out.println("Ontology as Turtle:");
ontology.saveOntology(System.out);
System.out.println("\nList of owl-axioms:");
ontology.axioms().forEach(System.out::println);
System.out.println("\nAll jena-statements:");
model.listStatements().forEachRemaining(System.out::println);

2) ONT-API RDF Model interface:

The com.github.owlcs.ontapi.OntologyManager contains methods to create and load org.apache.jena.rdf.model.Model directly, that is a shortening of the standard way through com.github.owlcs.ontapi.Ontology interface:

// getting manager:
OntologyManager manager = OntManagers.createManager();

// creating a graph ontology:
OntModel model = manager.createGraphModel("http://example.com");
// add version iri:
model.getID().setVersionIRI("http://example.com/1.0");
// add some annotations to the ontology header
model.getID().addComment("this is an example ontology", "fr");
// add some ns-prefixes (including standard):
model.setNsPrefixes(OntModelFactory.STANDARD).setNsPrefix("test", "http://example.com#");

// adding several individuals (both named and anonymous):
OntIndividual named = model.getOWLThing().createIndividual("http://example.com#individual");
OntIndividual anonymous = model.getOWLNothing().createIndividual();

// add disjoint individuals axiom assertion:
model.createDifferentIndividuals(named, anonymous);

// add annotation to anonymous individual declaration:
anonymous.addComment("this is an anonymous individual");

// print result as turtle to stdout:
model.write(System.out, OntFormat.TURTLE.getID());

3) ONT-API RDF model interacting with OWL 2 DL constructions (OWL-Object-Max-Cardinality Restriction in the example below).

The com.github.owlcs.ontapi.jena.model.OntModel interface supports all OWL2 language features (as opposed to the org.apache.jena.ontology.OntModel, which is only for OWL1). Another way to get an instance of this model is com.github.owlcs.ontapi.jena.OntModelFactory factory. Note that here is no any OWLOntology companion, which would wrap the same RDF data, unlike the previous example.

OntModel model = OntModelFactory.createModel().setNsPrefixes(OntModelFactory.STANDARD);
OntObjectProperty property = model.createObjectProperty("http://test#hasUnit");
OntClass clazz = model.createOntClass("http://test#Numeric");
clazz.addSuperClass(model.createOntClass("http://test#Characteristic"))
        .addSuperClass(model.createObjectMaxCardinality(property, 1,
                model.createOntClass("http://test#Scale")));
model.write(System.out, "ttl");

4) Iteration over all OWLAxioms that read from any RDF (Jena) Model (org.apache.jena.rdf.model.Model).

// Create a standard Jena Model:
Model m = ModelFactory.createDefaultModel();
// Load RDF data:
try (InputStream in = Example4.class.getResourceAsStream("/pizza.ttl")) {
    RDFDataMgr.read(m, in, Lang.TURTLE);
}
// list all OWLAxioms from Jena Model:
AxiomType.AXIOM_TYPES.stream()
        .map(AxiomParserProvider::get)
        .forEach(t -> t.axioms(OntModelFactory.createModel(m.getGraph()))
                .forEach(System.out::println));

5) Load ontology in functional syntax to Jena.

Since ONT-API is OWL-API, all standard facilities and tools of OWL-API are also supported, if they are included in the distribution (more about this see on format page).

String functionalSyntaxString = "Ontology(<http://test.org/simple>" +
        "SubClassOf(<http://test.org/simple#class2> <http://test.org/simple#class1>)" +
        "ClassAssertion(<http://test.org/simple#class1> <http://test.org/simple#individual>))";
InputStream in = new ByteArrayInputStream(functionalSyntaxString.getBytes(StandardCharsets.UTF_8));
OntologyManager manager = OntManagers.createManager();
Ontology ontology = manager.loadOntologyFromOntologyDocument(in);
Model model = ontology.asGraphModel();
model.write(System.out, "ttl");

6) Coping ontology from OWL-API-impl to ONT-API:

Both implementations (the default OWL-API-impl and ONT-API), obviously, refer to OWL-API-api in a OOP is-a relation, Since ONT-API IS OWL-API, it can be used in all cases where OWL-API is used. So please think twice if you are planning to use this functionality. Although this option exists, it does not mean that it is always smart to mix two different implementations. The good reason for such a mixing would be performance. If you found a lack of performance in ONT-API, please contact with me.

String uri = "http://ex.com";
// Get native OWL-API-impl manager through OWL-API-apibinding.
// Note that in ONT-API there is an alternative way: OntManagers.createOWL()
OWLOntologyManager owlManager = OWLManager.createOWLOntologyManager();
// Get ONT-API manager:
OntologyManager ontManager = OntManagers.createManager();

// Create pure OWL-ontology (no graph inside):
OWLOntology owlOntology = owlManager.createOntology(IRI.create(uri));
// Add single axiom (class-assertion):
OWLDataFactory df = ontManager.getOWLDataFactory();
OWLAxiom classAssertion = df.getOWLClassAssertionAxiom(
        df.getOWLClass(IRI.create(uri + "#", "clazz")),
        df.getOWLNamedIndividual(IRI.create(uri + "#", "individual")));
owlOntology.add(classAssertion);
// Copy from OWL- to ONT-Manager.
// This will produce an OWL-ontology (Ontology) with a jena Graph inside:
Ontology ontOntology = ontManager.copyOntology(owlOntology, OntologyCopy.DEEP);
// Print all triples from the inner graph:
ontOntology.asGraphModel().getGraph().find(Triple.ANY).forEachRemaining(System.out::println);
// Print all axioms:
ontOntology.axioms().forEach(System.out::println);

7) Easy way to pass Jena OntModel to ONT-API:

Any Jena Model (including most popular org.apache.jena.ontology.OntModel) can be wrapped as an instance of OWLOntology. For this there is a functionality OWLOntologyManager#addOntology(Graph). This avoids widely used, but time- and memory-consuming ways, like iteration with write or PipedOutputStream/PipedInputStream-based ways.

// Jena ONT-Model API
OntModelSpec spec = OntModelSpec.OWL_DL_MEM;
OntModel o1 = ModelFactory.createOntologyModel(spec);
OntModel o2 = ModelFactory.createOntologyModel(spec);
o1.createOntology("http://test.com/1/v1")
        .addImport(o2.createOntology("http://test.com/2"));
o1.addSubModel(o2);
o1.createOntology("http://test.com/1/v2");
o1.createClass("http://test.com#clazz1");
o2.createClass("http://test.com#clazz2");

// Pass to ONT-API
OntologyManager manager = OntManagers.createManager();
Ontology ontology = manager.addOntology(o1.getGraph());

// expected: two class-declarations:
ontology.axioms(Imports.INCLUDED).forEach(System.out::println);
// expected: <http://test.com/1/v1>
System.out.println(ontology.getOntologyID());
// expected: 2
System.out.println(manager.ontologies().count());

8) OWL-API + SPARQL:

Since ONT-API is a RDF-centric OWL-API implementation, Jena-ARQ is working:

String uri = "http://ex.com/test";
String ns = uri + "#";

OntologyManager m = OntManagers.createManager();
OWLDataFactory df = m.getOWLDataFactory();

// Interacting with OWL-API interfaces: assembly the ontology:
Ontology o = m.createOntology(IRI.create(uri));
OWLAnnotationProperty a1 = df.getOWLAnnotationProperty(IRI.create(ns, "prop1"));
OWLAnnotationProperty a2 = df.getOWLAnnotationProperty(IRI.create(ns, "prop2"));
OWLClass c1 = df.getOWLClass(IRI.create(ns, "class1"));
OWLNamedIndividual i1 = df.getOWLNamedIndividual(IRI.create(ns, "indi1"));
o.add(df.getOWLDeclarationAxiom(a1));
o.add(df.getOWLDeclarationAxiom(a2));
o.add(df.getOWLDeclarationAxiom(c1));
o.add(df.getOWLAnnotationPropertyDomainAxiom(a1, c1.getIRI()));
o.add(df.getOWLClassAssertionAxiom(c1, i1));
o.add(df.getOWLSubAnnotationPropertyOfAxiom(a2, a1));
o.add(df.getOWLAnnotationAssertionAxiom(a1, df.getOWLAnonymousIndividual(), i1.getIRI()));

// Print ontology before updating:
o.axioms().forEach(System.out::println);
o.saveOntology(System.out);

// SPARQL UPDATE: replace owl:AnnotationProperty -> owl:ObjectProperty
UpdateAction.parseExecute("PREFIX rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \n" +
                "PREFIX owl:     <http://www.w3.org/2002/07/owl#>\n" +
                "DELETE { ?x rdf:type owl:AnnotationProperty } \n" +
                "INSERT { ?x rdf:type owl:ObjectProperty } \n" +
                "WHERE { ?x rdf:type owl:AnnotationProperty }",
        o.asGraphModel());

// Print result:
o.axioms().forEach(System.out::println);
o.saveOntology(System.out);

// SPARQL SELECT: just print all declarations:
try (QueryExecution qexec = QueryExecutionFactory.create(QueryFactory
        .create("PREFIX rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \n" +
                "SELECT ?s ?o WHERE { ?s a ?o }"), o.asGraphModel())) {
    ResultSet res = qexec.execSelect();
    while (res.hasNext()) {
        System.out.println(res.next());
    }
}

9) InfModel (Jena Inference)

Since version 3.5.0, ONT-API uses jena-owl2, which supports Jena's InfModel. For set built-in specifications see com.github.sszuev.jena.ontapi.OntSpecification class.

String iri = "https://github.com/owlcs/ont-api";

OntologyManager manager = OntManagers.createManager();

// set ontology specification, see jena-owl2 for more details
manager.getOntologyConfigurator().setSpecification(OntSpecification.OWL2_EL_MEM_RDFS_INF);

OntModel om = manager.createGraphModel(iri);
om.createOntClass(iri + "#A");

// play with InfModel
InfModel im = om.asInferenceModel();
System.out.println(im.validate().isValid());
im.getDeductionsModel().listStatements().forEach(System.out::println);
System.out.println("=".repeat(42));
om.statements(null, RDFS.subClassOf, null).forEach(System.out::println);

10) ONT-MAP (an OWL2 ontology to ontology data mapper and inference engine)

This library is no longer supported ONT-MAP is a SPIN based solution, which allows to transfer a data from one OWL2 schema to another. Consider you have an ontology with two datatype properties, x and y, and data where a number individuals have coordinates assigned in the form of data property assertions. And now you want to transfer this data to another form, into an ontology, where only one datatype property (z) with a meaning hypotenuse (z = sqrt(x^2 + y^2)). The following code demonstrates the whole cycle of the described above scenario, starting from the creating test data, building mapping and finishing with running inference and validation:

Random r = new Random();
int n = 5;
// Assemble the source:
OntModel src = OntModelFactory.createModel().setNsPrefixes(OntModelFactory.STANDARD);
src.setID("src");
OntClass c1 = src.createOntClass("C1");
OntDataRange.Named d1 = src.getDatatype(XSD.integer);
OntDataProperty x = src.createDataProperty("X").addDomain(c1).addRange(d1);
OntDataProperty y = src.createDataProperty("Y").addDomain(c1).addRange(d1);
for (int i = 0; i < n; i++) {
    c1.createIndividual("I#" + i)
            .addProperty(x, d1.createLiteral(String.valueOf(r.nextInt(10))))
            .addProperty(y, d1.createLiteral(String.valueOf(r.nextInt(10))));
}
src.write(System.out, "ttl");

// Assemble the target:
OntModel dst = OntModelFactory.createModel().setNsPrefixes(OntModelFactory.STANDARD);
dst.setID("dst");
OntClass c2 = dst.createOntClass("C2");
OntDataRange d2 = dst.getDatatype(XSD.integer);
OntDataProperty z = dst.createDataProperty("Z").addDomain(c2).addRange(d2);

// Assemble the mapping:
MapManager manager = Managers.createMapManager();
MapFunction uuid = manager.getFunction(AVC.UUID);
MapFunction pow = manager.getFunction(MATH.pow);
MapFunction sum = manager.getFunction(SP.add);
MapFunction sqrt = manager.getFunction(MATH.sqrt);
MapFunction xd = manager.getFunction(XSD.xdouble);
MapFunction.Call f1 = uuid.create().build();
MapFunction.Call f2 = sqrt.create().addFunction(SP.arg1,
        xd.create().addFunction(SP.arg1,
                sum.create()
                        .addFunction(SP.arg1, pow.create()
                                .addProperty(SP.arg1, x)
                                .addLiteral(SP.arg2, 2))
                        .addFunction(SP.arg2, pow.create()
                                .addProperty(SP.arg1, y)
                                .addLiteral(SP.arg2, 2))))
        .build();
MapModel res = manager.createMapModel();
res.asGraphModel().setID("map");
res.createContext(c1, c2, f1).addPropertyBridge(f2, z);

// Run inference:
res.runInference(src.getGraph(), dst.getGraph());

// Print and validate:
dst.write(System.out, "ttl");
Assert.assertEquals(n, dst.individuals().count());

Related readings:

11) ONT-D2RQ (a virtual graph backed to relational databases)

This library is no longer supported This API allows to represent a relational (SQL) database as OWL2 ontology.

// JDBC Connection URI:
String uri = "jdbc:mysql://127.0.0.1/iswc";
// DB Credentials:
String u = "root";
String p = null;
// OWL manager:
OntologyManager manager = OntManagers.createManager();
// a connectivity to database:
OWLOntologyDocumentSource source = D2RQGraphDocumentSource.create(IRI.create(uri), u, p);
// connect, load db schema and assign ontology id to the result anonymous ontology:
OntModel schema = manager.loadOntologyFromOntologyDocument(source).asGraphModel();
schema.setID("d2rq://from-mysql-iswc");
// by way of example, pass all db content into memory and print all OWLAxioms:
Graph inMemory = D2RQGraphUtils.toMemory(schema.getBaseGraph());
OntModel withData = OntModelFactory.createModel(inMemory);
List<OWLAxiom> axioms = AxiomType.AXIOM_TYPES.stream()
        .map(AxiomParserProvider::get)
        .flatMap(t -> t.axioms(withData))
        .map(ONTObject::getOWLObject)
        .collect(Collectors.toList());
// print:
axioms.forEach(System.out::println);
withData.write(System.out, "ttl");