Search code examples
javajenardfsreasoning

Jena RDFS reasoning not returning expected results


I have the following two triples:

<http://example.com/a> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://example.com/b> . 
<http://example.com/b> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://example.com/c> .

And the following Jena code:

Reasoner reasoner = RDFSRuleReasonerFactory.theInstance().create(null);
    reasoner.setParameter(ReasonerVocabulary.PROPsetRDFSLevel, ReasonerVocabulary.RDFS_SIMPLE);
    reasoner.setDerivationLogging(true);

    Model schema = FileManager.get().loadModel(schemaFilepath);
    InfModel infmodel = ModelFactory.createInfModel(reasoner, schema);

    OutputStream output = new FileOutputStream(outputFilepath);
    RDFDataMgr.write(output, infmodel.getDeductionsModel(), RDFFormat.NT);

If I understand the spec right, I should get from getDedunctionsModel():

<http://example.com/a> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://example.com/c> .  

But I am getting an empty set. Any ideas why?


Solution

  • I think that the deductions model is populated on demand, and that it's up to the particular reasoner how it wants to use the deductions model. It's quite possible to only generate some deduced triples when requested, and to not store them in the deductions model. For instance, in the following example, we print the deductions model, then the whole model, then the deductions model again, and we can see that the desired subclass triples only show up when we print the entire model. In general, you should work with the top-level model, not the deductions model, unless you know something about the implementation of the reasoner and what it will use the deductions model for.

    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    import org.apache.jena.riot.RDFDataMgr;
    import org.apache.jena.riot.RDFLanguages;
    
    import com.hp.hpl.jena.ontology.OntModel;
    import com.hp.hpl.jena.ontology.OntModelSpec;
    import com.hp.hpl.jena.rdf.model.ModelFactory;
    
    public class RDFSReasoningExample {
        public static void main(String[] args) throws IOException {
            OntModel model = ModelFactory.createOntologyModel(OntModelSpec.RDFS_MEM_RDFS_INF);
            String content = (""
                    + "@prefix : <urn:ex:>.\n"
                    + "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.\n"
                    + "\n"
                    + ":a rdfs:subClassOf :b .\n"
                    + ":b rdfs:subClassOf :c .\n");
            try ( InputStream in = new ByteArrayInputStream(content.getBytes()) ) {
                RDFDataMgr.read(model, in, RDFLanguages.TTL);
            }
            System.out.println("* Write the deductions model");
            RDFDataMgr.write(System.out, model.getDeductionsModel(), RDFLanguages.NT);
            System.out.println("* Write the model");
            RDFDataMgr.write(System.out, model, RDFLanguages.NT);
            System.out.println("* Write the deductions model again");
            RDFDataMgr.write(System.out, model.getDeductionsModel(), RDFLanguages.NT);
        }
    }
    
    * Write the deductions model
    …nothing about :a, :b, or :c…
    * Write the model
    …
    <urn:ex:a> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <urn:ex:b> .
    <urn:ex:b> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <urn:ex:c> .
    <urn:ex:c> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <urn:ex:c> .
    <urn:ex:a> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <urn:ex:a> .
    <urn:ex:a> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <urn:ex:c> .
    <urn:ex:b> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <urn:ex:b> .
    …
    * Write the deductions model again
    …nothing about :a, :b, or :c…