سؤال

I have a simple ontology that consists of a Weather class and some subclasses (although I'm not sure if I should make them individuals instead) such as "Cold", "Rainy", "Sunny", etc. The thing is, I don't know which of these conditions hold until I get weather data at runtime. For instance, it is only "Cold" if the current temperature is less than, say, 70 degrees (I live in Texas ;p). Is there a way to structure the ontology so that this sort of reasoning can be done at runtime? (I am using Protege and Jena.)

Basically, I want to do different things based on which weather conditions are currently valid. For simplicity's sake, let's assume I just want to print out "It is currently cold, rainy ...", listing out the current weather conditions based on data such as temperature and amount of precipitation.

هل كانت مفيدة؟

المحلول

Writing the axioms in OWL

It sounds like you're trying to add some rules of the form:

If x has a temperature less than or equal to 32.0 F, then x has weather condition Cold.
If x has a temperature above 32.0 F and less than or equal to 70.0 F, then x has weather condition Warm.
If x has a temperature above 70.0 F, then x has weather condition Hot.

You can do these in OWL without much problem with axioms like

hasTemperature some double[> 32.0, <= 70.0] SubClassOf hasWeatherCondition value Warm

These are called general class axioms because they have class expressions rather than atomic class names on the left hand side. The full set that I described above would be entered in Protégé as follows:

three general class axioms in Protégé

Seeing the results with Jena and Pellet

To do the reasoning about numbers, you'll need a reasoner. I'm not sure whether or not Jena's rule reasoners can do this type of reasoning or not, but I know that Pellet can. The following code uses a Pellet-backed inference model.

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.mindswap.pellet.jena.PelletReasonerFactory;

import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
import com.hp.hpl.jena.ontology.Individual;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.vocabulary.OWL;

public class WeatherExample {
    public static void main(String[] args) throws FileNotFoundException, IOException {
        final String NS = "http://stackoverflow.com/q/20489574/1281433/weather#";

        // Create an OntModel and read in the content from the ontology.  We're creating an model
        // that has Pellet doing inference behind the scenes. Pellet can handle the types of datatype
        // reasoning that we need for this particular problem.
        final OntModel model = ModelFactory.createOntologyModel( PelletReasonerFactory.THE_SPEC );
        try ( final FileInputStream in = new FileInputStream( "/home/taylorj/tmp/ontologies/weather/weather.owl" )) {
            model.read( in, null, "RDF/XML" );
        }

        // create an individual and list the things that the model knows about it.
        final Individual todaysWeather = model.createIndividual( NS+"weatherOfToday", OWL.Thing );
        System.out.println( "== Initial Knowledge ==" );
        for ( final StmtIterator it = model.listStatements( todaysWeather, null, (RDFNode) null ); it.hasNext(); ) {
            System.out.println( it.next() );
        }

        // Add the information that todaysWeather had temperature 28.0.
        final OntProperty hasTemperature = model.createOntProperty( NS+"hasTemperature" );
        todaysWeather.addLiteral( hasTemperature, model.createTypedLiteral( "28.0", XSDDatatype.XSDdouble ));

        // Show the new knowledge about todaysWeather.
        System.out.println( "== Later Knowledge ==" );
        for ( final StmtIterator it = model.listStatements( todaysWeather, null, (RDFNode) null ); it.hasNext(); ) {
            System.out.println( it.next() );
        }
    }
}

The output follows. Notice that in the second chunk todaysWeather hasWeatherCondition Cold.

== Initial Knowledge ==
[http://stackoverflow.com/q/20489574/1281433/weather#weatherOfToday, http://www.w3.org/1999/02/22-rdf-syntax-ns#type, http://www.w3.org/2002/07/owl#Thing]
[http://stackoverflow.com/q/20489574/1281433/weather#weatherOfToday, http://www.w3.org/2002/07/owl#sameAs, http://stackoverflow.com/q/20489574/1281433/weather#weatherOfToday]

== Later Knowledge ==
[http://stackoverflow.com/q/20489574/1281433/weather#weatherOfToday, http://www.w3.org/1999/02/22-rdf-syntax-ns#type, http://www.w3.org/2002/07/owl#Thing]
[http://stackoverflow.com/q/20489574/1281433/weather#weatherOfToday, http://www.w3.org/2002/07/owl#sameAs, http://stackoverflow.com/q/20489574/1281433/weather#weatherOfToday]
[http://stackoverflow.com/q/20489574/1281433/weather#weatherOfToday, http://stackoverflow.com/q/20489574/1281433/weather#hasWeatherCondition, http://stackoverflow.com/q/20489574/1281433/weather#Cold]
[http://stackoverflow.com/q/20489574/1281433/weather#weatherOfToday, http://stackoverflow.com/q/20489574/1281433/weather#hasTemperature, "28.0"^^http://www.w3.org/2001/XMLSchema#double]

The ontology

You can copy and paste the content of the ontology from which I made the screenshot from the following.

<rdf:RDF
    xmlns="http://stackoverflow.com/q/20489574/1281433/weather#"
    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:rdfs="http://www.w3.org/2000/01/rdf-schema#">
  <owl:Ontology rdf:about="http://stackoverflow.com/q/20489574/1281433/weather"/>
  <owl:ObjectProperty rdf:about="http://stackoverflow.com/q/20489574/1281433/weather#hasWeatherCondition"/>
  <owl:DatatypeProperty rdf:about="http://stackoverflow.com/q/20489574/1281433/weather#hasTemperature">
    <rdfs:comment>temperature in degrees Fahrenheit </rdfs:comment>
    <rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#double"/>
  </owl:DatatypeProperty>
  <owl:Restriction>
    <rdfs:subClassOf>
      <owl:Restriction>
        <owl:onProperty rdf:resource="http://stackoverflow.com/q/20489574/1281433/weather#hasWeatherCondition"/>
        <owl:hasValue>
          <owl:NamedIndividual rdf:about="http://stackoverflow.com/q/20489574/1281433/weather#Hot"/>
        </owl:hasValue>
      </owl:Restriction>
    </rdfs:subClassOf>
    <owl:onProperty rdf:resource="http://stackoverflow.com/q/20489574/1281433/weather#hasTemperature"/>
    <owl:someValuesFrom>
      <rdfs:Datatype>
        <owl:onDatatype rdf:resource="http://www.w3.org/2001/XMLSchema#double"/>
        <owl:withRestrictions rdf:parseType="Collection">
          <rdf:Description>
            <xsd:minExclusive rdf:datatype="http://www.w3.org/2001/XMLSchema#double"
            >70.0</xsd:minExclusive>
          </rdf:Description>
        </owl:withRestrictions>
      </rdfs:Datatype>
    </owl:someValuesFrom>
  </owl:Restriction>
  <owl:Restriction>
    <rdfs:subClassOf>
      <owl:Restriction>
        <owl:onProperty rdf:resource="http://stackoverflow.com/q/20489574/1281433/weather#hasWeatherCondition"/>
        <owl:hasValue>
          <owl:NamedIndividual rdf:about="http://stackoverflow.com/q/20489574/1281433/weather#Warm"/>
        </owl:hasValue>
      </owl:Restriction>
    </rdfs:subClassOf>
    <owl:onProperty rdf:resource="http://stackoverflow.com/q/20489574/1281433/weather#hasTemperature"/>
    <owl:someValuesFrom>
      <rdfs:Datatype>
        <owl:onDatatype rdf:resource="http://www.w3.org/2001/XMLSchema#double"/>
        <owl:withRestrictions rdf:parseType="Collection">
          <rdf:Description>
            <xsd:maxInclusive rdf:datatype="http://www.w3.org/2001/XMLSchema#double"
            >70.0</xsd:maxInclusive>
          </rdf:Description>
          <rdf:Description>
            <xsd:minExclusive rdf:datatype="http://www.w3.org/2001/XMLSchema#double"
            >32.0</xsd:minExclusive>
          </rdf:Description>
        </owl:withRestrictions>
      </rdfs:Datatype>
    </owl:someValuesFrom>
  </owl:Restriction>
  <owl:Restriction>
    <rdfs:subClassOf>
      <owl:Restriction>
        <owl:onProperty rdf:resource="http://stackoverflow.com/q/20489574/1281433/weather#hasWeatherCondition"/>
        <owl:hasValue>
          <owl:NamedIndividual rdf:about="http://stackoverflow.com/q/20489574/1281433/weather#Cold"/>
        </owl:hasValue>
      </owl:Restriction>
    </rdfs:subClassOf>
    <owl:onProperty rdf:resource="http://stackoverflow.com/q/20489574/1281433/weather#hasTemperature"/>
    <owl:someValuesFrom>
      <rdfs:Datatype>
        <owl:onDatatype rdf:resource="http://www.w3.org/2001/XMLSchema#double"/>
        <owl:withRestrictions rdf:parseType="Collection">
          <rdf:Description>
            <xsd:maxInclusive rdf:datatype="http://www.w3.org/2001/XMLSchema#double"
            >32.0</xsd:maxInclusive>
          </rdf:Description>
        </owl:withRestrictions>
      </rdfs:Datatype>
    </owl:someValuesFrom>
  </owl:Restriction>
</rdf:RDF>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top