On Mon, Mar 4, 2013 at 5:25 AM, Bojan Milić <bojan.mi...@gmail.com> wrote: > Dear friends, > > I am developing ontology for supply chain management and I am > encountering some problems regarding Jena API. In my ontology I have > following structure: > > classA > classA1 > classA2 > classA3 > classA4 > classB > classC > classD > > Classes are representing some documents for example (classA = planning > doc, classB = execution doc, etc.). Now I would like to connect > (relationship) these classes with same ObjectProperty. In Jena > Ontology API it sais: In an ontology, a property denotes the name of a > relationship between resources, or between a resource and a data > value. I followed jena api and did the relationship like this > (OntologyPrintscreen.jpg in attachment): > > //let's start some JENA code -- simple default RDF model > String baseURI = InitInfo.getInstance().getDefaultBaseURI(); > > //create ontology model > OntModel processModel = > ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM_TRANS_INF); > > //createResource > Resource r = processModel.createResource(baseURI + "r"); > > > OntClass classA = processModel.createClass(baseURI + > "classA"); > OntClass classB = processModel.createClass(baseURI + > "classB"); > OntClass classC = processModel.createClass(baseURI + > "classC"); > OntClass classD = processModel.createClass(baseURI + > "classD"); > > classA.addSubClass(processModel.createClass(baseURI + > "classA1")); > classA.addSubClass(processModel.createClass(baseURI + > "classA2")); > classA.addSubClass(processModel.createClass(baseURI + > "classA3")); > classA.addSubClass(processModel.createClass(baseURI + > "classA4")); > > OntClass classA1 = processModel.getOntClass(baseURI + > "classA1"); > OntClass classA2 = processModel.getOntClass(baseURI + > "classA2"); > OntClass classA3 = processModel.getOntClass(baseURI + > "classA3"); > OntClass classA4 = processModel.getOntClass(baseURI + > "classA4"); > > ObjectProperty uses = > processModel.createObjectProperty(baseURI + "uses"); > ObjectProperty creates = > processModel.createObjectProperty(baseURI + > "creates"); > > creates.addDomain(classA1); > creates.addRange(classA2); > > uses.addDomain(classA1); > uses.addRange(classB); > > My problem: I would like to use same objectProperty (uses and creates) > to model relationship between my classes. For example: > classA1 uses classB > classA1 creates classA2 > classA2 creates classA3 > classA3 uses classD > classA4 creates classC > > There is a desired look (what I would like to achieve) with jena api > (OntologyDesired.jpg). I've already tried: > creates.addDomain(classA2); > creates.addRange(classA3); > > uses.addDomain(classA3); > uses.addRange(classD); > But statements get disregarded. > > Can you please help me model relationships between these classes with > same ObjectProperty, is this even possible? With protege API you can > do this: > OWLObjectProperty childrenProperty = > owlModel.createOWLObjectProperty("children"); > childrenProperty.addUnionRangeClass(personClass); > childrenProperty.addUnionRangeClass(animalClass); > > Is something like that possible with Jena, I haven't found anything on > the web, so you are my final chance :)
If I understand you correctly, the problem you're having is like the following: Classes Car CarFactory Boat BoatFactor Properties creates and what you'd like to enforce is that whenever you have a statement [x, creates, y] either x is a CarFactory and y is a Car, or x is a BoatFactory and y is a Boat . The way to do this is *not* adding CarFactory and BoatFactory as domains of creates, as this means that any x such that [x creates y] is *both* a CarFactory and a BoatFactory. The way to do this is *not* to set (CarFactory OR BoatFactory) as the domain of creates, as this means that any x such that [x creates y] is *either* a CarFactory or a BoatFactory, without any regard to whether y is a Car or a Boat. The way to do this is to add some restriction superclasses to CarFactory and BoatFactory that restrict the way that the property creates will be used for them: CarFactory isSubClassOf (creates only Car) BoatFactory isSubClassOf (creates only Boat) This will ensure that whenever [x creates y]: if x is a CarFactory then y is a Car; and if x is a BoatFactory then y is a Boat. Here's some code that illustrates this: public class JenaTest { public static void main(String[] args) { String NS = "http://example.com/factories#"; OntModel model = ModelFactory.createOntologyModel( OntModelSpec.OWL_DL_MEM_RULE_INF ); OntClass Car = model.createClass( NS+"Car" ); OntClass Boat = model.createClass( NS+"Boat"); OntClass BoatFactory = model.createClass( NS+"BoatFactory" ); OntClass CarFactory = model.createClass( NS+"CarFactory" ); OntProperty creates = model.createOntProperty( NS+"creates" ); BoatFactory.addSuperClass( model.createAllValuesFromRestriction( null, creates, Boat )); CarFactory.addSuperClass( model.createAllValuesFromRestriction( null, creates, Car )); Individual bf = model.createIndividual( NS+"someBoatFactory", BoatFactory ); Individual cf = model.createIndividual( NS+"someCarFactory", CarFactory ); Individual x = model.createIndividual( NS+"creature1", OWL.Thing ); Individual y = model.createIndividual( NS+"creature2", OWL.Thing ); bf.addProperty( creates, x ); cf.addProperty( creates, y ); for ( Individual i : new Individual[] { x, y } ) { ExtendedIterator<Resource> it = i.listRDFTypes( false ); while( it.hasNext() ) { System.out.println( i+" has type "+it.next() ); } } } } The output is: http://example.com/factories#creature1 has type http://www.w3.org/2002/07/owl#Thing http://example.com/factories#creature1 has type http://example.com/factories#Boat http://example.com/factories#creature1 has type http://www.w3.org/2000/01/rdf-schema#Resource http://example.com/factories#creature2 has type http://www.w3.org/2002/07/owl#Thing http://example.com/factories#creature2 has type http://example.com/factories#Car http://example.com/factories#creature2 has type http://www.w3.org/2000/01/rdf-schema#Resource Hope this helps! //JT -- Joshua Taylor, http://www.cs.rpi.edu/~tayloj/