Объясните вывод в Йене

В Йене я создал модель логического вывода RDFS, используя класс InfModel:

InfModel infmodel = ModelFactory.createRDFSModel(schema, data);

Имея вывод, полученный из infmodel, как мы можем получить два утверждения, которые использовались для его вывода, подобно опции «объяснить вывод» в Protégé? Например, если infModel содержит оператор :a rdf:type :t, мы можем получить два оператора, используемых для его вывода, например, :a :p :b и :p rdfs:domain :t.


person riad    schedule 21.04.2014    source источник


Ответы (1)


Согласно документации (и тестированию с помощью Jena 2.11.1) вы можете получить доступ к объект Derivation, который будет позволяют создать текстовое описание того, что произошло. В следующем примере мы получаем RuleDerivation объекты, раскрывающие немного больше информации о внутреннем состоянии.

Ниже приведена проверенная реализация примера документации, которая начинается со следующей модели:

<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> .

... и следующее правило:

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

... для создания этой результирующей модели:

<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> .

Этот базовый переходный вывод становится основным аспектом примера для подражания. Обратите внимание, что мы получаем экземпляр RuleDerivation, который является началом вашей конечной цели.

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

Результат этого примера:

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)

ИЗМЕНИТЬ — Советы

Ознакомьтесь с внутренностями RuleDerivation#printTrace(...), если вы ищете пример того, как изучить производные. Если вы хотите преобразовать тройку (из RuleDerivation#getMatches()) обратно в оператор, используйте StatementImpl#toStaetment(Triple,ModelCom).

EDIT2 – Готово Если вы используете один из встроенных в Jena алгоритмов рассуждений на основе правил, следующий код позволит вам исследовать совпадения для одного конкретного деривации, о котором сообщает ризонер.

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);
            }});
person Rob Hall    schedule 21.04.2014
comment
есть ли способ создать правило, включающее математические операции, такие как сумма или вычитание? - person KeyPi; 26.05.2015
comment
Да, например, вы можете использовать sum и difference для создания таких правил. - person Rob Hall; 26.05.2015
comment
@RobHall, что такое Map1? Не удается скомпилировать ваш код из-за этого неизвестного класса. - person Martynas Jusevičius; 18.06.2020
comment
Это компилирует: .mapWith( t -> StatementImpl.toStatement(t, (ModelCom)inf)); - person Martynas Jusevičius; 18.06.2020
comment
com.hp.hpl.jena.util.iterator.Map1 больше не существует . С тех пор Apache Jena устарела и удалила функциональность, от которой отказались потоки Java. Как вы продемонстрировали, NiceIterator.mapWith(...) теперь просто принимает java.util.function.Function, который может быть предоставлен лямбда-выражением. - person Rob Hall; 17.07.2020