Java 早期打印模型会在以后更改打印的表示形式吗?
我在Jena 2.5.5(Linux上)中得到了一个奇怪的效果,我在那里玩推理API。下面的代码是一个精简版本。我正在创建一个初始为空的模型和一个通用规则推理器。我为某个语句添加了一个自反性规则。我将推理器附加到模型以获得一个模型。然后创建匹配语句并将其添加到模型中 结果:InfModel同时包含语句及其反面。到目前为止还不错,这就是它应该做的 现在,在将匹配语句添加到模型之前,当我Java 早期打印模型会在以后更改打印的表示形式吗?,java,jena,jena-rules,Java,Jena,Jena Rules,我在Jena 2.5.5(Linux上)中得到了一个奇怪的效果,我在那里玩推理API。下面的代码是一个精简版本。我正在创建一个初始为空的模型和一个通用规则推理器。我为某个语句添加了一个自反性规则。我将推理器附加到模型以获得一个模型。然后创建匹配语句并将其添加到模型中 结果:InfModel同时包含语句及其反面。到目前为止还不错,这就是它应该做的 现在,在将匹配语句添加到模型之前,当我System.out.println()InfModel时,结果完全不同:规则似乎不会触发,因此InfModel最
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); // (*)
}
}
很可能model.toString()有副作用。我还没有查看JENA源代码,所以我不能确定。快速查看了相关源代码,您似乎有两个选择:
- 如果要对基础模型进行更改,然后确保它们传播到infModel,则必须在进行更改之后以及在“询问”infModel之前调用infModel.rebind()
- 您可以直接使用infModel(而不是model)来创建和添加语句的元素和语句本身
我知道这并不能直接回答您的问题,但它可能会解决您的问题(顺便说一句,这似乎是由ModelCom中的toString()方法触发的具体化引起的,该方法是InfModel的父类)。几年后的今天,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]>
当您这样做时,您将在两种情况下获得相同的输出。评论这句话时:
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]>
原始型号:
-----
=====
原始型号:
-----
推理模型:
在未注释行的情况下:
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
- 在第二种情况下(当您打印两次
时),第一次打印infModel
时,它参考infModel
并进行一些推断,但是model
为空,因此没有额外的三元组,然后它打印model
的三元组和额外推断的三元组(没有)。然后,第二次打印model
时,推理已经执行,因此它打印infModel
的三元组(但有一个额外的三元组)和任何推断的三元组(没有,因为没有执行更多的推理)model
将三元组添加到
model
后调用rebind()
,这意味着在第二种情况下,额外的推断三元组在打印时可用。感谢您的回答-我认为toString()不仅“可能”,而且完全明显地具有副作用。这当然出乎意料,但也许我和耶拿在一起的经历太少,不知道发生了什么。在任何情况下,我都找不到关于这种行为的任何文档。