递归查询的反向链接堆栈溢出
Backward chaining stack overflow for recursive queries
我正在试验 Drools 反向链接机制和一些简单的 Web Ontology 语言 (OWL)-RL 逻辑。 OWL 支持反向属性,这意味着我必须从我的 TBox 生成递归查询。 Drools 文档指出 "The algorithm uses stacks to handle recursion, so the method stack will not blow up.",但在调用我的查询时,CPU 使用率达到 100%,堆栈增长到无穷大。我对两个逆属性 "tsEquivalen" 和 "phxEquivalent" 进行了三个查询。调用的查询是 "bind_tsEquivalent_value" 查询。
query "bind_tsEquivalent_value"(Resource $subject, Resource $object)
@Abductive(target=ObjectPropertyQueryResult.class)
Statement(subject == $subject, predicate == tsEquivalent, $object := object)
or
$object := bind_phxEquivalent_inverse_value($subject;)
end
query "bind_tsEquivalent_inverse_value"(Resource $subject, Resource $object)
@Abductive(target=ObjectPropertyQueryResult.class)
Statement($object := subject, predicate == tsEquivalent, object == $subject)
or
$object := bind_phxEquivalent_inverse_value($subject;)
end
query "bind_phxEquivalent_inverse_value"(Resource $subject, Resource $object)
@Abductive(target=ObjectPropertyQueryResult.class)
Statement($object := subject, predicate == phxEquivalent, object == $subject)
or
$object := bind_tsEquivalent_inverse_value($subject;)
end
我的 ObjectPropertyQueryResult 如下所示:
import com.hp.hpl.jena.rdf.model.Resource;
public class ObjectPropertyQueryResult {
private Resource subject;
private Resource object;
public ObjectPropertyQueryResult() {
super();
}
public ObjectPropertyQueryResult(Resource subject, Resource object) {
this.subject = subject;
this.object = object;
}
public Resource getSubject() {
return subject;
}
public void setSubject(Resource subject) {
this.subject = subject;
}
public Resource getObject() {
return object;
}
public void setObject(Resource object) {
this.object = object;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((object == null) ? 0 : object.hashCode());
result = prime * result + ((subject == null) ? 0 : subject.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ObjectPropertyQueryResult other = (ObjectPropertyQueryResult) obj;
if (object == null) {
if (other.object != null)
return false;
} else if (!object.equals(other.object))
return false;
if (subject == null) {
if (other.subject != null)
return false;
} else if (!subject.equals(other.subject))
return false;
return true;
}
}
我认为这个查询组合(如果你原谅这个表达)是一个淘汰赛。 运行
bind_tsEquivalent_value"(sub, obj)
没有匹配 Statement
导致评估
bind_phxEquivalent_inverse_value(sub)
并且此委托给
bind_tsEquivalent_inverse_value(sub)
然后到
bind_phxEquivalent_inverse_value(sub)
现在您陷入了无限递归循环。
在非终端分支上没有约束条件的逻辑 "or" 不足以打破递归。当陷入这样的循环时,DRL 编译器可能应该终止递归,但基本上(我认为)这是程序员的错误。
"the CPU usage goes to 100% and the stack grows to infinity."
堆还是栈?如果您的查询从不 returns,它将递归直到您 运行 超出堆 space。
如果是堆栈错误,能不能贴一下trace。
我正在试验 Drools 反向链接机制和一些简单的 Web Ontology 语言 (OWL)-RL 逻辑。 OWL 支持反向属性,这意味着我必须从我的 TBox 生成递归查询。 Drools 文档指出 "The algorithm uses stacks to handle recursion, so the method stack will not blow up.",但在调用我的查询时,CPU 使用率达到 100%,堆栈增长到无穷大。我对两个逆属性 "tsEquivalen" 和 "phxEquivalent" 进行了三个查询。调用的查询是 "bind_tsEquivalent_value" 查询。
query "bind_tsEquivalent_value"(Resource $subject, Resource $object)
@Abductive(target=ObjectPropertyQueryResult.class)
Statement(subject == $subject, predicate == tsEquivalent, $object := object)
or
$object := bind_phxEquivalent_inverse_value($subject;)
end
query "bind_tsEquivalent_inverse_value"(Resource $subject, Resource $object)
@Abductive(target=ObjectPropertyQueryResult.class)
Statement($object := subject, predicate == tsEquivalent, object == $subject)
or
$object := bind_phxEquivalent_inverse_value($subject;)
end
query "bind_phxEquivalent_inverse_value"(Resource $subject, Resource $object)
@Abductive(target=ObjectPropertyQueryResult.class)
Statement($object := subject, predicate == phxEquivalent, object == $subject)
or
$object := bind_tsEquivalent_inverse_value($subject;)
end
我的 ObjectPropertyQueryResult 如下所示:
import com.hp.hpl.jena.rdf.model.Resource;
public class ObjectPropertyQueryResult {
private Resource subject;
private Resource object;
public ObjectPropertyQueryResult() {
super();
}
public ObjectPropertyQueryResult(Resource subject, Resource object) {
this.subject = subject;
this.object = object;
}
public Resource getSubject() {
return subject;
}
public void setSubject(Resource subject) {
this.subject = subject;
}
public Resource getObject() {
return object;
}
public void setObject(Resource object) {
this.object = object;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((object == null) ? 0 : object.hashCode());
result = prime * result + ((subject == null) ? 0 : subject.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ObjectPropertyQueryResult other = (ObjectPropertyQueryResult) obj;
if (object == null) {
if (other.object != null)
return false;
} else if (!object.equals(other.object))
return false;
if (subject == null) {
if (other.subject != null)
return false;
} else if (!subject.equals(other.subject))
return false;
return true;
}
}
我认为这个查询组合(如果你原谅这个表达)是一个淘汰赛。 运行
bind_tsEquivalent_value"(sub, obj)
没有匹配 Statement
导致评估
bind_phxEquivalent_inverse_value(sub)
并且此委托给
bind_tsEquivalent_inverse_value(sub)
然后到
bind_phxEquivalent_inverse_value(sub)
现在您陷入了无限递归循环。
在非终端分支上没有约束条件的逻辑 "or" 不足以打破递归。当陷入这样的循环时,DRL 编译器可能应该终止递归,但基本上(我认为)这是程序员的错误。
"the CPU usage goes to 100% and the stack grows to infinity."
堆还是栈?如果您的查询从不 returns,它将递归直到您 运行 超出堆 space。
如果是堆栈错误,能不能贴一下trace。