Search code examples
rdfsparqlowlontology

Request to determine the quantity of a specific members in several classes linked together with a multiplier


I've made a simplified example of my ontology in RDF/XML format. It's at the end of the question. I work with Protégé 5.0 beta.

Picture that explains my request: enter image description here

I sum short:

  • two level1 class : process, products

  • three sub Class Of process : process_1, process_2, process_3

  • each process has many own members which are linked to products members with a property input or output

  • each members of process_n has data property called quantity.

If you could help me for the syntax it could be nice, but mostly it's on the reasoning I need help.

Ontology (RDF/XML)

<?xml version="1.0"?>


<!DOCTYPE rdf:RDF [
<!ENTITY owl "http://www.w3.org/2002/07/owl#" >
<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
<!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >
<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
<!ENTITY untitled-ontology-14 "http://www.semanticweb.org/francocy/ontologies/2015/1/untitled-ontology-14#" >
]>


<rdf:RDF xmlns="http://www.semanticweb.org/francocy/ontologies/2015/1/untitled-ontology-14#"
 xml:base="http://www.semanticweb.org/francocy/ontologies/2015/1/untitled-ontology-14"
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns:owl="http://www.w3.org/2002/07/owl#"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
 xmlns:untitled-ontology-14="http://www.semanticweb.org/francocy/ontologies/2015/1/untitled-ontology-14#"
 xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<owl:Ontology rdf:about="http://www.semanticweb.org/francocy/ontologies/2015/1/untitled-ontology-14"/>

<owl:ObjectProperty rdf:about="&untitled-ontology-14;input"/>

<owl:ObjectProperty rdf:about="&untitled-ontology-14;output">
    <rdf:type rdf:resource="&owl;FunctionalProperty"/>
</owl:ObjectProperty>

<owl:DatatypeProperty rdf:about="&untitled-ontology-14;quantity"/>

<owl:Class rdf:about="&untitled-ontology-14;process"/>

<owl:Class rdf:about="&untitled-ontology-14;process_1">
    <rdfs:subClassOf rdf:resource="&untitled-ontology-14;process"/>
</owl:Class>

<owl:Class rdf:about="&untitled-ontology-14;process_2">
    <rdfs:subClassOf rdf:resource="&untitled-ontology-14;process"/>
</owl:Class>

<owl:Class rdf:about="&untitled-ontology-14;process_3">
    <rdfs:subClassOf rdf:resource="&untitled-ontology-14;process"/>
</owl:Class>

<owl:Class rdf:about="&untitled-ontology-14;products"/>

<owl:NamedIndividual rdf:about="&untitled-ontology-14;input_1_of_process_1">
    <rdf:type rdf:resource="&untitled-ontology-14;process_1"/>
    <quantity rdf:datatype="&xsd;integer">5</quantity>
    <input rdf:resource="&untitled-ontology-14;product_2"/>
</owl:NamedIndividual>

<owl:NamedIndividual rdf:about="&untitled-ontology-14;input_1_of_process_2">
    <rdf:type rdf:resource="&untitled-ontology-14;process_2"/>
    <quantity rdf:datatype="&xsd;integer">3</quantity>
    <input rdf:resource="&untitled-ontology-14;product_4"/>
</owl:NamedIndividual>

<owl:NamedIndividual rdf:about="&untitled-ontology-14;input_1_of_process_3">
    <rdf:type rdf:resource="&untitled-ontology-14;process_3"/>
    <quantity rdf:datatype="&xsd;integer">2</quantity>
    <input rdf:resource="&untitled-ontology-14;product_2"/>
</owl:NamedIndividual>

<owl:NamedIndividual rdf:about="&untitled-ontology-14;input_2_of_process_1">
    <rdf:type rdf:resource="&untitled-ontology-14;process_1"/>
    <quantity rdf:datatype="&xsd;integer">2</quantity>
    <input rdf:resource="&untitled-ontology-14;product_3"/>
