slanted W3C logo
Cover page images (keys)

Validation Orientation

RDF Data Shapes WG F2F
30 October, 2014

Problem Statement

Useful data needs consistent structure:

Detect and correct errors:

@prefix : <http://www.w3.org/2012/12/rdf-val/SOTA-ex#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/'> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<issue7> a :Issue , :SecurityIssue ;
    :state :unassigned ;
    :reportedBy <user6> , <user2> ; # cardinality 1
    :reportedOn "2012-12-31T23:57:00"^^xsd:dateTime ;
    :reproducedBy <user2>, <user1> ;
    :reproducedOn "2012-11-31T23:57:00"^^xsd:dateTime ;
                       # reproduced before being reported
    :related <issue4>, <issue3>, <issue2> .
                       # referenced issues not included

<issue4> # a ???         missing type arc
    :state :unsinged ; # misspelled
    # :reportedBy ??? -  missing
    :reportedOn "2012-12-31T23:57:00"^^xsd:dateTime .

<user2> a foaf:Person ;
    foaf:givenName "Alice" ;
    foaf:familyName "Smith" ;
    foaf:phone <tel:+1.555.222.2222> ;
    foaf:mbox <mailto:alice@example.com> .

<user6> a foaf:Agent ; # should be foaf:Person
    foaf:givenName "Bob" ; # foaf:familyName "???" - missing
    foaf:phone <tel:+.555.222.2222> ; # malformed tel: URL
    foaf:mbox <mailto:alice@example.com> .

Expectations

What do users get elsewhere?

SQLXML
missing propertiesreportedBy UNSIGNED INT NOT NULLelement reportedBy { User },
missing/bad type arcsN/AN/A
missing referentsFOREIGN KEY (reportedBy)
REFERENCES Users(ID)
<keyref refer="UserID">
inconsistent stateCHECK(reproducedOn>reportedOn)[schematron]
value set violationsENUM('unasigned', 'assigned')attribute state
{ "unassigned" | "assigned" }

Existing data

Technologies

in order of specificity:

Keep calm and validate.

SPARQL

ASK {
    { SELECT ?S (COUNT(*) AS ?S_c0) {
      ?S foaf:givenName ?o .
    } GROUP BY ?S}
    { SELECT ?S (COUNT(*) AS ?S_c1) {
      ?S foaf:givenName ?o .
    } GROUP BY ?S}
    FILTER (?S_c0 = ?S_c1 &&
            ?S_c0 = 1)
    { SELECT ?S (COUNT(*) AS ?S_c2) {
      ?S ex:state ?o .
    } GROUP BY ?S HAVING (COUNT(*)=1)}
    { SELECT ?S (COUNT(*) AS ?S_c3) {
      ?S ex:state ?o .
      FILTER ((?o = ex:unassigned ||
               ?o = ex:assigned))
    } GROUP BY ?S HAVING (COUNT(*)=1)}
    FILTER (?S_c2 = ?S_c3 &&
            (?S_c0 = 0 || ?S_c0 = 1))
}

Path-indexed ASK

per Simister, Brickley

{
  "@context": { … },
  "constraints": [{
    "context": "ex:status",
    "constraint": "ASK { ?s ex:assignee ?o }",
    "severity": "warning",
    "message": "a status of assigned requires an assignee"
  }]
}

SPARQL as SPIN

ASK {
    { SELECT ?this (COUNT(*) AS ?this_c0) {
      ?this foaf:givenName ?o .
    } GROUP BY ?this}
    { SELECT ?this (COUNT(*) AS ?this_c1) {
      ?this foaf:givenName ?o .
    } GROUP BY ?this}
    FILTER (?this_c0 = ?this_c1 &&
            ?this_c0 = 1)
    { SELECT ?this (COUNT(*) AS ?this_c2) {
      ?this ex:state ?o .
    } GROUP BY ?this HAVING (COUNT(*)=1)}
    { SELECT ?this (COUNT(*) AS ?this_c3) {
      ?this ex:state ?o .
      FILTER ((?o = ex:unassigned ||
               ?o = ex:assigned))
    } GROUP BY ?this HAVING (COUNT(*)=1)}
    FILTER (?this_c2 = ?this_c3 &&
            (?this_c0 = 0 || ?this_c0 = 1))
}

SPIN as templates

