печать InfModel раньше меняет печатное представление позже? - PullRequest
2 голосов
/ 08 декабря 2008

Я получаю странный эффект в 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 ]

1 голос
/ 12 декабря 2008

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

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

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

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

0 голосов
/ 24 сентября 2013

Прошло несколько лет, и Йена в серии 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 означает, что во втором случае дополнительные предполагаемые тройки доступны во время печати. ​​

0 голосов
/ 09 декабря 2008

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

...