</owl:NamedIndividual>

<owl:NamedIndividual rdf:about="&untitled-ontology-14;input_2_of_process_2">
    <rdf:type rdf:resource="&untitled-ontology-14;process_2"/>
    <quantity rdf:datatype="&xsd;integer">10</quantity>
    <input rdf:resource="&untitled-ontology-14;product_5"/>
</owl:NamedIndividual>

<owl:NamedIndividual rdf:about="&untitled-ontology-14;input_2_of_process_3">
    <rdf:type rdf:resource="&untitled-ontology-14;process_3"/>
    <quantity rdf:datatype="&xsd;integer">3</quantity>
    <input rdf:resource="&untitled-ontology-14;product_4"/>
</owl:NamedIndividual>

<owl:NamedIndividual rdf:about="&untitled-ontology-14;output_1_of_process_1">
    <rdf:type rdf:resource="&untitled-ontology-14;process_1"/>
    <quantity rdf:datatype="&xsd;integer">1</quantity>
    <output rdf:resource="&untitled-ontology-14;product_1"/>
</owl:NamedIndividual>

<owl:NamedIndividual rdf:about="&untitled-ontology-14;output_1_of_process_2">
    <rdf:type rdf:resource="&untitled-ontology-14;process_2"/>
    <quantity rdf:datatype="&xsd;integer">1</quantity>
    <output rdf:resource="&untitled-ontology-14;product_2"/>
</owl:NamedIndividual>

<owl:NamedIndividual rdf:about="&untitled-ontology-14;output_1_of_process_3">
    <rdf:type rdf:resource="&untitled-ontology-14;process_3"/>
    <quantity rdf:datatype="&xsd;integer">1</quantity>
    <output rdf:resource="&untitled-ontology-14;product_3"/>
</owl:NamedIndividual>

<owl:NamedIndividual rdf:about="&untitled-ontology-14;product_1">
    <rdf:type rdf:resource="&untitled-ontology-14;products"/>
</owl:NamedIndividual>

<owl:NamedIndividual rdf:about="&untitled-ontology-14;product_2">
    <rdf:type rdf:resource="&untitled-ontology-14;products"/>
</owl:NamedIndividual>

<owl:NamedIndividual rdf:about="&untitled-ontology-14;product_3">
    <rdf:type rdf:resource="&untitled-ontology-14;products"/>
</owl:NamedIndividual>

<owl:NamedIndividual rdf:about="&untitled-ontology-14;product_4">
    <rdf:type rdf:resource="&untitled-ontology-14;products"/>
</owl:NamedIndividual>

<owl:NamedIndividual rdf:about="&untitled-ontology-14;product_5">
    <rdf:type rdf:resource="&untitled-ontology-14;products"/>
</owl:NamedIndividual>
</rdf:RDF>

