我在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); // (*)
}
}
答案 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
表示在第二种情况下,在打印时可以使用其他推断的三元组。