在耶拿的规则推理者中记录先前断言的三元组的推导?

时间:2014-05-20 07:03:52

标签: java rdf jena jena-rules

我在文档中创建了一个Jena Rule Reasoner

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);

一切正常,我可以检查推断模型中三元组的推导,但rawData中已存在的三元组不会被推理器重新推断,即使它们可能是,这意味着没有关于这种三元组的推导的记录。有没有办法强制推理者重新推断和记录原始数据中已存在的三元组的派生?

1 个答案:

答案 0 :(得分:0)

不幸的是,我想不出一种方法可以迫使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的全部内容。

请注意,此操作的行为可能不一致或预期,尤其是在存在多个派生路径时。祝你好运。