Solution

  • Thank you for so much cleaning and reworking of your ontology. However, I still don't think it's a good way to capture what you're trying to express. For instance your ontology includes, in N3 notation):

    untitled-ontology-14:input_2_of_process_1
            a                              owl:NamedIndividual , untitled-ontology-14:process_1 ;
            untitled-ontology-14:input     untitled-ontology-14:product_3 ;
            untitled-ontology-14:quantity  2 .
    
    untitled-ontology-14:input_1_of_process_1
            a                              owl:NamedIndividual , untitled-ontology-14:process_1 ;
            untitled-ontology-14:input     untitled-ontology-14:product_2 ;
            untitled-ontology-14:quantity  5 .
    
    untitled-ontology-14:output_1_of_process_1
            a                              owl:NamedIndividual , untitled-ontology-14:process_1 ;
            untitled-ontology-14:output    untitled-ontology-14:product_1 ;
            untitled-ontology-14:quantity  1 .
    

    These are three instances of the class process_1. I don't think it makes sense that these are instances of a class called process_1.

    Rather, I think that there is some distinct process, and it happens to have two inputs and one output. Each input and output is a pair of a quantity and a particular product.

    I'd represent your processes with something like this in N3 or RDF/XML. (I'm going to work in pure RDF for the moment; translating to OWL is just a matter of declaring some classes and properties; this is question about SPARQL, after all, and SPARQL is an RDF query language.)

    @prefix : <urn:ex:> .
    
    :process1 a :Process ;
              :hasInput  [ a :Measure ; :quantity 2 ; :product :product3 ] ,
                         [ a :Measure ; :quantity 5 ; :product :product2 ] ;
              :hasOutput [ a :Measure ; :quantity 1 ; :product :product1 ] .
    
    :process2 a :Process ;
              :hasInput  [ a :Measure ; :quantity  3 ; :product :product4 ] ,
                         [ a :Measure ; :quantity 10 ; :product :product5 ] ;
              :hasOutput [ a :Measure ; :quantity  1 ; :product :product2 ] .
    
    :process3 a :Process ;
              :hasInput  [ a :Measure ; :quantity 2 ; :product :product2 ] ,
                         [ a :Measure ; :quantity 3 ; :product :product4 ] ;
              :hasOutput [ a :Measure ; :quantity 1 ; :product :product3 ] .
    
    <rdf:RDF
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns="urn:ex:">
      <Process rdf:about="urn:ex:process3">
        <hasInput>
          <Measure>
            <quantity rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
            >2</quantity>
            <product rdf:resource="urn:ex:product2"/>
          </Measure>
        </hasInput>
        <hasInput>
          <Measure>
            <quantity rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
            >3</quantity>
            <product rdf:resource="urn:ex:product4"/>
          </Measure>
        </hasInput>
        <hasOutput>
          <Measure>
            <quantity rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
            >1</quantity>
            <product rdf:resource="urn:ex:product3"/>
          </Measure>
        </hasOutput>
      </Process>
      <Process rdf:about="urn:ex:process2">
        <hasInput>
          <Measure>
            <quantity rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
            >3</quantity>
            <product rdf:resource="urn:ex:product4"/>
          </Measure>
        </hasInput>
        <hasInput>
          <Measure>
            <quantity rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
            >10</quantity>
            <product rdf:resource="urn:ex:product5"/>
          </Measure>
        </hasInput>
        <hasOutput>
          <Measure>
            <quantity rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
            >1</quantity>
            <product rdf:resource="urn:ex:product2"/>
          </Measure>
        </hasOutput>
      </Process>
      <Process rdf:about="urn:ex:process1">
        <hasInput>
          <Measure>
            <quantity rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
            >2</quantity>
            <product rdf:resource="urn:ex:product3"/>
          </Measure>
        </hasInput>
        <hasInput>
          <Measure>
            <quantity rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
            >5</quantity>
            <product rdf:resource="urn:ex:product2"/>
          </Measure>
        </hasInput>
        <hasOutput>
          <Measure>
            <quantity rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
            >1</quantity>
            <product rdf:resource="urn:ex:product1"/>
          </Measure>
        </hasOutput>
      </Process>
    </rdf:RDF>
    

    This doesn't solve the problem, of course, and I'm not sure whether you can do all the computation you want with SPARQL, especially when there are multiple ways to produce various products, but you can at least start to write queries like this that will help you to figure out what you need to produce things, and which processes can help:

    prefix : <urn:ex:>
    
    select * where {
     ?process :hasOutput [ :quantity ?q ; :product :product1 ] ;
              :hasInput [ :quantity ?inputq ; :product ?input ] .
     ?input ^:product/^:hasOutput ?subprocess          
    }
    
    ---------------------------------------------------
    | process   | q | inputq | input     | subprocess |
    ===================================================
    | :process1 | 1 | 5      | :product2 | :process2  |
    | :process1 | 1 | 2      | :product3 | :process3  |
    ---------------------------------------------------