使用OWL API + Openllet获取数据断言公理的解释
我想要获取Openllet Reasoner做出推断的解释。
如果我尝试使用来自 这个 的代码,我会得到错误:未计算出解释。
当我尝试使用来自 这个问题 的答案中的代码示例时,出现错误——此阶段的值不能为null。
我尝试为下一个本体获取解释:
<?xml version="1.0"?>
<rdf:RDF xmlns="ontology://tasks/7c159bcc-b490-417a-9e0c-ea28bab98628#"
xml:base="ontology://tasks/7c159bcc-b490-417a-9e0c-ea28bab98628"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:swrla="http://swrl.stanford.edu/ontologies/3.3/swrla.owl#"
xmlns:base-ontology="http://www.semanticweb.org/user/ontologies/base-ontology#">
<owl:Ontology rdf:about="ontology://tasks/7c159bcc-b490-417a-9e0c-ea28bab98628">
<owl:imports rdf:resource="http://www.semanticweb.org/user/ontologies/base-ontology"/>
</owl:Ontology>
<!-- ontology://tasks/7c159bcc-b490-417a-9e0c-ea28bab98628#Cargo:737106ca-5efa-4035-875b-bf8fcc865754 -->
<owl:NamedIndividual rdf:about="ontology://tasks/7c159bcc-b490-417a-9e0c-ea28bab98628#Cargo:737106ca-5efa-4035-875b-bf8fcc865754">
<rdf:type rdf:resource="http://www.semanticweb.org/user/ontologies/base-ontology#Груз"/>
<base-ontology:Weight rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">24</base-ontology:Weight>
<base-ontology:Cargo_name>Cargo1</base-ontology:Cargo_name>
</owl:NamedIndividual>
<!-- ontology://tasks/7c159bcc-b490-417a-9e0c-ea28bab98628#Road:5b89f851-ee26-48d3-b480-be586ea9c9c2 -->
<owl:NamedIndividual rdf:about="ontology://tasks/7c159bcc-b490-417a-9e0c-ea28bab98628#Road:5b89f851-ee26-48d3-b480-be586ea9c9c2">
<rdf:type rdf:resource="http://www.semanticweb.org/user/ontologies/base-ontology#Road"/>
<base-ontology:Road_length rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">33</base-ontology:Road_length>
<base-ontology:Coating_wear>Medium</base-ontology:Coating_wear>
<base-ontology:Coating_type>Asphalt</base-ontology:Coating_type>
</owl:NamedIndividual>
</rdf:RDF>
在规则本体中,我有如下规则:Road(?r), Road_length(?r, ?l), swrlb:greaterThan(?l, 25) -> Safety_eval(?r, "low"),它把来自任务本体的公理导入到工作本体中。
解决方案
@UninformedUser,
完整代码:
@Service
public class ReasoningService {
@Autowired
private TaskRuleOrderRepository taskRuleRepo;
@Autowired
private TaskOntologyRepository taskRepo;
@Autowired
private UserTaskRoleRepository roleRepo;
@Autowired
private OntologyStorage ontologyStorage;
@Transactional(readOnly = true)
public ReasoningResult run(UUID userId, UUID taskOntologyId) throws UnsupportedOperationException, OWLException, IOException {
taskRepo.findById(taskOntologyId)
.orElseThrow(() -> new EntityNotFoundException("Task ontology not found"));
roleRepo.findByIdUserIdAndIdTaskId(userId, taskOntologyId)
.orElseThrow(() -> new AccessDeniedException("No access"));
OWLOntology taskOntology = ontologyStorage.loadTaskOntology(taskOntologyId);
List<TaskRuleOrder> ruleOntologies = taskRuleRepo.findByIdTaskIdOrderByOrderNumberAsc(taskOntologyId);
if (ruleOntologies == null || ruleOntologies.isEmpty())
throw new IllegalStateException("No rule ontologies assigned");
OWLOntologyManager manager = taskOntology.getOWLOntologyManager();
UUID workId = UUID.randomUUID();
ontologyStorage.createTaskOntology(workId);
OWLOntology workingOntology = ontologyStorage.loadTaskOntology(workId);
manager.addAxioms(workingOntology, taskOntology.getAxioms());
List<InferenceStep> steps = new ArrayList<>();
for (TaskRuleOrder ruleOntologyOrder : ruleOntologies) {
UUID ruleId = ruleOntologyOrder.getId().getRuleId();
OWLOntology ruleOntology = ontologyStorage.loadRuleOntology(ruleId);
InferenceStep step = applyRules(
workingOntology,
ruleOntology,
ruleId
);
steps.add(step);
}
ontologyStorage.deleteTaskOntology(workId);
return new ReasoningResult(taskOntologyId, steps);
}
private InferenceStep applyRules(OWLOntology workingOntology, OWLOntology ruleOntology, UUID ruleOntologyId) throws UnsupportedOperationException, OWLException, IOException {
OWLOntologyManager manager = workingOntology.getOWLOntologyManager();
Set<SWRLRule> rules = ruleOntology.getAxioms(AxiomType.SWRL_RULE);
manager.addAxioms(workingOntology, rules);
OpenlletReasonerFactory rf = OpenlletReasonerFactory.getInstance();
OpenlletReasoner reasoner = rf.createReasoner(workingOntology);
reasoner.getKB().realize();
reasoner.precomputeInferences();
Set<OWLAxiom> inferred = extractInferredAxioms(reasoner, workingOntology);
List<String> explanations = new ArrayList<>();
ExplanationGeneratorFactory<OWLAxiom> genFac = createExplanationGeneratorFactory(rf, null, OWLManager::createOWLOntologyManager);
ExplanationGenerator<OWLAxiom> gen = genFac.createExplanationGenerator(inferred, null);
for (OWLAxiom infer : inferred) {
System.out.println("Inferred axiom: " + infer.toString());
try {
Set<Explanation<OWLAxiom>> explanation = gen.getExplanations(infer, 5);
System.out.println("Explanation: " + explanation.toString());
explanations.add(explanation.toString());
} catch (Exception e) {
System.out.println("ERROR IN EXPLANATION:");
e.printStackTrace();
System.out.println("END ERROR");
}
}
manager.addAxioms(workingOntology, inferred);
reasoner.flush();
reasoner.dispose();
workingOntology.removeAxioms(rules);
return new InferenceStep(
ruleOntologyId,
inferred.stream().map(axiom -> axiom.toString()).toList(),
explanations
);
}
private Set<OWLAxiom> extractInferredAxioms(OpenlletReasoner reasoner, OWLOntology ontology) {
OWLDataFactory factory = ontology.getOWLOntologyManager().getOWLDataFactory();
Set<OWLAxiom> asserted = ontology.getABoxAxioms(Imports.INCLUDED);
Set<OWLAxiom> inferred = new HashSet<>();
for (OWLNamedIndividual individual : ontology.getIndividualsInSignature()) {
NodeSet<OWLClass> types = reasoner.getTypes(individual, false);
for (OWLClass cls : types.getFlattened()) {
inferred.add(factory.getOWLClassAssertionAxiom(cls, individual));
}
for (OWLObjectProperty prop : ontology.objectPropertiesInSignature().toList()) {
NodeSet<OWLNamedIndividual> values =
reasoner.getObjectPropertyValues(individual, prop);
for (OWLNamedIndividual value : values.getFlattened()) {
inferred.add(factory.getOWLObjectPropertyAssertionAxiom(
prop, individual, value
));
}
}
for (OWLDataProperty prop : ontology.dataPropertiesInSignature().toList()) {
Set<OWLLiteral> values =
reasoner.getDataPropertyValues(individual, prop);
for (OWLLiteral val : values) {
inferred.add(factory.getOWLDataPropertyAssertionAxiom(
prop, individual, val
));
}
}
}
inferred.removeAll(asserted);
inferred.removeIf(ax ->
ax.toString().contains("owl:Thing") ||
ax.toString().contains("topDataProperty") ||
ax.toString().contains("topObjectProperty")
);
return inferred;
}
public static ExplanationGeneratorFactory<OWLAxiom> createExplanationGeneratorFactory(
OWLReasonerFactory reasonerFactory, ExplanationProgressMonitor<OWLAxiom> progressMonitor,
Supplier<OWLOntologyManager> m) {
EntailmentCheckerFactory<OWLAxiom> checker =
new SatisfiabilityEntailmentCheckerFactory(reasonerFactory, m);
Configuration<OWLAxiom> config = new Configuration<>(checker,
new StructuralTypePriorityExpansionStrategy<OWLAxiom>(
InitialEntailmentCheckStrategy.PERFORM, m),
new DivideAndConquerContractionStrategy<OWLAxiom>(), progressMonitor, m);
return new BlackBoxExplanationGeneratorFactory<>(config);
}
}
堆栈跟踪:
java.lang.IllegalStateException: value cannot be null at this stage
at org.semanticweb.owlapi.util.OWLAPIPreconditions.verifyNotNull(OWLAPIPreconditions.java:56)
at org.semanticweb.owlapi.util.OWLAPIPreconditions.verifyNotNull(OWLAPIPreconditions.java:40)
at uk.ac.manchester.cs.owl.explanation.ordering.ExplanationOrdererImplNoManager$SeedExtractor.getTarget(ExplanationOrdererImplNoManager.java:309)
at uk.ac.manchester.cs.owl.explanation.ordering.ExplanationOrdererImplNoManager.getOrderedExplanation(ExplanationOrdererImplNoManager.java:174)
at org.semanticweb.owl.explanation.api.Explanation.toString(Explanation.java:149)
at java.base/java.lang.String.valueOf(Unknown Source)
at java.base/java.lang.StringBuilder.append(Unknown Source)
at java.base/java.util.AbstractCollection.toString(Unknown Source)
at com.logistic.ontologies.service.reasoning.ReasoningService.applyRules(ReasoningService.java:130)
at com.logistic.ontologies.service.reasoning.ReasoningService.run(ReasoningService.java:94)
2026-05-11 17:04:32
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
2026-05-11 17:04:32
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:359)
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。