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

时间:2015-03-14 11:19:15

标签: drools

我正在尝试使用Drools反向链接机制和一些简单的Web本体语言(OWL)-RL逻辑。 OWL支持反向属性,这意味着我必须从我的TBox生成递归查询。 Drools文档指出“该算法使用堆栈来处理递归,因此方法堆栈不会爆炸。”但是在调用我的查询时,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;
    }
}

2 个答案:

答案 0 :(得分:0)

我认为这个查询组合是(如果你原谅表达式)一个冲洗。运行

bind_tsEquivalent_value"(sub, obj)

没有匹配的Statement会导致评估

bind_phxEquivalent_inverse_value(sub)

并且代表

bind_tsEquivalent_inverse_value(sub)

然后到

bind_phxEquivalent_inverse_value(sub)

现在你陷入无限递归循环。

非终端分支上没有约束条件的逻辑“或”不足以打破递归。 DRL编译器可能会在这样的循环中被捕获时终止递归,但基本上(我认为)这是程序员的错误。

答案 1 :(得分:0)

“CPU使用率达到100%,堆栈增长到无穷大。”

堆还是堆栈?如果您的查询永远不会返回,它将递归,直到您的堆空间用完为止。

如果是堆栈错误,可以粘贴跟踪。