java - 如何使用 OWL API 4 或 3.5 正确合并 2 个本体

标签 java merge ontology owl-api

在我的硕士论文项目中,我想合并几个具有不同命名空间的本体(仅填充个体),但共享相同的导入和一些个体(例如本体A#Harold 和本体B#Harold)。

我正在尝试获得一个新的合并本体,其中:

  1. 保留了 2 个本体的本体 header 信息(如使用 OWL API 3.5.1 的 Protege 5)。
  2. 来自合并本体的个体被“合并”,尽管它们的命名空间不同
  3. 合并后的本体只有 1 个命名空间

我的合并代码

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();
        }   
    }

到目前为止,我只能归档本体个体的简单文本合并。在 Protege 上,本体标题也被合并,但不与我的代码合并。

据我所知,我无法合并具有相同命名空间的 2 个本体,OWLOntologyManager 将抛出异常。因此这不是一个选择。

如何实现本体的“智能”合并? 我做错了什么? 有代码示例吗?

<小时/>

回复伊格纳齐奥: 对于本体标题,我的意思是:

<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>

本体A的Harold个体看起来像:

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

本体 B 的 Harold 个体看起来像:

<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>
<小时/>

添加公理:

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);

结果与使用 OWLOntologyMerger 相同。

手动合并公理、导入并使用 OWLEntityRenamer 我可以获得良好的合并结果。

代码如下:

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));
            }
        }   
    }

最佳答案

本体的命名空间不是问题 - 问题是当本体具有相同的本体 ID 时。在这种情况下,它们不能合并在同一个管理器中 - 管理器需要关系ontologyID->ontology才能发挥作用。为了能够对新本体使用相同的本体 ID,它必须由单独的管理器进行管理。

请注意,本体 IRI 并不规定其中包含的各个名称的命名空间;一旦解析,各个 IRI 就独立于本体,并且公理可以毫无问题地转移到其他本体。

您能描述一下本体标题的含义吗?

本体公理本身可以通过多种方式合并;我能想到的最简单的方法是将两个本体中的所有公理添加到一个集合中,并使用该集合创建一个新的本体。

关于java - 如何使用 OWL API 4 或 3.5 正确合并 2 个本体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30888449/

相关文章:

java - 如何传递参数

调用 getDrawable() 时出现 java.lang.OutOfMemoryError

java - 如何在java中有效地使用方法中的参数?

r - 在 R4.0.0 中合并数据帧比 R3.6.3 慢 60 倍?

java - 什么使 java 中的枚举不可实例化?

c# - 如何在 C# 中将两个 List<dynamic> 对象合并为一个具有特定条件的对象?

python - 使用非唯一索引合并多个 pandas 数据集

java - 使用 Jena API 读取猫头鹰文件

java - 如何使用 Jena Java API 从本体读取对象属性

java - org.semanticweb.owl.io.UnparsableOntologyException