我的目标:在包含大约5000个公理的本体中找到不相交的公理(断言和推断)。
我的代码:
for (OWLClass clazz1 : ontology.getClassesInSignature()) {
for (OWLClass clazz2 : ontology.getClassesInSignature()) {
OWLAxiom axiom = MyModel.factory.getOWLDisjointClassesAxiom(clazz2, clazz1);
if( !(ontology.containsAxiom(axiom)) && reasoner.isEntailed(axiom))
{
System.out.println(clazz2.toString() + " disjoint with " + clazz1.toString());
}
问题:执行时间非常慢,我会说是永恒的。即使我减少与if语句的比较次数,情况仍然是相同的。
Protege似乎可以非常快速地计算出那些推断的公理,并且它基于我正在使用的相同API(OWLAPI)。那么,我的方法是错误的吗?
答案 0 :(得分:1)
分析代码很可能会发现缓慢的部分是
reasoner.isEntailed(axiom)
此表单要求推理人重新计算每个类对的蕴涵,包括clazz1
和clazz2
相等的对(您可能希望跳过该对)。
或者,您可以在签名中迭代一次,并使用推理器获取所有不相交的类:
Set<OWLClass> visited=new HashSet<>();
for (OWLClass c: ontology.getClassesInSignature()) {
if (visited.add(c)) {
NodeSet set = reasoner.getDisjointClasses(c);
for (Node node: set.getNodes()) {
System.out.println("Disjoint with "+c+": "+node);
visited.addAll(node.getEntities());
}
}
}
最糟糕的情况是,这将为每个类调用一个推理器(因为没有类是不相交的)。最好的情况是,所有类都是不相交的或等同于另一个类,因此只需要一个推理器调用。