2 votes

Impression Les modifications antérieures du modèle Inf ont-elles été imprimées plus tard?

Je rencontre un effet étrange dans Jena 2.5.5 (sur Linux) où je joue avec l'API d'inférence. Le code suivant est une version simplifiée. Je crée un Model initialement vide et un raisonneur de règles générique. J'ajoute une règle de réflexivité pour une certaine déclaration. J'attache le raisonneur au modèle pour obtenir un InfModel. Ensuite, je crée la déclaration correspondante et l'ajoute au Modèle.

Résultat : InfModel contient à la fois la déclaration et son inverse. Jusque-là tout va bien, c'est ce qu'il est censé faire.

Maintenant, lorsque je System.out.println() l'InfModel avant d'ajouter la déclaration correspondante au Modèle, le résultat est complètement différent : la règle semble ne pas se déclencher et donc, InfModel ne contiendra pas l'inverse de la déclaration originale.

Comment l'écriture du modèle dans la console change-t-elle le fonctionnement du code ? Ce comportement est-il documenté ?

import java.util.*;

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

/**
 * Décrire la classe RuleTest ici.
 */
public class RuleTest {
    public static void main(String[] args) throws Exception {
        /* créer un modèle */
        Model model = ModelFactory.createDefaultModel();

        /* modèle de sortie */
        System.out.println("modèle d'origine : " + model);
        System.out.println("-----");

        /* collecte de règles */
        List rules = new ArrayList();
        Rule rule = Rule.parseRule("[ (subject predicate object) -> (object predicate subject) ].");
        rules.add(rule);

        /* créer un raisonneur de règles */
        GenericRuleReasoner reasoner = new GenericRuleReasoner(rules);

        /* attacher le raisonneur au modèle */
        InfModel infModel = ModelFactory.createInfModel(reasoner, model);

        /* modèle de sortie */
        //-----------------------------------------------//
        // commenter la ligne suivante change          //
        // la sortie de (*) ci-dessous dans Jena 2.5.5  //
        //-----------------------------------------------//
        //System.out.println("modèle d'inférence : " + infModel);        
        System.out.println("=====");

        /* ajouter des faits au modèle d'origine */
        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);

        /* modèles de sortie */
        System.out.println("modèle d'origine : " + model);
        System.out.println("-----");
        System.out.println("modèle d'inférence : " + infModel); // (*)
    }
}

1voto

Un rapide regard sur la source pertinente semble indiquer que vous avez deux options :

  • Si vous souhaitez apporter des modifications au modèle de base et vous assurer qu'elles se propagent à l'infModel, vous devez appeler infModel.rebind() après avoir apporté les modifications et avant de "demander" quoi que ce soit à l'infModel.

  • Vous pouvez utiliser directement l'infModel (au lieu du modèle) pour créer et ajouter les éléments de l'énoncé et l'énoncé lui-même.

Je sais que cela ne répond pas directement à votre question, mais cela pourrait résoudre votre problème (qui, soit dit en passant, semble être causé par la réification déclenchée par la méthode toString() dans ModelCom - la classe parente de InfModel).

0voto

Il est probable que model.toString() ait des effets secondaires. Je n'ai pas regardé le code source de JENA, donc je ne peux pas être sûr, cependant.

0voto

Joshua Taylor Points 29737

C'est maintenant quelques années plus tard et Jena se trouve dans la série 2.10.x. Lorsque la ligne indiquée est commentée, la sortie de votre programme est :

modèle d'origine : 
-----
=====
modèle d'origine : 
-----
modèle d'inférence : 

et la représentation en chaîne de caractères de InfModel contient deux triplets. Lorsque la ligne est décommentée, la sortie est :

modèle d'origine : 
-----
modèle d'inférence : 
=====
modèle d'origine : 
-----
modèle d'inférence : 

et la seconde représentation en chaîne de caractères de InfModel ne contient qu'un triplet, donc la différence est toujours observée. (J'ai inclus la sortie ici, car dans la question il n'est pas claire quelle différence était observée.)

La réponse courte est que cela se produit car vous êtes sournois et que vous modifiez model sans dire à infModel que vous avez changé le model sous-jacent. Pour remédier à cela, vous devriez ajouter un appel à infModel.rebind(); après avoir mis à jour model. Ainsi, vous auriez maintenant :

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

Si vous faites cela, vous obtiendrez la même sortie dans les deux cas. Avec la ligne commentée :

modèle d'origine : 
-----
=====
modèle d'origine : 
-----
modèle d'inférence : 

Avec la ligne décommentée :

modèle d'origine : 
-----
modèle d'inférence : 
=====
modèle d'origine : 
-----
modèle d'inférence : 

Ma supposition ici est que l'écriture de la représentation en chaîne de caractères de InfModel n'entraîne aucune inférence à moins qu'aucune inférence n'ait déjà été effectuée, puis imprime le modèle sous-jacent puis tout triplet supplémentaire qui est inféré. Par conséquent :

  • Dans le premier cas (lorsque vous imprimez infModel une seule fois), aucune inférence n'a encore été effectuée, donc il consulte model et effectue l'inférence appropriée et obtient les triplets supplémentaires. Ensuite, il imprime les triplets de model puis les triplets inférés.
  • Dans le deuxième cas (lorsque vous imprimez infModel deux fois), la première fois que vous imprimez infModel, il consulte model et effectue une certaine inférence, mais model est vide, donc il n'y a pas de triplets supplémentaires, puis il imprime les triplets de model et les triplets inférés supplémentaires (il n'y en a pas). Ensuite, la deuxième fois que infModel est imprimé, l'inférence a déjà été effectuée, donc il imprime les triplets de model (mais il y en a un en plus) et les triplets inférés (il n'y en a pas, car aucune autre inférence n'a été effectuée).

L'appel à rebind() après avoir ajouté des triplets à model signifie que dans le deuxième cas, les triplets inférés supplémentaires sont disponibles au moment de l'impression.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X