Explain inference in Jena

南楼画角 提交于 2019-12-06 06:51:39

According to the documentation (and testing with Jena 2.11.1) you can get access to a Derivation object which will allow you to create a textual description of what happened. In the following example, we retrieve RuleDerivation objects that expose a little bit more regarding the internal state.

The following is a tested implementation of the documentation example which begins with the following model:

<urn:eg:C>  <urn:eg:p>  <urn:eg:D> .
<urn:eg:B>  <urn:eg:p>  <urn:eg:C> .
<urn:eg:A>  <urn:eg:p>  <urn:eg:B> .

... and the following rule:

[rule1: (?a urn:eg:p ?b) (?b urn:eg:p ?c) -> (?a urn:eg:p ?c)]

... to produce this resulting model:

<urn:eg:B>  <urn:eg:p>  <urn:eg:D> , <urn:eg:C> .
<urn:eg:A>  <urn:eg:p>  <urn:eg:D> , <urn:eg:C> , <urn:eg:B> .
<urn:eg:C>  <urn:eg:p>  <urn:eg:D> .

This basic transitive inference becomes the core aspect of the example to follow. Note that we obtain an instance of RuleDerivation which is a start towards your end goal.

final Resource A = ResourceFactory.createResource("urn:eg:A");
final Resource B = ResourceFactory.createResource("urn:eg:B");
final Resource C = ResourceFactory.createResource("urn:eg:C");
final Resource D = ResourceFactory.createResource("urn:eg:D");
final Property p = ResourceFactory.createProperty("urn:eg:p");

final Model rawData = ModelFactory.createDefaultModel();
rawData.add(A, p, B);
rawData.add(B, p, C);
rawData.add(C, p, D);

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

final 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 (final Iterator<Derivation> id = inf.getDerivation(s); id.hasNext(); ) {
        final RuleDerivation deriv = (RuleDerivation) id.next();
        deriv.printTrace(out, true);
    }
}
out.flush();

The output of this example is:

Statement is [urn:eg:A, urn:eg:p, urn:eg:D]
Rule rule1 concluded (urn:eg:A urn:eg:p urn:eg:D) <-
    Rule rule1 concluded (urn:eg:A urn:eg:p urn:eg:C) <-
        Fact (urn:eg:A urn:eg:p urn:eg:B)
        Fact (urn:eg:B urn:eg:p urn:eg:C)
    Fact (urn:eg:C urn:eg:p urn:eg:D)

EDIT - Tips

Check out the internals of RuleDerivation#printTrace(...) if you are looking for an example about how to explore derivations. If you want to convert a triple (from RuleDerivation#getMatches()) back to a statement, use StatementImpl#toStaetment(Triple,ModelCom).

EDIT2 - Done Assuming that you are using one of Jena's built in rule-based reasoners, the following code will allow you to explore the matches for one particular derivation reported by a reasoner.

final StmtIterator input = inf.listStatements(A, p, D);
assert( input.hasNext() );

final Iterator<Derivation> derivations = inf.getDerivation(input.next());
assert( null != derivations );
assert( derivations.hasNext() );

final RuleDerivation oneDerivation = (RuleDerivation) derivations.next();
final ExtendedIterator< Statement > matches = 
        new NiceIterator< Triple >()
        .andThen( oneDerivation.getMatches().iterator())
        .mapWith( new Map1< Triple, Statement >(){
            @Override
            public Statement map1( final Triple t )
            {
                /* Note that it seems that this model doesn't really mean anything. While
                 * the statement will be associated with the infModel, the triple that led
                 * to the match could have been from either the deductions graph or the
                 * raw graph. This does not actually add any triples to the underlying
                 * store.
                 */
                return StatementImpl.toStatement(t, (ModelCom)inf);
            }});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!