Печать InfModel раньше меняет печатное представление позже?

Я получаю странный эффект в Jena 2.5.5 (в Linux), где я играю с API вывода. Следующий код является урезанной версией. Я создаю изначально пустую модель и обобщение общих правил. Я добавляю правило рефлексивности для определенного утверждения. Я присоединяю модель к модели, чтобы получить InfModel. Затем я создаю соответствующий оператор и добавляю его в модель.

Результат: InfModel содержит как инструкцию, так и ее реверс. Пока все хорошо, это то, что он должен делать.

Теперь, когда я System.out.println() InfModel до добавления соответствующего оператора в Model, результат совершенно другой: кажется, что правило не срабатывает, и, таким образом, InfModel в итоге не будет содержать реверс исходного оператора.

Как запись модели в консоль изменяет функциональность кода? Это поведение задокументировано?

import java.util.*;

import com.hp.hpl.jena.rdf.model.*;
import com.hp.hpl.jena.reasoner.rulesys.*;

/**
 * Describe class <code>RuleTest</code> here.
 */
public class RuleTest {
    public static void main(String[] args) throws Exception {
        /* create model */
        Model model = ModelFactory.createDefaultModel();

        /* output model */
        System.out.println("original model : " + model);
        System.out.println("-----");

        /* collect rules */
        List<Rule> rules = new ArrayList<Rule>();
        Rule rule = Rule.parseRule("[ (subject predicate object) -> (object predicate subject) ].");
        rules.add(rule);

        /* create rule reasoner */
        GenericRuleReasoner reasoner = new GenericRuleReasoner(rules);

        /* attach reasoner to model */
        InfModel infModel = ModelFactory.createInfModel(reasoner, model);

        /* output model */
        //-----------------------------------------------//
        // commenting the following line in/out changes  //
        // the output of (*) below in Jena 2.5.5 ?!?!?!  //
        //-----------------------------------------------//
        //System.out.println("inference model: " + infModel);        
        System.out.println("=====");

        /* add facts to original model */
        Resource s = model.createResource("subject");
        Property p = model.createProperty("predicate");
        RDFNode  o = model.createResource("object");
        Statement stmt = model.createStatement(s, p, o);
        model.add(stmt);

        /* output models */
        System.out.println("original model : " + model);
        System.out.println("-----");
        System.out.println("inference model: " + infModel); // (*)
    }
}

3 ответа

Быстро взглянул на соответствующий источник, и оказалось, что у вас есть два варианта:

  • Если вы хотите внести изменения в базовую модель, а затем быть уверенным, что они распространяются на infModel, то вы должны вызвать infModel.rebind() после внесения изменений и до того, как вы что-то спросите у infModel.

  • Вы можете использовать infModel напрямую (вместо модели) для создания и добавления элементов оператора и самого оператора.

Я знаю, что это не дает прямого ответа на ваш вопрос, но может решить вашу проблему (которая, между прочим, кажется, вызвана реификацией, вызванной методом toString() в ModelCom - родительском классе InfModel).

Вполне вероятно, что model.toString() имеет побочные эффекты. Я не смотрел на источник JENA, поэтому я не уверен, хотя.

Прошло уже несколько лет, и Йена в серии 2.10.x. Когда указанная строка закомментирована, результат вашей программы:

original model : <ModelCom   {} | >
-----
=====
original model : <ModelCom   {subject @predicate object} |  [subject, predicate, object]>
-----
inference model: <ModelCom   {object @predicate subject; subject @predicate object} |  [object, predicate, subject] [subject, predicate, object]>

и строковое представление InfModel содержит две тройки. Когда строка не закомментирована, вывод:

original model : <ModelCom   {} | >
-----
inference model: <ModelCom   {} | >
=====
original model : <ModelCom   {subject @predicate object} |  [subject, predicate, object]>
-----
inference model: <ModelCom   {subject @predicate object} |  [subject, predicate, object]>

и второе строковое представление InfModel имеет только одну тройку, поэтому разница все еще наблюдается. (Я включил вывод здесь, потому что в вопросе не ясно, какая разница наблюдалась.)

Короткий ответ заключается в том, что это происходит потому, что вы подлый и изменяющий model не говоря infModel что вы изменили базовый model, Чтобы решить эту проблему, вы должны добавить вызов infModel.rebind(); после обновления model, То есть вы бы сейчас имели:

model.add(stmt);
infModel.rebind();

Когда вы сделаете это, вы получите одинаковый результат в обоих случаях. С комментариями:

original model : <ModelCom   {} | >
-----
=====
original model : <ModelCom   {subject @predicate object} |  [subject, predicate, object]>
-----
inference model: <ModelCom   {object @predicate subject; subject @predicate object} |  [object, predicate, subject] [subject, predicate, object]>

С строкой без комментариев:

original model : <ModelCom   {} | >
-----
inference model: <ModelCom   {} | >
=====
original model : <ModelCom   {subject @predicate object} |  [subject, predicate, object]>
-----
inference model: <ModelCom   {object @predicate subject; subject @predicate object} |  [object, predicate, subject] [subject, predicate, object]>

Я предполагаю, что написание строкового представления InfModel не приводит к выполнению какого-либо вывода, если оно еще не выполнено, а затем печатает базовую модель и затем любые дополнительные тройки, которые были выведены. В следствии:

  • В первом случае (когда вы печатаете infModel только один раз) он еще не сделал никакого вывода, поэтому он консультируется model и делает соответствующий вывод и получает дополнительные тройки. Тогда это печатает modelТройной, а затем предполагаемый тройной.
  • Во втором случае (когда вы печатаете infModel дважды), первый раз вы печатаете infModelконсультируется model и делает некоторые выводы, но model пусто, поэтому нет дополнительных троек, а затем он печатает modelЭто тройки и дополнительные предполагаемые тройки (их нет). Затем во второй раз infModel печатается, вывод уже выполнен, поэтому печатает modelэто тройки (но есть лишние) и любые предполагаемые тройки (их нет, потому что больше не делали вывод).

Призыв к rebind() после добавления троек к model означает, что во втором случае дополнительные предполагаемые тройки доступны во время печати.

Другие вопросы по тегам