How to properly merge 2 ontologies with OWL API 4 or 3.5

2.2k views Asked by At

in my master thesis project I want to merge several ontologies (filled only with individuals) having different namespaces, but sharing the same imports and some individuals(e.G ontologyA#Harold & ontologyB#Harold).

I'm trying to gain a new merged ontology where:

  1. the ontology header's information of the 2 ontologies are preserved (like in Protege 5 with OWL API 3.5.1).
  2. Individuals from merged ontologies are "merged" despite their different namespaces
  3. The merged ontology has only 1 namespace

My code for the merging

private ArrayList<Ontology> ontologies;
    private OWLOntologyManager man;
    private OWLOntologyMerger merger;
    private String fileName;
    private OWLOntology mergedOntology;

public Merger(ArrayList<Ontology> ontologies, OWLOntologyManager man, String filename){

        this.ontologies = ontologies;
        this.man = man;
        this.fileName = filename;
        //create the OWL Ontology merger which retrievs all loaded ontology from manager
        merger = new OWLOntologyMerger(man);    
        //call the merging process
        mergeOntologies();
    }

private void mergeOntologies(){
        IRI mergedOntologyIRI = IRI.create("http://semanticweb.org/ontology/" + fileName);
        for(Ontology ontology : ontologies){
            try {

                man.loadOntologyFromOntologyDocument(ontology.getFile());

            } catch (OWLOntologyCreationException e) {
                e.printStackTrace();
            }
        }
        try {
            mergedOntology = merger.createMergedOntology(man, mergedOntologyIRI);
        } catch (OWLOntologyCreationException e) {
            e.printStackTrace();
        }   
    }

So far I could only archive a simple textual merge of the individuals of the ontologies. On Protege also the ontology headers are merged,but not with my code.

As I understand I cannot merge 2 ontologies having the same namespace, the OWLOntologyManager will throw an Exception. Therefore it's not an option.

How can I achieve a "smart" merging of ontologies? What I'm doing wrong? Is there any code example?


In response to Ignazio: With ontology header I mean:

<owl:Ontology rdf:about="http://semanticweb.org/ontologies/Harold/Structural_Context">
        <structure:modeltype>Structural Context</structure:modeltype>
        <structure:modelname>Harold</structure:modelname>
        <structure:adoversion>Version 1.0 4.0</structure:adoversion>
        <structure:date>07.01.2015</structure:date>
        <structure:time>17:49</structure:time>
        <structure:username>alex</structure:username>
        <owl:imports rdf:resource="http://MyServer/HCML/structure"/>
    </owl:Ontology>

The individual Harold of Ontology A looks like:

<owl:NamedIndividual rdf:about="http://semanticweb.org/ontologies/Harold/Structural_Context#Harold">
        <rdf:type rdf:resource="http://MyServer/HCML/structure#Object"/>
    </owl:NamedIndividual>

The individual Harold of Ontology B looks like:

<owl:NamedIndividual rdf:about="http://semanticweb.org/ontologies/evening_activity/User_Context#Harold">
        <rdf:type rdf:resource="http://MyServer/HCML/structure#Person"/>
        <structure:connection rdf:resource="http://semanticweb.org/ontologies/evening_activity/User_Context#bedroom"/>
        <structure:calling rdf:resource="http://semanticweb.org/ontologies/evening_activity/User_Context#enter_the_living_room"/>
        <structure:executing rdf:resource="http://semanticweb.org/ontologies/evening_activity/User_Context#enter_the_living_room"/>
        <structure:participating rdf:resource="http://semanticweb.org/ontologies/evening_activity/User_Context#enter_the_living_room"/>
    </owl:NamedIndividual>

Adding the axioms:

IRI mergedOntologyIRI = IRI.create("http://semanticweb.org/ontology/" + fileName);
        Set<OWLAxiom> axioms = new HashSet<OWLAxiom>();
        for(Ontology ontology : ontologies){
                man.loadOntologyFromOntologyDocument(ontology.getFile());
                axioms.addAll(ontology.getOntology().getAxioms());
                man.removeOntology(ontology.getOntology());
        }
            mergedOntology = man.createOntology(mergedOntologyIRI);
            man.addAxioms(mergedOntology, axioms);

The result is the same as using the OWLOntologyMerger.

Merging manually the axioms, imports and using the OWLEntityRenamer I could achieve a good merging result.

Here the code:

private void mergeOntologies(){
IRI mergedOntologyIRI = IRI.create("http://semanticweb.org/ontology/" + fileName);
    //Using HashSet to avoid duplicated entries
    Set<OWLAxiom> axioms = new HashSet<OWLAxiom>();
    Set<OWLImportsDeclaration> imports = new HashSet<OWLImportsDeclaration>();
    try{    
        for(Ontology ontology : ontologies){
            man.loadOntologyFromOntologyDocument(ontology.getFile());
            axioms.addAll(ontology.getOntology().getAxioms());
            imports.addAll(ontology.getOntology().getImportsDeclarations());
            man.removeOntology(ontology.getOntology()); 
        } 
        mergedOntology = man.createOntology(mergedOntologyIRI);
        man.addAxioms(mergedOntology, axioms);
    } catch (OWLOntologyCreationException e) {
        e.printStackTrace();
    } 
    //Adding the import declarations
    for(OWLImportsDeclaration decl : imports){
        man.applyChange(new AddImport(mergedOntology, decl));
    }
    //rename individuals names to use the merged ontology's IRI
    renameIRIs(mergedOntologyIRI);
}

  private void renameIRIs (IRI newIRI){
        OWLEntityRenamer renamer = new OWLEntityRenamer(man, man.getOntologies());

        for(Ontology ontology : ontologies){
            for ( OWLEntity individual : ontology.getOntology().getIndividualsInSignature()){
                //replace the individual's old IRI with the new one E.g: http://ontologyOld#name becomes newIRI#name
                IRI individualName = IRI.create(individual.getIRI().toString().replaceFirst("[^*]+(?=#|;)", newIRI.toString()));
                man.applyChanges(renamer.changeIRI(individual.getIRI(), individualName));
            }
        }   
    }
1

There are 1 answers

8
Ignazio On BEST ANSWER

The namespace for the ontologies is not the issue - the problem is when the ontologies have the same ontology id. In that case, they cannot be merged in the same manager - the manager needs the relation ontologyID->ontology to be functional. To be able to use the same ontology id for a new ontology, it must be managed by a separate manager.

Note that the ontology IRI does not dictate the namespace for the individual names contained in it; once parsed, the individual IRIs are independent of the ontology, and the axioms can be moved to other ontologies without issues.

Can you describe what you mean by ontology headers?

The ontology axioms themselves can be merged in multiple ways; the simplest I can think of is adding all axioms from both ontologies to a set, and using the set to create a new ontology.