You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache Jena无法基于数据属性推理个体类型问题

OWL本体类型推理失败问题排查与解决

问题背景

我用Protégé创建了一个简单OWL本体,内容如下:

  • 类Person
  • 类Adult:子类于Person与限制条件age exactly 1 xsd:integer[> 17]的交集
  • 类Minor:子类于Person与限制条件age exactly 1 xsd:integer[< 18]的交集
  • 数据属性age:定义域为Adult和Minor的并集,值域为xsd:integer
  • 个体Child(age=12)、Grandfather(age=70)

目标是通过Jena推理,根据age值推断个体类型(如Child属于Minor),编写的代码如下:

OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM_RULE_INF);
FileManager fileManager = FileManager.getInternal();
model.read(fileManager.open(Objects.requireNonNull(getClass().getResource("/persone.owl")).toString()), null);

Reasoner reasoner = ReasonerRegistry.getOWLReasoner().bindSchema(model);
InfModel infModel = ModelFactory.createInfModel(reasoner, model);

Resource minor = infModel.getResource("http://www.semanticweb.org/lorenzo/ontologies/2023/5/Persone#Minor");
Resource child = infModel.getResource("http://www.semanticweb.org/lorenzo/ontologies/2023/5/Persone#Child");

printStatements(infModel, child, null, null);

if (infModel.contains(child, RDF.type, minor)) {
    System.out.println("Child is type Minor -> Inferenced correctly");
} else {
    System.out.println("Failed to inference Child's type correctly");
}

但推理失败,输出结果:

- (<http://www.semanticweb.org/lorenzo/ontologies/2023/5/Persone#Child> <http://www.semanticweb.org/lorenzo/ontologies/2023/5/Persone#age> '12'^^http://www.w3.org/2001/XMLSchema#integer)
 - (<http://www.semanticweb.org/lorenzo/ontologies/2023/5/Persone#Child> rdf:type owl:NamedIndividual)
 - (<http://www.semanticweb.org/lorenzo/ontologies/2023/5/Persone#Child> rdf:type owl:Thing)
 - (<http://www.semanticweb.org/lorenzo/ontologies/2023/5/Persone#Child> owl:sameAs <http://www.semanticweb.org/lorenzo/ontologies/2023/5/Persone#Child>)
 - (<http://www.semanticweb.org/lorenzo/ontologies/2023/5/Persone#Child> rdf:type rdfs:Resource)
 - (<http://www.semanticweb.org/lorenzo/ontologies/2023/5/Persone#Child> rdf:type 2449192a-2fc0-426e-a3ab-f9ef16f56342)
Failed to inference Child's type correctly

问题原因

  1. 推理器能力不足:Jena自带的OWL_DL_MEM_RULE_INF规则推理器对OWL 2的数值限制推理支持有限,无法处理基于数据属性数值比较的类成员推断。
  2. 本体类定义不严谨:将Adult和Minor定义为交集的子类,而非等价类。推理器需要明确的等价类定义,才能反向推断个体所属类。

解决方案

1. 修正本体类定义

在Protégé中,将Adult和Minor的定义从SubClass Of改为Equivalent To:

  • Adult等价于:Person and (age exactly 1 xsd:integer[> 17])
  • Minor等价于:Person and (age exactly 1 xsd:integer[< 18])

2. 更换支持OWL 2的推理器

使用HermiT或Pellet这类完整的OWL 2推理器,替代Jena自带的规则推理器。以下是使用HermiT的代码示例:

import org.semanticweb.HermiT.ReasonerFactory;
import org.apache.jena.ontology.OntModel;
import org.apache.jena.ontology.OntModelSpec;
import org.apache.jena.rdf.model.InfModel;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.util.FileManager;
import org.apache.jena.reasoner.Reasoner;

import java.util.Objects;

public class OntologyInference {
    public static void main(String[] args) {
        // 创建基础本体模型
        OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM);
        FileManager fileManager = FileManager.getInternal();
        model.read(fileManager.open(Objects.requireNonNull(OntologyInference.class.getResource("/persone.owl")).toString()), null);

        // 初始化HermiT推理器
        ReasonerFactory reasonerFactory = new ReasonerFactory();
        Reasoner reasoner = reasonerFactory.createReasoner(model.getOntModelSpec().getProfile());
        InfModel infModel = ModelFactory.createInfModel(reasoner, model);

        // 获取资源引用
        Resource minor = infModel.getResource("http://www.semanticweb.org/lorenzo/ontologies/2023/5/Persone#Minor");
        Resource child = infModel.getResource("http://www.semanticweb.org/lorenzo/ontologies/2023/5/Persone#Child");

        // 输出所有相关语句
        printStatements(infModel, child, null, null);

        // 验证推理结果
        if (infModel.contains(child, org.apache.jena.vocabulary.RDF.type, minor)) {
            System.out.println("Child is type Minor -> Inferenced correctly");
        } else {
            System.out.println("Failed to inference Child's type correctly");
        }
    }

    private static void printStatements(InfModel model, Resource subject, org.apache.jena.rdf.model.Property predicate, org.apache.jena.rdf.model.RDFNode object) {
        model.listStatements(subject, predicate, object).forEachRemaining(stmt -> {
            System.out.println(" - (" + stmt.getSubject() + " " + stmt.getPredicate() + " " + stmt.getObject() + ")");
        });
    }
}

3. 添加依赖(Maven)

在pom.xml中添加HermiT和Jena的依赖:

<dependencies>
    <!-- Jena本体API -->
    <dependency>
        <groupId>org.apache.jena</groupId>
        <artifactId>jena-ontology</artifactId>
        <version>4.9.0</version>
    </dependency>
    <!-- HermiT推理器 -->
    <dependency>
        <groupId>net.sourceforge.owlapi</groupId>
        <artifactId>org.semanticweb.hermit</artifactId>
        <version>1.4.3.517</version>
    </dependency>
</dependencies>

验证效果

修改后运行代码,推理器会正确推断出Child rdf:type Minor,输出中会包含该语句,并打印Child is type Minor -> Inferenced correctly。

内容的提问来源于stack exchange,提问作者Alessio Rubicini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 19:45:24