2

我在使用推理 API 的 Jena 2.5.5(在 Linux 上)中得到了一种奇怪的效果。以下代码是精简版。我正在创建一个最初为空的模型和一个通用规则推理器。我为某个陈述添加了反身性规则。我将推理器附加到模型以获得 InfModel。然后我创建匹配语句并将其添加到模型中。

结果:InfModel 包含语句及其反向语句。到目前为止一切顺利,这就是它应该做的。

现在,当我System.out.println()在将匹配语句添加到 Model 之前的 InfModel 时,结果完全不同:规则似乎没有触发,因此,InfModel 最终将不包含原始语句的反向。

将模型写入控制台会如何改变代码的功能?这种行为是否记录在案?

import java.util.*;

import com.hp.hpl.jena.rdf.model.*;
import com.hp.hpl.jena.reasoner.rulesys.*;

/**
 * Describe class <code>RuleTest</code> here.
 */
public class RuleTest {
    public static void main(String[] args) throws Exception {
        /* create model */
        Model model = ModelFactory.createDefaultModel();

        /* output model */
        System.out.println("original model : " + model);
        System.out.println("-----");

        /* collect rules */
        List<Rule> rules = new ArrayList<Rule>();
        Rule rule = Rule.parseRule("[ (subject predicate object) -> (object predicate subject) ].");
        rules.add(rule);

        /* create rule reasoner */
        GenericRuleReasoner reasoner = new GenericRuleReasoner(rules);

        /* attach reasoner to model */
        InfModel infModel = ModelFactory.createInfModel(reasoner, model);

        /* output model */
        //-----------------------------------------------//
        // commenting the following line in/out changes  //
        // the output of (*) below in Jena 2.5.5 ?!?!?!  //
        //-----------------------------------------------//
        //System.out.println("inference model: " + infModel);        
        System.out.println("=====");

        /* add facts to original model */
        Resource s = model.createResource("subject");
        Property p = model.createProperty("predicate");
        RDFNode  o = model.createResource("object");
        Statement stmt = model.createStatement(s, p, o);
        model.add(stmt);

        /* output models */
        System.out.println("original model : " + model);
        System.out.println("-----");
        System.out.println("inference model: " + infModel); // (*)
    }
}
4

3 回答 3

1

快速浏览了相关来源,您似乎有两个选择:

  • 如果您想对基本模型进行更改,然后确保它们传播到infModel,那么您必须在进行更改之后调用infModel.rebind()并且在“询问” infModel任何内容之前。

  • 您可以直接使用infModel(而不是model)来创建和添加语句的元素和语句本身。

我知道这并不能直接回答您的问题,但它可能会解决您的问题(顺便说一句,这似乎是由 ModelCom 中的 toString() 方法触发的具体化引起的- InfModel)。

于 2008-12-11T21:00:06.320 回答
0

现在是几年后的事了,Jena 在 2.10.x 系列中。当指示的行被注释掉时,您的程序的输出是:

original model : <ModelCom   {} | >
-----
=====
original model : <ModelCom   {subject @predicate object} |  [subject, predicate, object]>
-----
inference model: <ModelCom   {object @predicate subject; subject @predicate object} |  [object, predicate, subject] [subject, predicate, object]>

InfModel 的字符串表示包含两个三元组。取消注释该行时,输出为:

original model : <ModelCom   {} | >
-----
inference model: <ModelCom   {} | >
=====
original model : <ModelCom   {subject @predicate object} |  [subject, predicate, object]>
-----
inference model: <ModelCom   {subject @predicate object} |  [subject, predicate, object]>

InfModel 的第二个字符串表示只有一个三元组,所以仍然可以观察到差异。(我在此处包含了输出,因为在问题中尚不清楚观察到的差异。)

简短的回答是,发生这种情况是因为您偷偷摸摸地进行修改model,而没有告诉infModel您更改了底层model. infModel.rebind();为了解决这个问题,你应该在 update 之后添加一个调用model。也就是说,您现在将拥有:

model.add(stmt);
infModel.rebind();

当你这样做时,你会在两种情况下得到相同的输出。该行评论为:

original model : <ModelCom   {} | >
-----
=====
original model : <ModelCom   {subject @predicate object} |  [subject, predicate, object]>
-----
inference model: <ModelCom   {object @predicate subject; subject @predicate object} |  [object, predicate, subject] [subject, predicate, object]>

未注释该行:

original model : <ModelCom   {} | >
-----
inference model: <ModelCom   {} | >
=====
original model : <ModelCom   {subject @predicate object} |  [subject, predicate, object]>
-----
inference model: <ModelCom   {object @predicate subject; subject @predicate object} |  [object, predicate, subject] [subject, predicate, object]>

我的猜测是,编写 InfModel 的字符串表示不会导致执行任何推理,除非尚未执行任何推理,然后打印底层模型,然后打印任何额外的三元组。因此:

  • 在第一种情况下(当您infModel只打印一次时)它还没有进行任何推理,因此它会咨询model并进行适当的推理并获得额外的三元组。然后它打印model's 三元组,然后是推断的三元组。
  • 在第二种情况下(当您打印infModel两次时),第一次打印infModel时,它会咨询model并进行一些推断,但model它是空的,因此没有额外的三元组,然后它打印model的三元组和额外的推断三元组(有没有任何)。然后,第二次infModel打印,推理已经执行,所以它打印model的三元组(但有一个额外的)和任何推断的三元组(没有,因为没有执行更多的推理)。

rebind()在添加三元组后调用 tomodel意味着在第二种情况下,额外的推断三元组在打印时可用。

于 2013-09-24T16:48:40.803 回答
0

model.toString() 很可能有副作用。我没有看过 JENA 的来源,所以我不能确定。

于 2008-12-08T21:07:42.470 回答