Attached the output of the current SHACL converter. Note we don't
support the xsd:minExclusive yet, although we could certainly turn them
into sh:minExclusive. How commonly used is that?
In case anyone is interested, I have also attached the converter file
itself (written in SHACL rules). It likely requires the upcoming 5.4
release of TopBraid to run (or the open source API).
Holger
On 31/08/2017 17:50, Bohms, H.M. (Michel) wrote:
Hi Holger,
Hereby my small example (having the 2 restrictions where only would
was expected to be converted) FYI.
Greetings, Michel
Dr. ir. H.M. (Michel) Böhms
Senior Data Scientist
T +31888663107
M +31630381220
E [email protected] <mailto:[email protected]>
Location
<https://www.google.com/maps/place/TNO+-+Locatie+Delft+-+Stieltjesweg/@52.000788,4.3745183,17z/data=%213m1%214b1%214m5%213m4%211s0x47c5b58c52869997:0x56681566be3b8c88%218m2%213d52.000788%214d4.376707>
<http://www.tno.nl/>
This message may contain information that is not intended for you. If
you are not the addressee or if this message was sent to you by
mistake, you are requested to inform the sender and delete the
message. TNO accepts no liability for the content of this e-mail, for
the manner in which you use it and for damage of any kind resulting
from the risks inherent to the electronic transmission of messages.
*From:*[email protected]
[mailto:[email protected]] *On Behalf Of *Holger Knublauch
*Sent:* woensdag 30 augustus 2017 23:59
*To:* [email protected]
*Subject:* Re: [topbraid-users] my first shacl try
There have been some other changes to the converter, in Java code. We
could revert the process however - if someone wants to send me their
OWL files (off or on list), I could use them to test the converter and
send the outcome back.
Holger
--
You received this message because you are subscribed to the Google Groups "TopBraid
Suite Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
# baseURI: http://example.com/priva.shapes
# imports: http://datashapes.org/dash
# imports: http://example.com/priva
@prefix : <http://example.com/priva#> .
@prefix dash: <http://datashapes.org/dash#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix spin: <http://spinrdf.org/spin#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
:BigSpace
rdf:type sh:NodeShape ;
sh:property :BigSpace-area ;
sh:property :BigSpace-hasPump ;
.
:BigSpace-area
rdf:type sh:PropertyShape ;
sh:path :area ;
sh:class xsd:float ;
.
:BigSpace-hasPump
rdf:type sh:PropertyShape ;
sh:path :hasPump ;
sh:class :BigPump ;
.
:SmallSpace
rdf:type sh:NodeShape ;
sh:property :SmallSpace-hasPump ;
.
:SmallSpace-hasPump
rdf:type sh:PropertyShape ;
sh:path :hasPump ;
sh:class :SmallPump ;
.
:Space
rdf:type sh:NodeShape ;
sh:property :Space-area ;
sh:property :Space-hasPump ;
.
:Space-area
rdf:type sh:PropertyShape ;
sh:path :area ;
sh:class xsd:float ;
.
:Space-hasPump
rdf:type sh:PropertyShape ;
sh:path :hasPump ;
sh:class :Pump ;
.
<http://example.com/priva.shapes>
rdf:type owl:Ontology ;
owl:imports <http://datashapes.org/dash> ;
owl:imports <http://example.com/priva> ;
.
# baseURI: http://datashapes.org/owl2shacl
# imports: http://datashapes.org/dash
# prefix: owl2shacl
@prefix dash: <http://datashapes.org/dash#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix owl2shacl: <http://datashapes.org/owl2shacl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix swa: <http://topbraid.org/swa#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<http://datashapes.org/owl2shacl>
rdf:type owl:Ontology ;
rdfs:comment """A collection of SHACL rules that take an RDFS/OWL ontology as
input and produce corresponding SHACL statements, essentially adding
closed-world semantics on top of the classes.
Many rules produce mapping metadata that can be used to track which of the
anonymous superclasses have been converted and could be removed from the OWL
model.""" ;
owl:imports <http://datashapes.org/dash> ;
sh:declare [
rdf:type sh:PrefixDeclaration ;
sh:namespace "http://datashapes.org/owl2shacl#"^^xsd:anyURI ;
sh:prefix "owl2shacl" ;
] ;
.
owl2shacl:ClassShape
rdf:type sh:NodeShape ;
rdfs:comment "Creates SHACL constraints from RDFS and OWL restrictions
attached to the given classes." ;
sh:rule owl2shacl:CreatePropertyShapesFromMatchingDomains ;
sh:rule owl2shacl:CreatePropertyShapesFromRestrictions ;
sh:rule owl2shacl:owlAllValuesFrom2shClassOrDatatype ;
sh:rule owl2shacl:owlAllValuesFromUnion2shClassOrDatatype ;
sh:rule owl2shacl:owlFunctionalProperty2shMaxCount1 ;
sh:rule owl2shacl:owlHasValue2shHasValue ;
sh:rule owl2shacl:owlMaxCardinality2shMaxCount ;
sh:rule owl2shacl:owlMaxQualifiedCardinalityOnClass2shQualifiedMaxCount ;
sh:rule owl2shacl:owlMaxQualifiedCardinalityOnDataRange2shQualifiedMaxCount ;
sh:rule owl2shacl:owlMinCardinality2shMinCount ;
sh:rule owl2shacl:owlMinQualifiedCardinalityOnClass2shQualifiedMinCount ;
sh:rule owl2shacl:owlMinQualifiedCardinalityOnDataRange2shQualifiedMinCount ;
sh:rule owl2shacl:owlQualifiedCardinalityOnClass2shQualifiedMinMaxCount ;
sh:rule owl2shacl:owlQualifiedCardinalityOnDataRange2shQualifiedMinMaxCount ;
sh:rule owl2shacl:owlSomeValuesFromAllValuesFrom2dashHasValueWithClass ;
sh:rule owl2shacl:owlSomeValuesFromIRI2dashHasValueWithClass ;
sh:rule owl2shacl:owlSomeValuesFromUnion2dashHasValueWithClass ;
sh:rule owl2shacl:owlUnionOfIRIs2rdfsSubClassOf ;
sh:rule owl2shacl:rdfsRange2shClassOrDatatype ;
sh:rule owl2shacl:shPropertyShapeCleanUp ;
sh:target [
rdf:type sh:SPARQLTarget ;
rdfs:comment "Targets all named classes, skipping blank nodes such as
owl:Restrictions and system namespace classes" ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
sh:select """SELECT ?this
WHERE {
{
?type rdfs:subClassOf* rdfs:Class .
?this a ?type .
FILTER isIRI(?this) .
}
FILTER (afn:namespace(?this) NOT IN (
\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\",
\"http://www.w3.org/2000/01/rdf-schema#\",
\"http://www.w3.org/2002/07/owl#\"))
}""" ;
] ;
.
owl2shacl:CreatePropertyShapesFromMatchingDomains
rdf:type sh:SPARQLRule ;
rdfs:comment "Creates a sh:property shape for each property with matching
rdfs:domain." ;
rdfs:label "rdfs:domain to sh:property" ;
sh:construct """
CONSTRUCT {
$this a sh:NodeShape .
$this sh:property ?propertyShape .
?propertyShape sh:path ?property .
}
WHERE {
{
?property rdfs:domain $this .
}
UNION {
?property rdfs:domain/owl:unionOf
?unionOf .
?unionOf rdf:rest*/rdf:first $this .
}
BIND (owl2shacl:getPropertyShape(?property,
$this) AS ?propertyShape) .
}
""" ;
sh:order 2 ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:CreatePropertyShapesFromRestrictions
rdf:type sh:SPARQLRule ;
rdfs:comment "Creates a sh:property shape for each property that is mentioned
in an owl:Restriction." ;
rdfs:label "owl:onProperty to sh:property" ;
sh:construct """
CONSTRUCT {
$this a sh:NodeShape .
$this sh:property ?propertyShape .
?propertyShape sh:path ?property .
}
WHERE {
$this rdfs:subClassOf/owl:onProperty ?property .
BIND (owl2shacl:getPropertyShape(?property,
$this) AS ?propertyShape) .
}
""" ;
sh:order 1 ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:OWL2SHACLJSLibrary
rdf:type sh:JSLibrary ;
sh:jsLibrary dash:DASHJSLibrary ;
sh:jsLibraryURL "http://TopBraid/SHACL/owl2shacl.js"^^xsd:anyURI ;
.
owl2shacl:createPropertyShapeURIs
rdf:type rdf:Property ;
rdfs:comment "A flag that informs the engine as to whether it should create
property shape URIs. Needs to be set to true for any subject in the shapes
graph." ;
rdfs:label "create property shape URIs" ;
rdfs:range xsd:boolean ;
.
owl2shacl:getPropertyShape
rdf:type sh:SPARQLFunction ;
dash:private "true"^^xsd:boolean ;
rdfs:comment "Gets an existing sh:PropertyShape for a given property at a
given shape. If none is found, return a new blank node that will be reused by
future calls." ;
rdfs:label "get property shape" ;
sh:parameter [
sh:path owl2shacl:predicate ;
sh:class rdf:Property ;
sh:description "The predicate to match." ;
] ;
sh:parameter [
sh:path owl2shacl:shape ;
sh:class sh:Shape ;
sh:description "The shape hosting the constraint." ;
] ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
sh:returnType sh:PropertyShape ;
sh:select """
SELECT ?result
WHERE {
{
?shape sh:property ?result .
?result sh:path ?predicate .
}
UNION
{
BIND (IF(isIRI($shape) && EXISTS { ?any
owl2shacl:createPropertyShapeURIs true },
IRI(CONCAT(str($shape), \"-\",
afn:localname(?predicate))),
BNODE()) AS ?result) .
}
}
""" ;
.
owl2shacl:isDatatypeRange
rdf:type sh:SPARQLFunction ;
sh:ask """
ASK WHERE {
FILTER bound(?range) .
FILTER ((?range = rdfs:Literal) || EXISTS {
GRAPH <http://topbraid.org/shacl/shaclify> {
?range a rdfs:Datatype .
}
}) .
}
""" ;
sh:parameter [
sh:path owl2shacl:range ;
sh:class rdfs:Class ;
sh:description "The range to test." ;
] ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
sh:returnType xsd:boolean ;
.
owl2shacl:mappedTo
rdf:type rdf:Property ;
rdfs:comment "Associates an OWL/RDFS subject with one or more SHACL subjects
that have been produced by the mapping rules. Statements that have been mapped
to others can in principle be deleted. This is currently only used to flag
blank nodes that appear in rdfs:subClassOf triples." ;
rdfs:label "mapped to" ;
.
owl2shacl:owlAllValuesFrom2shClassOrDatatype
rdf:type sh:SPARQLRule ;
rdfs:comment "For each owl:allValuesFrom restriction, create a corresponding
sh:class or sh:datatype constraint." ;
rdfs:label "owl:allValuesFrom with IRI to sh:class or sh:datatype" ;
sh:construct """
CONSTRUCT {
?propertyShape ?parameter ?allValuesFrom .
?restriction owl2shacl:mappedTo ?propertyShape .
}
WHERE {
{
$this rdfs:subClassOf ?restriction .
?restriction a owl:Restriction .
FILTER isBlank(?restriction) .
}
?restriction owl:onProperty ?property .
?restriction owl:allValuesFrom ?allValuesFrom .
FILTER isIRI(?allValuesFrom) .
BIND (owl2shacl:getPropertyShape(?property,
$this) AS ?propertyShape) .
BIND
(IF(owl2shacl:isDatatypeRange(?allValuesFrom), sh:datatype, sh:class) AS
?parameter) .
}
""" ;
sh:order 4 ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:owlAllValuesFromUnion2shClassOrDatatype
rdf:type sh:JSRule ;
rdfs:comment "For each owl:allValuesFrom that has an owl:unionOf as its
value, create a sh:or of sh:class or sh:datatype shapes." ;
rdfs:label "owl:allValuesFrom with union to sh:or of sh:class or sh:datatype"
;
sh:jsFunctionName "owlAllValuesFromUnion2shClassOrDatatype" ;
sh:jsLibrary owl2shacl:OWL2SHACLJSLibrary ;
sh:order "4"^^xsd:decimal ;
.
owl2shacl:owlFunctionalProperty2shMaxCount1
rdf:type sh:SPARQLRule ;
rdfs:comment "For each relevant property that is owl:FunctionalProperty,
create sh:maxCount of 1 (unless there is an OWL cardinality restriction)." ;
rdfs:label "owl:FunctionalProperty to sh:maxCount 1" ;
sh:construct """
CONSTRUCT {
?propertyShape sh:maxCount 1 .
}
WHERE {
$this sh:property ?propertyShape .
?propertyShape sh:path ?property .
?property a owl:FunctionalProperty .
FILTER NOT EXISTS {
$this rdfs:subClassOf* ?class .
?class rdfs:subClassOf ?restriction .
?restriction a owl:Restriction .
?restriction
owl:maxCardinality|owl:cardinality ?any .
}
}
""" ;
sh:order 3 ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:owlHasValue2shHasValue
rdf:type sh:SPARQLRule ;
rdfs:comment "For each owl:hasValue restriction, create a corresponding
sh:hasValue constraint." ;
rdfs:label "owl:hasValue to sh:hasValue" ;
sh:construct """
CONSTRUCT {
?propertyShape sh:hasValue ?hasValue .
?restriction owl2shacl:mappedTo ?propertyShape .
}
WHERE {
{
$this rdfs:subClassOf ?restriction .
?restriction a owl:Restriction .
FILTER isBlank(?restriction) .
}
?restriction owl:onProperty ?property .
?restriction owl:hasValue ?hasValue .
BIND (owl2shacl:getPropertyShape(?property,
$this) AS ?propertyShape) .
}
""" ;
sh:order 8 ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:owlMaxCardinality2shMaxCount
rdf:type sh:SPARQLRule ;
rdfs:comment "For each owl:maxCardinality restriction, create a corresponding
sh:maxCount constraint." ;
rdfs:label "owl:maxCardinality to sh:maxCount" ;
sh:construct """
CONSTRUCT {
?propertyShape sh:maxCount ?maxCount .
?restriction owl2shacl:mappedTo ?propertyShape .
}
WHERE {
$this rdfs:subClassOf ?restriction .
?restriction a owl:Restriction .
FILTER isBlank(?restriction) .
?restriction owl:onProperty ?property .
?restriction owl:maxCardinality|owl:cardinality
?raw .
BIND (xsd:integer(?raw) AS ?maxCount) .
BIND (owl2shacl:getPropertyShape(?property,
$this) AS ?propertyShape) .
}
""" ;
sh:order 6 ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:owlMaxQualifiedCardinalityOnClass2shQualifiedMaxCount
rdf:type sh:SPARQLRule ;
rdfs:comment "For each owl:maxQualifiedCardinality restriction on an IRI
class, create a corresponding (new) sh:qualifiedMaxCount constraint." ;
rdfs:label "owl:maxQualifiedCardinality with owl:onClass to
sh:qualifiedMaxCount" ;
sh:construct """
CONSTRUCT {
$this sh:property ?propertyShape .
?propertyShape sh:path ?property .
?propertyShape sh:qualifiedMaxCount ?maxCount .
?propertyShape sh:qualifiedValueShape
?valueShape .
?valueShape sh:class ?onClass .
?restriction owl2shacl:mappedTo ?propertyShape .
}
WHERE {
{
$this rdfs:subClassOf ?restriction .
?restriction a owl:Restriction .
FILTER isBlank(?restriction) .
}
?restriction owl:maxQualifiedCardinality ?raw .
?restriction owl:onProperty ?property .
?restriction owl:onClass ?onClass .
FILTER isIRI(?onClass) .
BIND (xsd:integer(?raw) AS ?maxCount) .
BIND (BNODE() AS ?propertyShape) .
BIND (BNODE() AS ?valueShape) .
}
""" ;
sh:order 6 ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:owlMaxQualifiedCardinalityOnDataRange2shQualifiedMaxCount
rdf:type sh:SPARQLRule ;
rdfs:comment "For each owl:maxQualifiedCardinality restriction on an IRI
datatype, create a corresponding (new) sh:qualifiedMaxCount constraint." ;
rdfs:label "owl:maxQualifiedCardinality with owl:onDataRange to
sh:qualifiedMaxCount" ;
sh:construct """
CONSTRUCT {
$this sh:property ?propertyShape .
?propertyShape sh:path ?property .
?propertyShape sh:qualifiedMaxCount ?maxCount .
?propertyShape sh:qualifiedValueShape
?valueShape .
?valueShape sh:datatype ?onDataRange .
?restriction owl2shacl:mappedTo ?propertyShape .
}
WHERE {
{
$this rdfs:subClassOf ?restriction .
?restriction a owl:Restriction .
FILTER isBlank(?restriction) .
}
?restriction owl:maxQualifiedCardinality ?raw .
?restriction owl:onProperty ?property .
?restriction owl:onDataRange ?onDataRange .
FILTER isIRI(?onDataRange) .
BIND (xsd:integer(?raw) AS ?maxCount) .
BIND (BNODE() AS ?propertyShape) .
BIND (BNODE() AS ?valueShape) .
}
""" ;
sh:order 6 ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:owlMinCardinality2shMinCount
rdf:type sh:SPARQLRule ;
rdfs:comment "For each owl:minCardinality restriction, create a corresponding
sh:minCount constraint." ;
rdfs:label "owl:minCardinality to sh:minCount" ;
sh:construct """
CONSTRUCT {
?propertyShape sh:minCount ?maxCount .
?restriction owl2shacl:mappedTo ?propertyShape .
}
WHERE {
{
$this rdfs:subClassOf ?restriction .
?restriction a owl:Restriction .
FILTER isBlank(?restriction) .
}
?restriction owl:minCardinality|owl:cardinality
?raw .
?restriction owl:onProperty ?property .
BIND (xsd:integer(?raw) AS ?maxCount) .
BIND (owl2shacl:getPropertyShape(?property,
$this) AS ?propertyShape) .
}
""" ;
sh:order 4 ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:owlMinQualifiedCardinalityOnClass2shQualifiedMinCount
rdf:type sh:SPARQLRule ;
rdfs:comment "For each owl:minQualifiedCardinality restriction on an IRI
class, create a corresponding (new) sh:qualifiedMinCount constraint." ;
rdfs:label "owl:minQualifiedCardinality with owl:onClass to
sh:qualifiedMinCount" ;
sh:construct """
CONSTRUCT {
$this sh:property ?propertyShape .
?propertyShape sh:path ?property .
?propertyShape sh:qualifiedMinCount ?minCount .
?propertyShape sh:qualifiedValueShape
?valueShape .
?valueShape sh:class ?onClass .
?restriction owl2shacl:mappedTo ?propertyShape .
}
WHERE {
{
$this rdfs:subClassOf ?restriction .
?restriction a owl:Restriction .
FILTER isBlank(?restriction) .
}
?restriction owl:minQualifiedCardinality ?raw .
?restriction owl:onClass ?onClass .
?restriction owl:onProperty ?property .
FILTER isIRI(?onClass) .
BIND (xsd:integer(?raw) AS ?minCount) .
BIND (BNODE() AS ?propertyShape) .
BIND (BNODE() AS ?valueShape) .
}
""" ;
sh:order 6 ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:owlMinQualifiedCardinalityOnDataRange2shQualifiedMinCount
rdf:type sh:SPARQLRule ;
rdfs:comment "For each owl:minQualifiedCardinality restriction on an IRI
datatype, create a corresponding (new) sh:qualifiedMinCount constraint." ;
rdfs:label "owl:minQualifiedCardinality with owl:onDataRange to
sh:qualifiedMinCount" ;
sh:construct """
CONSTRUCT {
$this sh:property ?propertyShape .
?propertyShape sh:path ?property .
?propertyShape sh:qualifiedMinCount ?minCount .
?propertyShape sh:qualifiedValueShape
?valueShape .
?valueShape sh:datatype ?onDataRange .
?restriction owl2shacl:mappedTo ?propertyShape .
}
WHERE {
{
$this rdfs:subClassOf ?restriction .
?restriction a owl:Restriction .
FILTER isBlank(?restriction) .
}
?restriction owl:minQualifiedCardinality ?raw .
?restriction owl:onDataRange ?onDataRange .
?restriction owl:onProperty ?property .
FILTER isIRI(?onDataRange) .
BIND (xsd:integer(?raw) AS ?minCount) .
BIND (BNODE() AS ?propertyShape) .
BIND (BNODE() AS ?valueShape) .
}
""" ;
sh:order 6 ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:owlQualifiedCardinalityOnClass2shQualifiedMinMaxCount
rdf:type sh:SPARQLRule ;
rdfs:comment "For each owl:qualifiedCardinality restriction on an IRI class,
create a corresponding (new) sh:qualifiedMax/MinCount constraint." ;
rdfs:label "owl:qualifiedCardinality with owl:onClass to
sh:qualifiedMax/MinCount" ;
sh:construct """
CONSTRUCT {
$this sh:property ?propertyShape .
?propertyShape sh:path ?property .
?propertyShape sh:qualifiedMaxCount ?count .
?propertyShape sh:qualifiedMinCount ?count .
?propertyShape sh:qualifiedValueShape
?valueShape .
?valueShape sh:class ?onClass .
?restriction owl2shacl:mappedTo ?propertyShape .
}
WHERE {
{
$this rdfs:subClassOf ?restriction .
?restriction a owl:Restriction .
FILTER isBlank(?restriction) .
}
?restriction owl:qualifiedCardinality ?raw .
?restriction owl:onClass ?onClass .
?restriction owl:onProperty ?property .
FILTER isIRI(?onClass) .
BIND (xsd:integer(?raw) AS ?count) .
BIND (BNODE() AS ?propertyShape) .
BIND (BNODE() AS ?valueShape) .
}
""" ;
sh:order 6 ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:owlQualifiedCardinalityOnDataRange2shQualifiedMinMaxCount
rdf:type sh:SPARQLRule ;
rdfs:comment "For each owl:qualifiedCardinality restriction on an IRI
datatype, create a corresponding (new) sh:qualifiedMax/MinCount constraint." ;
rdfs:label "owl:qualifiedCardinality with owl:onDataRange to
sh:qualifiedMax/MinCount" ;
sh:construct """
CONSTRUCT {
$this sh:property ?propertyShape .
?propertyShape sh:path ?property .
?propertyShape sh:qualifiedMaxCount ?count .
?propertyShape sh:qualifiedMinCount ?count .
?propertyShape sh:qualifiedValueShape
?valueShape .
?valueShape sh:datatype ?onDataRange .
?restriction owl2shacl:mappedTo ?propertyShape .
}
WHERE {
{
$this rdfs:subClassOf ?restriction .
?restriction a owl:Restriction .
FILTER isBlank(?restriction) .
}
?restriction owl:qualifiedCardinality ?raw .
?restriction owl:onDataRange ?onDataRange .
?restriction owl:onProperty ?property .
FILTER isIRI(?onDataRange) .
BIND (xsd:integer(?raw) AS ?count) .
BIND (BNODE() AS ?propertyShape) .
BIND (BNODE() AS ?valueShape) .
}
""" ;
sh:order 6 ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:owlSomeValuesFromAllValuesFrom2dashHasValueWithClass
rdf:type sh:SPARQLRule ;
rdfs:comment """For each owl:someValuesFrom restriction combined with an
owl:allValuesFrom on an IRI, create a corresponding dash:hasValueWithClass
constraint using a path expression.
For example:
ex:ConstitutionalOwner
a owl:Class ;
rdfs:subClassOf [
a owl:Restriction ;
owl:onProperty ex:isPlayedBy ;
owl:someValuesFrom [
a owl:Restriction ;
owl:allValuesFrom ex:StockholdersEquity ;
owl:onProperty ex:holdsEquityIn ;
] ;
] .
becomes
ex:ConstitutionalOwner
a sh:NodeShape ;
sh:property [
sh:path ( ex:isPlayedBy ex:holdsEquityIn ) ;
dash:hasValueWithClass ex:StockholdersEquity ;
] .""" ;
rdfs:label "owl:someValuesFrom with IRI to dash:hasValueWithClass" ;
sh:construct """
CONSTRUCT {
$this sh:property ?propertyShape .
?propertyShape dash:hasValueWithClass
?allValuesFrom .
?propertyShape sh:path ?firstNode .
?firstNode rdf:first ?property .
?firstNode rdf:rest ?secondNode .
?secondNode rdf:first ?allValuesFromProperty .
?secondNode rdf:rest rdf:nil .
?restriction owl2shacl:mappedTo ?propertyShape .
}
WHERE {
{
{
$this rdfs:subClassOf
?restriction .
?restriction a owl:Restriction .
FILTER isBlank(?restriction) .
}
?restriction owl:someValuesFrom
?someValuesFrom .
?someValuesFrom owl:allValuesFrom
?allValuesFrom .
FILTER isIRI(?allValuesFrom) .
FILTER (!owl2shacl:isDatatypeRange(?allValuesFrom)) .
FILTER isBlank(?someValuesFrom) .
}
?restriction owl:onProperty ?property .
?someValuesFrom owl:onProperty
?allValuesFromProperty .
BIND (BNODE() AS ?propertyShape) .
BIND (BNODE() AS ?firstNode) .
BIND (BNODE() AS ?secondNode) .
}
""" ;
sh:order 7 ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:owlSomeValuesFromIRI2dashHasValueWithClass
rdf:type sh:SPARQLRule ;
rdfs:comment "For each owl:someValuesFrom restriction with an IRI, create a
corresponding dash:hasValueWithClass constraint." ;
rdfs:label "owl:someValuesFrom with IRI to dash:hasValueWithClass" ;
sh:construct """
CONSTRUCT {
?propertyShape dash:hasValueWithClass
?someValuesFrom .
?restriction owl2shacl:mappedTo ?propertyShape .
}
WHERE {
{
$this rdfs:subClassOf ?restriction .
?restriction a owl:Restriction .
FILTER isBlank(?restriction) .
}
?restriction owl:someValuesFrom ?someValuesFrom
.
?restriction owl:onProperty ?property .
FILTER (isIRI(?someValuesFrom) &&
!owl2shacl:isDatatypeRange(?someValuesFrom)) .
BIND (owl2shacl:getPropertyShape(?property,
$this) AS ?propertyShape) .
}
""" ;
sh:order 4 ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:owlSomeValuesFromUnion2dashHasValueWithClass
rdf:type sh:JSRule ;
rdfs:comment "For each owl:someValuesFrom that has an owl:unionOf as its
value, create a sh:or of dash:hasValueWithClass shapes." ;
rdfs:label "owl:someValuesFrom with union to sh:or of dash:hasValueWithClass"
;
sh:condition [
rdf:type sh:NodeShape ;
sh:sparql [
rdfs:comment "Don't perform this rule if any of the members of the
nested rdf:List are not IRIs." ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
sh:select """SELECT $this
WHERE {
$this rdfs:subClassOf/owl:someValuesFrom/owl:unionOf ?union .
?union rdf:rest*/rdf:first ?member .
FILTER (isBlank(?member) || owl2shacl:isDatatypeRange(?member)) .
}""" ;
] ;
] ;
sh:jsFunctionName "owlSomeValuesFromUnion2dashHasValueWithClass" ;
sh:jsLibrary owl2shacl:OWL2SHACLJSLibrary ;
sh:order "4"^^xsd:decimal ;
.
owl2shacl:owlUnionOfIRIs2rdfsSubClassOf
rdf:type sh:SPARQLRule ;
rdfs:comment "For each owl:unionOf that only consists of named classes, move
these classes into \"normal\" rdfs:subClassOf triples." ;
rdfs:label "owl:unionOf IRIs to rdfs:subClassOf" ;
sh:construct """
CONSTRUCT {
$this rdfs:subClassOf ?class .
?union owl2shacl:mappedTo $this .
}
WHERE {
{
$this rdfs:subClassOf ?union .
?union owl:unionOf ?unionOf .
FILTER isBlank(?union) .
}
FILTER NOT EXISTS {
?unionOf rdf:rest*/rdf:first ?member .
FILTER (!isIRI(?member)) .
} .
?unionOf rdf:rest*/rdf:first ?class .
}
""" ;
sh:order "4"^^xsd:decimal ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:rdfsRange2shClassOrDatatype
rdf:type sh:SPARQLRule ;
rdfs:comment "For each relevant property that has an rdfs:range, create
sh:class or sh:datatype constraint unless it already exists (from a
restriction)." ;
rdfs:label "rdfs:range with IRI to sh:class or sh:datatype" ;
sh:construct """
CONSTRUCT {
?propertyShape ?parameter ?range .
}
WHERE {
{
$this sh:property ?propertyShape .
FILTER NOT EXISTS { ?propertyShape
sh:class|sh:datatype ?any } .
}
?propertyShape sh:path ?property .
?property rdfs:range ?range .
FILTER isIRI(?range) .
BIND (IF(owl2shacl:isDatatypeRange(?range),
sh:datatype, sh:class) AS ?parameter) .
}
""" ;
sh:order 5 ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
owl2shacl:shPropertyShapeCleanUp
rdf:type sh:SPARQLRule ;
rdfs:comment "For each value of sh:property that is a IRI, add a rdf:type
sh:PropertyShape triple." ;
rdfs:label "sh:property shape clean up" ;
sh:construct """CONSTRUCT {
?propertyShape a sh:PropertyShape .
}
WHERE {
?shape sh:property ?propertyShape .
FILTER isIRI(?propertyShape) .
}""" ;
sh:order "100"^^xsd:decimal ;
sh:prefixes <http://datashapes.org/owl2shacl> ;
.
rdf:HTML
rdf:type rdfs:Datatype ;
.
rdf:PlainLiteral
rdf:type rdfs:Datatype ;
.
rdf:XMLLiteral
rdf:type rdfs:Datatype ;
.
xsd:ENTITY
rdf:type rdfs:Datatype ;
.
xsd:ID
rdf:type rdfs:Datatype ;
.
xsd:IDREF
rdf:type rdfs:Datatype ;
.
xsd:NCName
rdf:type rdfs:Datatype ;
.
xsd:NMTOKEN
rdf:type rdfs:Datatype ;
.
xsd:NOTATION
rdf:type rdfs:Datatype ;
.
xsd:Name
rdf:type rdfs:Datatype ;
.
xsd:QName
rdf:type rdfs:Datatype ;
.
xsd:anySimpleType
rdf:type rdfs:Datatype ;
.
xsd:anyURI
rdf:type rdfs:Datatype ;
.
xsd:base64Binary
rdf:type rdfs:Datatype ;
.
xsd:boolean
rdf:type rdfs:Datatype ;
.
xsd:byte
rdf:type rdfs:Datatype ;
.
xsd:date
rdf:type rdfs:Datatype ;
.
xsd:dateTime
rdf:type rdfs:Datatype ;
.
xsd:decimal
rdf:type rdfs:Datatype ;
.
xsd:double
rdf:type rdfs:Datatype ;
.
xsd:duration
rdf:type rdfs:Datatype ;
.
xsd:float
rdf:type rdfs:Datatype ;
.
xsd:gDay
rdf:type rdfs:Datatype ;
.
xsd:gMonth
rdf:type rdfs:Datatype ;
.
xsd:gMonthDay
rdf:type rdfs:Datatype ;
.
xsd:gYear
rdf:type rdfs:Datatype ;
.
xsd:gYearMonth
rdf:type rdfs:Datatype ;
.
xsd:hexBinary
rdf:type rdfs:Datatype ;
.
xsd:int
rdf:type rdfs:Datatype ;
.
xsd:integer
rdf:type rdfs:Datatype ;
.
xsd:language
rdf:type rdfs:Datatype ;
.
xsd:long
rdf:type rdfs:Datatype ;
.
xsd:negativeInteger
rdf:type rdfs:Datatype ;
.
xsd:nonNegativeInteger
rdf:type rdfs:Datatype ;
.
xsd:nonPositiveInteger
rdf:type rdfs:Datatype ;
.
xsd:normalizedString
rdf:type rdfs:Datatype ;
.
xsd:positiveInteger
rdf:type rdfs:Datatype ;
.
xsd:short
rdf:type rdfs:Datatype ;
.
xsd:string
rdf:type rdfs:Datatype ;
.
xsd:time
rdf:type rdfs:Datatype ;
.
xsd:token
rdf:type rdfs:Datatype ;
.
xsd:unsignedByte
rdf:type rdfs:Datatype ;
.
xsd:unsignedInt
rdf:type rdfs:Datatype ;
.
xsd:unsignedLong
rdf:type rdfs:Datatype ;
.
xsd:unsignedShort
rdf:type rdfs:Datatype ;
.