打印InfModel之前更改后的打印表示?

时间:2008-12-08 14:08:43

标签: java jena jena-rules

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

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

现在,当我在向Model添加匹配语句之前System.out.println() 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); // (*)
    }
}

3 个答案:

答案 0 :(得分:1)

快速浏览一下相关来源,看来你有两个选择:

  • 如果您想更改基本模型,然后确保它们传播到 infModel ,那么您必须调用 infModel完成更改之后,在“询问” infModel 之前.rebind()

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

我知道这并没有直接回答你的问题,但它可以解决你的问题(顺便说一句,似乎是由 ModelCom中的 toString()方法触发的具体化引起的/ em> - InfModel 的父类。)

答案 1 :(得分:0)

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

答案 2 :(得分: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();后添加对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的三元组,然后是推断的三元组。
  • 在第二种情况下(当您打印infModel两次)时,第一次打印infModel时,它会咨询model并进行一些推断,但model为空,所以没有额外的三元组,然后它打印model的三元组和额外的推断三元组(没有)。然后,第二次打印infModel,已经执行推理,因此它打印model的三元组(但是有一个额外的三元组)和任何推断的三元组(没有,因为没有更多的推论演出)。

在向rebind()添加三元组后调用model表示在第二种情况下,在打印时可以使用其他推断的三元组。