- From: Holger Knublauch <holger@topquadrant.com>
- Date: Thu, 20 Nov 2014 10:49:23 +1000
- To: RDF Data Shapes Working Group <public-data-shapes-wg@w3.org>
- Message-ID: <546D3A93.2080603@topquadrant.com>
[Starting a new thread on this specific solution, extending on [1] ] I have implemented a new SPIN property function spin:constructViolations and a helper function spl:violatesConstraints, and those have allowed me to implement oslc:valueRange as defined by the Resource Shapes 2.0 spec. The implementation and an example file are attached. In the example, we have :Issue pointing at :Person via two properties :assignedTo and :submittedBy. Both are Persons, but submitters may not have last name or email, but assignees must have those. This is modeled via oslc_issue:Issue rdf:type owl:Class ; spin:constraint [ rdf:type oslc:Property ; oslc:propertyDefinition oslc_issue:assignedTo ; oslc:range oslc_issue:Person ; oslc:valueRange oslc_issue:Assignee ; ] ; spin:constraint [ rdf:type oslc:Property ; oslc:propertyDefinition oslc_issue:submittedBy ; oslc:range oslc_issue:Person ; oslc:valueRange oslc_issue:Submitter ; ] ; rdfs:label "Issue"^^xsd:string ; rdfs:subClassOf owl:Thing . which means although the range of both properties is Person, different additional constraints are used depending on the context. Here is Assignee: oslc_issue:Assignee rdf:type owl:Class ; spin:constraint [ rdf:type oslc:Property ; oslc:occurs oslc:Exactly-one ; oslc:propertyDefinition oslc_issue:email ; ] ; spin:constraint [ rdf:type oslc:Property ; oslc:occurs oslc:Exactly-one ; oslc:propertyDefinition oslc_issue:lastName ; ] ; rdfs:comment "All assignees must have an email and a last name."^^xsd:string ; rdfs:label "Assignee"^^xsd:string ; rdfs:subClassOf oslc_issue:Person . This :Assignee class doesn't need to be part of the actual ontology - it may just live in a SPIN file that isn't visible to end users. The actual context-sensitive check behind oslc:valueRange is implemented using CONSTRUCT { _:cv a spin:ConstraintViolation ; spin:violationRoot ?this ; spin:violationPath ?propertyDefinition ; rdfs:label ?label . ?s ?p ?o . } WHERE { ?this ?propertyDefinition ?value . (?value ?valueRange) spin:constructViolations (?s ?p ?o) BIND (CONCAT("Value ", xsd:string(?value), " of property ", xsd:string(?propertyDefinition), " does not match the shape ", xsd:string(?valueRange)) AS ?label) . } where spin:constraintViolations essentially spawns off a recursive constraint checking engine to verify that the given ?value meets all constraints defined at the class ?valueRange. Any nested constraint violations get propagated forward in the surrounding CONSTRUCT. But nobody needs to look into those details - they can be solved by a shapes library. The cost of this solution is that engines who want to support this would need to implement the spin:constructViolations property function. There is currently no official extension mechanism in SPARQL for property functions, but many SPARQL databases actually have this implemented as a de-facto standard. Yet we would need to somehow specify this. If we cannot use property functions (aka magic properties) then we could make it a normal SPARQL function that returns a temporary named graph or maybe just a boolean, so it will definitely work even with the current SPARQL language spec in one way or another. Anyway, the extension above is now in the TopBraid code base and will go into the next SPIN API for Jena too. This means that SPIN can now be used to check an instance against a certain "shape" even if the instance doesn't have a corresponding rdf:type. I would appreciate feedback from those in the Shapes/ShEx camp. What else is needed? Thanks, Holger [1] http://lists.w3.org/Archives/Public/public-data-shapes-wg/2014Nov/0193.html
Attachments
- text/plain attachment: oslc.spin.ttl
- text/plain attachment: oslc_issue.ttl
Received on Thursday, 20 November 2014 00:52:09 UTC