1
votes

I am facing a problem extracting the Individual's name from the Jena Graph (RDF Inference Model with Generic Rule Reasoner and OntSpec is RDFS_MEM_RDFS_INF ). It may be a simple case but I am not able to find proper tutorial online to get this done (new to jena rules). What is the proper api to call for in this case?

infStmts = pModel.listStatements().filterKeep( new Filter<Statement>() {
        @Override
        public boolean accept(Statement o) {                
            boolean ex = false;
            Property prop1 = pModel.getProperty(prefix + "hasPropertyP1");
            String predicateName  = o.asTriple().getPredicate().getLocalName();             
            if(predicateName.equalsIgnoreCase(prop1.getLocalName()) )                   
                ex = true;                
            return ex;

        }
    });

    Statement s = infStmts.next();
    Statement st = ResourceFactory.createStatement(s.getSubject(), s.getPredicate(), s.getObject());
    System.out.println(st.getSubject().toString() + "****" + pModel.getRDFNode(st.getSubject().asNode()).as(Individual.class));
Exception in thread "Thread-37" com.hp.hpl.jena.ontology.ConversionException: Cannot convert node 4e62503a:14b01762f42:-7eea to Individual
at com.hp.hpl.jena.ontology.impl.IndividualImpl$1.wrap(IndividualImpl.java:61)
at com.hp.hpl.jena.enhanced.EnhNode.convertTo(EnhNode.java:152)
at com.hp.hpl.jena.enhanced.EnhNode.convertTo(EnhNode.java:31)
at com.hp.hpl.jena.enhanced.Polymorphic.asInternal(Polymorphic.java:62)
at com.hp.hpl.jena.enhanced.EnhNode.as(EnhNode.java:107)
...

The Jena rules file has the following rule

[rule: ( :Subject1 :hasPropertyP2 :Object1) ->
       ( ?x rdf:type :Class1)
       ( ?x :hasPropertyP1 :Object2)]

I need the value of ?x in terms of individuals' names

1
What do you mean by the "Individual name"? The IRI of a named individual? A value of an rdfs:label property? Something else?Joshua Taylor
Yes, IRI of named Individual is what I want.user3747396
It is my understanding that the blank node (en.wikipedia.org/wiki/Blank_node) 4e62503a:14b01762f42:-7eea is holding the required set of individuals satisfying the rule and I would therefore like to retrieve the contained data which in this case is that of those individuals that have the hasPropertyP1 or that the jena rule is to be written such that individuals are retrieved similar to sparql queriesuser3747396
"the blank node 4e62503a:14b01762f42:-7eea is holding the required set of individuals satisfying the rule " This doesn't make sense. A blank node isn't a container, it's just an anonymous resource. It's just like an IRI resource, except that it doesn't have an IRI.Joshua Taylor
If you found a solution to this problem in your newer question, you should consider closing/deleting this one.Joshua Taylor

1 Answers

3
votes

In the following line you're trying to get the the subject, then get a Node version of it, and then get an Individual version of it.

System.out.println(st.getSubject().toString() + "****" + pModel.getRDFNode(st.getSubject().asNode()).as(Individual.class));

You're doing this for the subject of every triple in the graph. The documentation for Individual says:

In order to be recognised as an individual, rather than a generic resource, at least one rdf:type statement, referring to a known class, must be present in the model.

The error message you're getting,

Cannot convert node 4e62503a:14b01762f42:-7eea to Individual

indicates that somewhere in the graph, there's a triple whose subject is a blank node. Apparently one of those blank nodes doesn't meet the criteria for being an Individual. You need to check whether the node can be an Individual before doing as(Individual.class). You can check first with canAs(Individual.class).

However, you need to be aware that just because the rules file only has one rule does not mean that all the triples in the inference graph will have been generated by it. There can be lots more triples in the inference graph.

A better way to do what you're trying to do would be to list the statements with the property that you care about using Model.listStatements, and then check whether the subject is a URI resource, and if is, then get it as a URI resource and extract its URI:

Property p1 = model.createProperty(...)
StmtIterator stmts = model.listStatements(null,p1,null); 
while ( stmts.hasNext() ) {
  Statement stmt = stmts.next();
  RDFNode subject = stmt.getSubject();
  if ( subject.isURIResource() ) {
    System.out.println( "Subject URI is: "+ subject.asResource().getURI() );
  }
}