Apache Jena框架的推理示例存在问题
我有一个严重的问题,让任何推理器运行起来。 此外,文档中的示例: https : //jena.apache.org/documentation/inference/在此处不起作用。 我将示例转移到unit testing中,以便可以更容易地再现问题。
推理仅限于某些环境,如空间JDK等,或者我遇到了什么问题?
谢谢
这里的示例代码(作为javaunit testing):
import static org.junit.Assert.assertNotNull; import java.io.PrintWriter; import java.util.Iterator; import org.junit.Before; import org.junit.Test; import com.hp.hpl.jena.rdf.model.InfModel; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.reasoner.Derivation; import com.hp.hpl.jena.reasoner.rulesys.GenericRuleReasoner; import com.hp.hpl.jena.reasoner.rulesys.Rule; import com.hp.hpl.jena.vocabulary.RDFS; public class ReasonerTest { String NS = "urn:x-hp-jena:eg/"; // Build a trivial example data set Model model = ModelFactory.createDefaultModel(); InfModel inf; Resource A = model.createResource(NS + "A"); Resource B = model.createResource(NS + "B"); Resource C = model.createResource(NS + "C"); Resource D = model.createResource(NS + "D"); Property p = model.createProperty(NS, "p"); Property q = model.createProperty(NS, "q"); @Before public void init() { // Some small examples (subProperty) model.add(p, RDFS.subPropertyOf, q); model.createResource(NS + "A").addProperty(p, "foo"); String rules = "[rule1: (?a eg:p ?b) (?b eg:p ?c) -> (?a eg:p ?c)]"; GenericRuleReasoner reasoner = new GenericRuleReasoner(Rule.parseRules(rules)); reasoner.setDerivationLogging(true); inf = ModelFactory.createInfModel(reasoner, model); // Derivations A.addProperty(p, B); B.addProperty(p, C); C.addProperty(p, D); } @Test public void subProperty() { Statement statement = A.getProperty(q); System.out.println("Statement: " + statement); assertNotNull(statement); } @Test public void derivations() { String trace = null; PrintWriter out = new PrintWriter(System.out); for (StmtIterator i = inf.listStatements(A, p, D); i.hasNext(); ) { Statement s = i.nextStatement(); System.out.println("Statement is " + s); for (Iterator id = inf.getDerivation(s); id.hasNext(); ) { Derivation deriv = (Derivation) id.next(); deriv.printTrace(out, true); trace += deriv.toString(); } } out.flush(); assertNotNull(trace); } @Test public void listStatements() { StmtIterator stmtIterator = inf.listStatements(); while(stmtIterator.hasNext()) { System.out.println(stmtIterator.nextStatement()); } } }
前缀例如:不是你认为的那样:
规则中的eg:
前缀不会扩展到您的想法。 我将你的规则字符串修改为
String rules = "[rule1: (?a eg:p ?b) (?b eg:p ?c) -> (?a eg:p ?c)] [rule2: -> ( eg:foo )]";
因此rule2将始终插入三元组:ex:a eg:foo urn:ex:b into the graph。 然后,测试的输出包括:
[urn:ex:a, urn:x-hp:eg/foo, urn:ex:b] [urn:x-hp-jena:eg/C, urn:x-hp-jena:eg/p, urn:x-hp-jena:eg/D]
第一行显示我的rule2插入的三元组,而第二行使用您手动输入的前缀。 我们看到eg:
前缀是urn:x-hp:eg/
缩写urn:x-hp:eg/
。 如果相应地更改了NS字符串,则使用String NS = "urn:x-hp:eg/";
,那么你的推导测试将通过。
你需要问正确的模型
subProperty测试失败有两个原因。 首先,它正在检查错误的模型。
你正在检查A.getProperty(q)
:
Statement statement = A.getProperty(q); System.out.println("Statement: " + statement); assertNotNull(statement);
A
是您为模型model
创建的资源,而不是模型inf
,因此当您要求A.getProperty(q)
,它实际上是在询问model
的语句,因此您不会在inf
看到推论。 您可以使用inModel
获取A
“in inf
”,以便getProperty
查找正确的模型:
Statement statement = A.inModel(inf).getProperty(q);
或者,您也可以直接询问inf
是否包含A q
forms的三元组:
inf.contains( A, q, (RDFNode) null );
或者你可以列举所有这些陈述:
StmtIterator stmts = inf.listStatements( A, q, (RDFNode) null ); assertTrue( stmts.hasNext() ); while ( stmts.hasNext() ) { System.out.println( "Statement: "+stmts.next() ); }
你也需要RDFS推理
即使您正在查询正确的模型,您的推理模型仍然需要进行RDFS推理以及使属性p传递的自定义规则。 为此,我们可以从RDFS推理器中取出规则,将规则添加到该列表的副本,然后使用新的规则列表创建自定义推理器:
// Get an RDFS reasoner GenericRuleReasoner rdfsReasoner = (GenericRuleReasoner) ReasonerRegistry.getRDFSReasoner(); // Steal its rules, and add one of our own, and create a // reasoner with these rules List customRules = new ArrayList<>( rdfsReasoner.getRules() ); String customRule = "[rule1: (?a eg:p ?b) (?b eg:p ?c) -> (?a eg:p ?c)]"; customRules.add( Rule.parseRule( customRule )); Reasoner reasoner = new GenericRuleReasoner( customRules );
完整的结果
这是修改后的代码,一起用于轻松复制和粘贴。 所有的测试都通过了。
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.junit.Before; import org.junit.Test; import com.hp.hpl.jena.rdf.model.InfModel; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.reasoner.Derivation; import com.hp.hpl.jena.reasoner.Reasoner; import com.hp.hpl.jena.reasoner.ReasonerRegistry; import com.hp.hpl.jena.reasoner.rulesys.GenericRuleReasoner; import com.hp.hpl.jena.reasoner.rulesys.Rule; import com.hp.hpl.jena.vocabulary.RDFS; public class ReasonerTest { String NS = "urn:x-hp:eg/"; // Build a trivial example data set Model model = ModelFactory.createDefaultModel(); InfModel inf; Resource A = model.createResource(NS + "A"); Resource B = model.createResource(NS + "B"); Resource C = model.createResource(NS + "C"); Resource D = model.createResource(NS + "D"); Property p = model.createProperty(NS, "p"); Property q = model.createProperty(NS, "q"); @Before public void init() { // Some small examples (subProperty) model.add(p, RDFS.subPropertyOf, q); A.addProperty(p, "foo" ); // Get an RDFS reasoner GenericRuleReasoner rdfsReasoner = (GenericRuleReasoner) ReasonerRegistry.getRDFSReasoner(); // Steal its rules, and add one of our own, and create a // reasoner with these rules List customRules = new ArrayList<>( rdfsReasoner.getRules() ); String customRule = "[rule1: (?a eg:p ?b) (?b eg:p ?c) -> (?a eg:p ?c)]"; customRules.add( Rule.parseRule( customRule )); Reasoner reasoner = new GenericRuleReasoner( customRules ); reasoner.setDerivationLogging(true); inf = ModelFactory.createInfModel(reasoner, model); // Derivations A.addProperty(p, B); B.addProperty(p, C); C.addProperty(p, D); } @Test public void subProperty() { StmtIterator stmts = inf.listStatements( A, q, (RDFNode) null ); assertTrue( stmts.hasNext() ); while ( stmts.hasNext() ) { System.out.println( "Statement: "+stmts.next() ); } } @Test public void derivations() { String trace = null; PrintWriter out = new PrintWriter(System.out); for (StmtIterator i = inf.listStatements(A, p, D); i.hasNext(); ) { Statement s = i.nextStatement(); System.out.println("Statement is " + s); for (Iterator id = inf.getDerivation(s); id.hasNext(); ) { Derivation deriv = (Derivation) id.next(); deriv.printTrace(out, true); trace += deriv.toString(); } } out.flush(); assertNotNull(trace); } @Test public void listStatements() { StmtIterator stmtIterator = inf.listStatements(); while(stmtIterator.hasNext()) { System.out.println(stmtIterator.nextStatement()); } } }