On Tue, Mar 5, 2013 at 11:32 AM, Dave Reynolds
<dave.e.reyno...@gmail.com> wrote:
> On 05/03/13 16:16, Joshua TAYLOR wrote:
>>
>> On Tue, Mar 5, 2013 at 10:59 AM, Dave Reynolds
>> <dave.e.reyno...@gmail.com> wrote:
>>>
>>> On 05/03/13 14:11, Joshua TAYLOR wrote:
>>>>
>>>>
>>>> On Tue, Mar 5, 2013 at 3:20 AM, Vegard Vaage <vegard.va...@tv2.no>
>>>> wrote:
>>>>>
>>>>>
>>>>> I'm trying to verify instance data against an ontology using Jenas OWL
>>>>> reasoner. Right now I'm just trying to verify that the input literals
>>>>> are of
>>>>> the correct types and ranges, but later on I'll need more advanced
>>>>> verification against the ontology.
>>>>> I've been following the Jena OWL Reasoner example and come up with
>>>>> this:
>>>>>
>>>>> Reasoner reasoner = ReasonerRegistry.getOWLReasoner();
>>>>> Resource resource = IndividualMapper.mapResource(dataModel, data, uri);
>>>>> InfModel infModel = ModelFactory.createInfModel(reasoner, schema,
>>>>> dataModel);
>>>>> Resource clazz = infModel.getResource(uri);
>>>>> if (infModel.contains(resource, RDF.type, clazz)) {
>>>>>           return true;
>>>>> }
>>>>> return false;
>>>>>
>>>>> But no matter how I define instance data I always get true as a return
>>>>> value. The ontology is basically a single class using owl:restriction
>>>>> on a
>>>>> datatypeProperty:
>>>>>
>>>>>    <owl:DatatypeProperty rdf:about="http://snipped/#Id";>
>>>>>           <rdf:type rdf:resource="&owl;FunctionalProperty"/>
>>>>>       </owl:DatatypeProperty>
>>>>>
>>>>> <owl:Class rdf:about="http://snipped/#MyClass";>
>>>>>           <rdfs:label xml:lang="en">MyClass</rdfs:label>
>>>>>           <rdfs:subClassOf>
>>>>>               <owl:Restriction>
>>>>>                   <owl:onProperty rdf:resource="http://snipped/#Id"/>
>>>>>                   <owl:someValuesFrom rdf:resource="&xsd;long"/>
>>>>>               </owl:Restriction>
>>>>>           </rdfs:subClassOf>
>>>>> </owl:Class>
>>>>>
>>>>> What am I doing wrong? See below for source code for the non-Jena
>>>>> stuff:
>>>>
>>>>
>>>>
>>>> What sort of instance data are you providing?
>>>> What result are you expecting that you aren't seeing?
>>>> What result aren't you expecting that you are seeing?
>>>>
>>>> What exactly do you mean by validation?  You said that you're trying
>>>> to check that the "input literals are of the correct type and ranges".
>>>>    However, it looks like check that you're performing is to see whether
>>>> individuals have a particular RDF type.  Based on your ontology, I
>>>> don't see any way to infer that something is a member of MyClass
>>>> except through explicit assertion, although there are ways that you
>>>> could infer that something *isn't* a MyClass, e.g., if it has a value
>>>> for Id that's not a long.
>>>
>>>
>>>
>>> Actually not even then. Vegard's restriction on MyClass is
>>> owl:someValuesFrom which won't work for several reasons.
>>>
>>> First, the the open world assumption means that if there isn't such a
>>> value
>>> then there is no inconsistency (the data is incomplete but not
>>> inconsistent).
>>
>>
>> Well, I'd been hoping we could elicit a few more details from the OP,
>> so that we could figure out whether some kind of validation would be
>> possible for his case.  Since his "Id" property was declared to be
>> functional, a reasoner could recognize that once an individual has an
>> Id with a *non* xsd:long value, that it *can't* be a member of
>> MyClass. Since he was talking about checking the datatypes of property
>> values, but his code was checking the class membership of individuals,
>> I expected that we'd probably get to testing both for MyClass and for
>> [not MyClass] (i.e., to see if something happened that would *prevent*
>> something from being a MyClass.
>>
>>> Second, that's OWL2 and Jena only supports OWL1.
>>
>>
>> I might be missing something, but which part of this falls into OWL2?
>> It looks like OWL1 [1] has both someValuesFrom [2] and
>> functionalProperty [3].
>
>
> Oops. Sorry, you are right. I was thinking of qualified cardinality
> restrictions, someValuesFrom is fine.

That said, I played with a bit more code than I posted above.  Say we
had the data

x Id "foo"^^xsd:string

Since Id is functional, x can have at most one Id value.  Since
"foo"^^xsd:string isn't an xsd:long, and x can't have another Id
value, x can't have a xsd:long value, and so can't be a MyClass, and
must, then, be a NotMyClass.  The Jena reasoners can't check this, but
Pellet can.  I've included some code that illustrates this.  The OP
should be aware that certain validation tasks may require certain
kinds of reasoners.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.mindswap.pellet.jena.PelletReasonerFactory;

import com.hp.hpl.jena.ontology.FunctionalProperty;
import com.hp.hpl.jena.ontology.Individual;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.XSD;

public class Validation {
        
        @SuppressWarnings("serial")
        private static final Map<OntModelSpec, String> specs = new
HashMap<OntModelSpec,String>() {{
                put(OntModelSpec.OWL_DL_MEM, "OWL_DL_MEM");
                put(OntModelSpec.OWL_DL_MEM_RDFS_INF, "OWL_DL_MEM_RDFS_INF");
                put(OntModelSpec.OWL_DL_MEM_RULE_INF, "OWL_DL_MEM_RULE_INF");
                put(OntModelSpec.OWL_DL_MEM_TRANS_INF, "OWL_DL_MEM_TRANS_INF");
                put(PelletReasonerFactory.THE_SPEC, 
"PelletReasonerFactory.THE_SPEC");
        }};
        
        private static OntModel model;
        private static List<Individual> inds = new ArrayList<>();
        private static OntClass myClass, notMyClass;
        
        public static void main( String[] args ) {
                for ( OntModelSpec spec : specs.keySet() ) {

                        // Create a model with this iteration's OntModelSpec 
and add the
                        // test model as a submodel.
                        System.out.println( "== "+ specs.get( spec )+" ==" );
                        OntModel testModel = ModelFactory.createOntologyModel( 
spec );
                        testModel.addSubModel( model );
                        
                        // Check and report whether each individual is known to 
be a
                        // MyClass, a NotMyClass, or neither.
                        for ( Individual i : inds ) {
                                boolean known = false;
                                if ( testModel.contains( i, RDF.type, myClass ) 
) {
                                        System.out.println( i+" is known to be 
a MyClass" );
                                        known = true;
                                }
                                if ( testModel.contains( i, RDF.type, 
notMyClass ) ) {
                                        System.out.println( i+" is known to be 
a notMyClass" );
                                        known = true;
                                }
                                if ( !known ) {
                                        System.out.println( i+" is not known to 
be a MyClass or a notMyClass" );
                                }
                        }
                        System.out.println();
                }
        }
        
        static {
                String NS = "http://snipped/#";;
                model = ModelFactory.createOntologyModel( 
OntModelSpec.OWL_DL_MEM );
                myClass = model.createClass( NS+"myClass" );
                notMyClass = model.createComplementClass( NS+"notMyClass", 
myClass );
                FunctionalProperty id = model.createDatatypeProperty( NS+"Id"
).convertToFunctionalProperty();
                myClass.addSuperClass( model.createSomeValuesFromRestriction( 
null,
id, XSD.xlong ));
                
                System.out.println( "===" );
                model.write( System.out, "RDF/XML-ABBREV" );

                // with no id
                Individual a = model.createIndividual( NS+"a", OWL.Thing );
                
                // with a long id
                Individual b = model.createIndividual( NS+"b", OWL.Thing );
                b.addLiteral(id, 72L );
                
                // with a string id
                Individual c = model.createIndividual( NS+"c", OWL.Thing );
                c.addLiteral( id, "someString" );
                
                // with an xsd:integer id
                Individual d = model.createIndividual( NS+"d", OWL.Thing );
                d.addLiteral( id, model.createTypedLiteral( 34 ));
                
                System.out.println( "===" );
                model.write( System.out, "RDF/XML-ABBREV" );

                inds.add( a );
                inds.add( b );
                inds.add( c );
                inds.add( d );
        }
}

Output includes:

== OWL_DL_MEM_RDFS_INF ==
http://snipped/#a is not known to be a MyClass or a notMyClass
http://snipped/#b is not known to be a MyClass or a notMyClass
http://snipped/#c is not known to be a MyClass or a notMyClass
http://snipped/#d is not known to be a MyClass or a notMyClass

== PelletReasonerFactory.THE_SPEC ==
http://snipped/#a is not known to be a MyClass or a notMyClass
http://snipped/#b is not known to be a MyClass or a notMyClass
http://snipped/#c is known to be a notMyClass
http://snipped/#d is not known to be a MyClass or a notMyClass

//JT

-- 
Joshua Taylor, http://www.cs.rpi.edu/~tayloj/

Reply via email to