tags:

views:

224

answers:

2

I'm getting a strange effect in Jena 2.5.5 (on linux) where I am playing around with the inference API. The following code is a stripped down version.

I am creating an initially empty Model and a generic rule reasoner. I add a reflexivity rule for a certain statement. I attach the reasoner to the model to get an InfModel. Then I create the matching statement and add it to the Model.

Result: InfModel contains both the statement and its reverse. So far so good, that's what it's supposed to do.

Now, when I System.out.println() the InfModel prior to adding the matching statement to Model, the result is completely different: the rule seems not to fire and thus, InfModel will end up not containing the reverse of the original statement.

So, my question is: how does writing the model to the console change the functionality of the code? Is this behavior documented?

Thanks.

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); // (*)
    }
}
A: 

It's likely that model.toString() has side-effects. I have not looked at the JENA source, so I can't be sure, though.

Thanks for the answer - I think it's not only "likely" but also completely obvious that toString() must have side-effects. Which is certainly unexpected, but perhaps my experience with Jena is just too little to know what's going on. In any case, I could not find any documentation of this behavior.
+1  A: 

Had a quick look at the relevant source and it appears that you have two options:

  • If you want to make changes to the base model and then be sure that they propagate to the infModel, then you have to call infModel.rebind() after having made the changes and before you "ask" the infModel anything.

  • You can use the infModel directly (instead of model) to create and add the statement's elements and the statement itself.

I know this does not directly answer your question, but it may solve your problem (which, btw, seems to be caused by reification triggered by the toString() method in ModelCom - the parent class of InfModel).

Alex