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/

Reply via email to