:Issue a owl:Class ;
  rdfs:subClassOf owl:Thing ;
  spin:constraint [
      a spl:ObjectCountPropertyConstraint ;
      arg:property ex:name ;
      arg:minCount 1 ;
      arg:maxCount 1 ;
    ] ;
  spin:constraint [
      a spl:ObjectCountPropertyConstraint ;
      arg:property ex:state ;
      arg:minCount 0 ;
      arg:maxCount 1 ;
    ] ;
  spin:constraint [
      a spl:UntypedObjectPropertyConstraint ;
      arg:property ex:state ;
    ] .

ex:name a owl:DatatypeProperty ;
  rdfs:domain my:name-status ;
  rdfs:range xsd:string .

:ValidState a owl:Class ;
  rdfs:label "Valid state" ;
  rdfs:subClassOf owl:Thing ;
.
:state a owl:ObjectProperty ;
  rdfs:domain my:name-status ;
  rdfs:range ex:ValidState .
:unassigned a ex:ValidState .
:assigned a ex:ValidState .

OWL

Combine OWL with a premise type associated with data.

Datatype: rdfs:Literal 
DataProperty: ex:name 
ObjectProperty: ex:status 
    
Class: ex:name-status 
    SubClassOf: 
        ex:name exactly 1 rdfs:Literal ,
        ex:status max 1 ({ ex:assigned , ex:unassigned }) ,
        ex:status min 0 owl:Thing 
    
Individual: ex:assigned 
Individual: ex:unassigned 

Not a real proposal; instead used with in a different interpretation…

OWL/ICV

OWL with unique name assumption and closed world

Datatype: rdfs:Literal 
DataProperty: ex:name 
ObjectProperty: ex:status 
    
Class: ex:name-status 
    SubClassOf: 
        ex:name exactly 1 rdfs:Literal ,
        ex:status max 1 ({ ex:assigned , ex:unassigned }) ,
        ex:status min 0 owl:Thing 
    
Individual: ex:assigned 
Individual: ex:unassigned 

Resource Shapes/Description Set Profiles/TQ schema

my:name-status a rs:ResourceShape ;
    rs:property [
        rs:name "name" ;
        rs:propertyDefinition foaf:name ;
        rs:valueType xsd:string ;
        rs:occurs rs:Exactly-one ;
    ] ;
    rs:property [
        rs:name "state" ;
        rs:propertyDefinition ex:state ;
        rs:allowedValue ex:unassigned> , ex:assigned ;
        rs:occurs rs:Zero-or-one ;
    ] .

Shape Expressions

my:name-status {
  ex:name xsd:string ,
  ex:status ( ex:unassigned ex:assigned )?
}

Semantics

my:name-status {
  ex:name xsd:string ,
  ex:status ( ex:unassigned ex:assigned )?
}
Datatype: rdfs:Literal 
DataProperty: ex:name 
ObjectProperty: ex:status 
    
Class: ex:name-status 
    SubClassOf: 
        ex:name exactly 1 rdfs:Literal ,
        ex:status max 1 ({ ex:assigned , ex:unassigned }) ,
        ex:status min 0 owl:Thing 
    
Individual: ex:assigned 
Individual: ex:unassigned 
my:name-status a rs:ResourceShape ;
    rs:property [
        rs:name "name" ;
        rs:propertyDefinition foaf:name ;
        rs:valueType xsd:string ;
        rs:occurs rs:Exactly-one ;
    ] ;
    rs:property [
        rs:name "state" ;
        rs:propertyDefinition ex:state ;
        rs:allowedValue ex:unassigned> , ex:assigned ;
        rs:occurs rs:Zero-or-one ;
    ] .
ASK {
    { SELECT ?S (COUNT(*) AS ?S_c0) {
      ?S foaf:givenName ?o .
    } GROUP BY ?S}
    { SELECT ?S (COUNT(*) AS ?S_c1) {
      ?S foaf:givenName ?o .
    } GROUP BY ?S}
    FILTER (?S_c0 = ?S_c1 &&
            ?S_c0 = 1)
    { SELECT ?S (COUNT(*) AS ?S_c2) {
      ?S ex:state ?o .
    } GROUP BY ?S HAVING (COUNT(*)=1)}
    { SELECT ?S (COUNT(*) AS ?S_c3) {
      ?S ex:state ?o .
      FILTER ((?o = ex:unassigned ||
               ?o = ex:assigned))
    } GROUP BY ?S HAVING (COUNT(*)=1)}
    FILTER (?S_c2 = ?S_c3 &&
            (?S_c0 = 0 || ?S_c0 = 1))
}

Issues:

Terminology


    

Requirements

review "small" requirements group.

Questions