Thanks, to both Chris and Joshua. I had a hunch that this would be the issue, but I thought getting a description from the experts would provide the right information to pass along to him. This was real helpful for our evaluation of Jena.
-----Original Message----- From: Chris Dollin [mailto:[email protected]] Sent: Thursday, March 14, 2013 12:31 PM To: [email protected] Subject: Re: inferencing question On Thursday, March 14, 2013 01:59:03 PM David Jordan wrote: (I shall say "you" to refer to yourself or your colleague indiscriminately) > There is an individual in another organization of my company that is > struggling to get something working in Jena. I have advised him > several times to post his issue to this group, but he won’t. He is > trying to have an instance get dynamically associated with a subclass. > I don’t have the time bandwidth to figure this out for him because I > am busy with my own Jena evaluation work due in about a week. His > issue deals with how/whether Jena does inferencing on the fly. He is > not getting the results he expects. Below is his sample ontology and also the > Jena Java code. His challenge/question is in the comments at the very end of > the code. That InfModel is built on a reasoner which incorporates the data model m (which is built on top of an OntModel which /also/ does inference, likely not a good idea). Inference models do not notice if you update their underlying models, because the designed use case is that you make updates to the inference model and that forwards them to the underlying data model. The underlying model is consulted when the first query, or the first query after a rebind, is made to the inference model. So adding the > bmxRace.addProperty(prop, myCar); property changes the model that bmxrace was created by, which is the model chat bmxclass was created by, which is m; and myCar was created by the model that vehCls was created by/in, which is m: OntModel m = ModelFactory.createOntologyModel(); which does only RDFS inference, which doesn't look like eough to draw the conclusion you want. Iterating through the properties of myCar will show only what's in m. When you then iterate over the statements of /model/, this is the first query over model, so it initialises and consults the underlying model m and does its Pellety thing and gets the answer you desire. So the answer to the challenge is "ask the question of the correct model, and make it easy to know which that one is." It's important in Jena to realise that Resource objects (and Individuals, which are more specialised Resources) are "in" a model, in the sense that questions about their properties will be answered by consulting that model, and that two resources with the same URI can have different collections of properties if they are "in" different models. Chris > package assign; > > import java.io.FileInputStream; > import java.io.IOException; > import java.util.Iterator; > import com.hp.hpl.jena.ontology.*; > import com.hp.hpl.jena.rdf.model.*; > import com.hp.hpl.jena.reasoner.Reasoner; > import com.hp.hpl.jena.reasoner.ReasonerRegistry; > import com.hp.hpl.jena.reasoner.ValidityReport; > import com.hp.hpl.jena.util.PrintUtil; > > public class RefineTest { > public static void main(String[] args) throws IOException { > // load the ontology > OntModel m = ModelFactory.createOntologyModel(); > FileInputStream inStream = new > FileInputStream("ontology/vehicle.owl"); > m.read(inStream, null); > inStream.close(); > // create an OWL reasoner and bind it to the ontology > // Reasoner reasoner = PelletReasonerFactory.theInstance().create(); > Reasoner reasoner = ReasonerRegistry.getOWLReasoner(); > reasoner = reasoner.bindSchema(m); > // create a container for the data, and bind it to the reasoner > Model data = ModelFactory.createDefaultModel(); > InfModel model = ModelFactory.createInfModel(reasoner, data); > // get the Vehicle class. Vehicle has a cardinality restricton on the > // property numWheels > String uriBase = m.getNsPrefixURI(""); > OntClass vehCls = m.getOntClass(uriBase + "Vehicle"); > OntClass bmxClass = m.getOntClass(uriBase + "BmxRace"); > Individual myCar = vehCls.createIndividual(uriBase + "data/myCar"); > Individual bmxRace = > bmxClass.createIndividual(uriBase + "data/bmxRace"); > ObjectProperty prop = m.getObjectProperty(uriBase + "hasRacer"); > System.out.println("Dom " + prop.getDomain() + " Rng: " > + prop.getRange()); > // by specifying that myCar is in the BMX race, it should force myCar > // to be a motorcycle > bmxRace.addProperty(prop, myCar); > // The statements below show that the individual objects do not change > // as a result of > // the property assignment (aside from the assignment itself) > for (StmtIterator sti = myCar.listProperties(); sti.hasNext();) { > Statement st = sti.nextStatement(); > System.out.println(" - " + PrintUtil.print(st)); > } > for (StmtIterator sti = bmxRace.listProperties(); sti.hasNext();) { > Statement st = sti.nextStatement(); > System.out.println(" - " + PrintUtil.print(st)); > } > // By iterating through the model statements though, we show that the > // myCar resource does include Motorcycle as a type > for (StmtIterator sti = > model.listStatements(myCar, null, (RDFNode) null); > sti.hasNext();) { > Statement st = sti.nextStatement(); > System.out.println(" * " + PrintUtil.print(st)); > } > ValidityReport rept = model.validate(); > System.out.println("Rept is Clean: " + rept.isClean() + " valid: " > + rept.isValid()); > for (Iterator<ValidityReport.Report> riter = rept.getReports(); riter > .hasNext();) { > ValidityReport.Report rep = riter.next(); > System.out.println("ValRep: " + rep.getDescription()); > } > // Now the challenge is to get the myCar individual to update with the > // statements > // automatically - I need to show that myCar is a Motorcycle without > // iterating > // through the entire set of statements in the model > } > } > > > -- "I know it was late, but Mountjoy never bothers, /Archer's Goon/ so long as it's the full two thousand words." Epimorphics Ltd, http://www.epimorphics.com Registered address: Court Lodge, 105 High Street, Portishead, Bristol BS20 6PT Epimorphics Ltd. is a limited company registered in England (number 7016688)
