不幸的是,我想不出一種方法來強制Jena構建原始數據信息的派生。然而,我可以想出一種蠻力的方式來導致信息被派生出來,從而導致派生。
考慮以下(JUnit的)測試通過的結果:
final Property p = ResourceFactory.createProperty("urn:eg:p");
final Model rawData = ModelFactory.createDefaultModel();
final Resource a = rawData.createResource("urn:a");
final Resource b = rawData.createResource("urn:b");
final Resource c = rawData.createResource("urn:c");
a.addProperty(p, b);
b.addProperty(p, c);
a.addProperty(p, c);
final String rules = "[rule1: (?a urn:eg:p ?b) (?b urn:eg:p ?c) -> (?a urn:eg:p ?c)]";
final Reasoner reasoner = new GenericRuleReasoner(Rule.parseRules(rules));
reasoner.setDerivationLogging(true);
final InfModel inf = ModelFactory.createInfModel(reasoner, rawData);
assertTrue(inf.contains(a,p,c));
final Iterator<Derivation> d0 = inf.getDerivation(inf.asStatement(Triple.create(a.asNode(), p.asNode(), c.asNode())));
assertFalse(d0.hasNext());
inf.remove(a,p,c);
assertTrue(inf.contains(a,p,c));
final Iterator<Derivation> d1 = inf.getDerivation(inf.asStatement(Triple.create(a.asNode(), p.asNode(), c.asNode())));
assertTrue(d1.hasNext());
實際上,如果從爲當前原始數據圖中刪除三,然後,如果三重可以衍生它將保留在圖表中。然後你可以得到派生。
final Set<Statement> statements = new HashSet<>(rawData.listStatements().toSet());
for(final Statement s : statements) {
assert(inf.contains(s));
inf.remove(s);
if(!inf.contains(s)) {
System.out.println("Cannot derive statement from raw data: "+s);
inf.add(s);
} else {
System.out.println("Derivable statement removed from raw data: "+s);
}
}
對於以上(假設我們創造inf
後刪除一切,我們的循環替換它)的示例數據:您可以使用下面的循環安全地進行對在圖中所有三元這樣(昂貴)的操作,輸出如下:現在
Derivable statement removed from raw data: [urn:a, urn:eg:p, urn:c]
Cannot derive statement from raw data: [urn:b, urn:eg:p, urn:c]
Cannot derive statement from raw data: [urn:a, urn:eg:p, urn:b]
你的數據在這裏您可以取得推導爲所有衍生事物的狀態,而只有rawData
最小量仍然會允許你總結的inf
全部。
請注意,此操作的行爲可能不一致或預期,特別是在存在多個派生路徑的情況下。祝你好運。
爲了有助於回答這個問題,請你提供一些關於通過讓推理記錄這些推導可以滿足的目標的背景嗎?例如,您是否嘗試識別三元組,如果已刪除,可能會/將被當前規則集重新派生? –
@RobHall是的,我想要檢查所有三元組的派生路徑,甚至可以在被移除後推斷出那些派生路徑 – riad