【问题标题】:printing InfModel earlier changes printed representation later?早先打印 InfModel 会在以后更改打印表示?
【发布时间】:2008-12-08 14:08:43
【问题描述】:

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

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

现在,当我 System.out.println() InfModel 在将匹配语句添加到 Model 之前,结果完全不同:规则似乎没有触发,因此,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); // (*)
    }
}

【问题讨论】:

    标签: java jena jena-rules


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 感谢您的回答-我认为 toString() 必须有副作用不仅“可能”而且完全显而易见。这当然是出乎意料的,但也许我对耶拿的经验太少了,不知道发生了什么。无论如何,我找不到任何关于这种行为的文档。
      【解决方案3】:

      现在是几年后,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。为了解决这个问题,您应该在更新model 后添加对infModel.rebind(); 的调用。也就是说,您现在将拥有:

      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 的三元组(但还有一个额外的)和任何推断的三元组(没有,因为没有执行更多的推断)。

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

      【讨论】:

        猜你喜欢
        • 2011-08-24
        • 1970-01-01
        • 1970-01-01
        • 2013-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-06
        • 1970-01-01
        相关资源
        最近更新 更多