递归查询的反向链接堆栈溢出

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。