Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement SHACL validation #108

Merged
merged 3 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<itemizedlist>
<title>Properties</title>
<listitem>
<para><literal>dmlex:langCode</literal> REQUIRED (exactly 1) of type <literal>http://www.w3.org/2001/XMLSchema#language</literal></para>
<para><literal>dmlex:langCode</literal> REQUIRED (exactly 1) of type <literal>http://www.w3.org/2001/XMLSchema#language</literal> (subproperty of <literal>http://www.w3.org/ns/lemon/lime#language</literal>)</para>
</listitem>
<listitem>
<para><literal>dmlex:displayName</literal> OPTIONAL (at most 1) of type <literal>http://www.w3.org/2001/XMLSchema#string</literal></para>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<para><literal>dmlex:listingOrder</literal> REQUIRED (exactly 1) of type <literal>http://www.w3.org/2001/XMLSchema#nonNegativeInteger</literal></para>
</listitem>
<listitem>
<para><literal>dmlex:language</literal> REQUIRED (exactly 1) of type <literal>http://www.w3.org/2001/XMLSchema#language</literal> (subproperty of <literal>http://www.w3.org/ns/lemon/lime#language</literal>)</para>
<para><literal>dmlex:langCode</literal> OPTIONAL of type <literal>http://www.w3.org/2001/XMLSchema#language</literal> (subproperty of <literal>http://www.w3.org/ns/lemon/lime#language</literal>)</para>
</listitem>
<listitem>
<para><literal>dmlex:partOfSpeech</literal> OPTIONAL reference to <olink targetptr="rdf_PartOfSpeech">PartOfSpeech</olink></para>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<para><literal>dmlex:listingOrder</literal> OPTIONAL of type <literal>http://www.w3.org/2001/XMLSchema#nonNegativeInteger</literal></para>
</listitem>
<listitem>
<para><literal>dmlex:language</literal> OPTIONAL (at most 1) of type <literal>http://www.w3.org/2001/XMLSchema#language</literal> (subproperty of <literal>http://www.w3.org/ns/lemon/lime#language</literal>)</para>
<para><literal>dmlex:langCode</literal> OPTIONAL of type <literal>http://www.w3.org/2001/XMLSchema#language</literal> (subproperty of <literal>http://www.w3.org/ns/lemon/lime#language</literal>)</para>
</listitem>
<listitem>
<para><literal>dmlex:label</literal> OPTIONAL reference to <olink targetptr="rdf_Label">Label</olink></para>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<itemizedlist>
<title>Properties</title>
<listitem>
<para><literal>dmlex:language</literal> OPTIONAL (at most 1) of type <literal>http://www.w3.org/2001/XMLSchema#language</literal> (subproperty of <literal>http://www.w3.org/ns/lemon/lime#language</literal>)</para>
<para><literal>dmlex:langCode</literal> OPTIONAL of type <literal>http://www.w3.org/2001/XMLSchema#language</literal> (subproperty of <literal>http://www.w3.org/ns/lemon/lime#language</literal>)</para>
</listitem>
<listitem>
<para><literal>dmlex:text</literal> REQUIRED (exactly 1) of type <literal>http://www.w3.org/2000/01/rdf-schema#Literal</literal></para>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<para><literal>dmlex:listingOrder</literal> REQUIRED (exactly 1) of type <literal>http://www.w3.org/2001/XMLSchema#nonNegativeInteger</literal></para>
</listitem>
<listitem>
<para><literal>dmlex:language</literal> OPTIONAL (at most 1) of type <literal>http://www.w3.org/2001/XMLSchema#language</literal> (subproperty of <literal>http://www.w3.org/ns/lemon/lime#language</literal>)</para>
<para><literal>dmlex:langCode</literal> OPTIONAL of type <literal>http://www.w3.org/2001/XMLSchema#language</literal> (subproperty of <literal>http://www.w3.org/ns/lemon/lime#language</literal>)</para>
</listitem>
<listitem>
<para><literal>dmlex:partOfSpeech</literal> OPTIONAL reference to <olink targetptr="rdf_PartOfSpeech">PartOfSpeech</olink></para>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
<para><literal>dmlex:etymonLanguage</literal> OPTIONAL reference to <olink targetptr="rdf_EtymonLanguage">EtymonLanguage</olink></para>
</listitem>
<listitem>
<para><literal>dmlex:language</literal> REQUIRED (exactly 1) of type <literal>http://www.w3.org/2001/XMLSchema#language</literal> (subproperty of <literal>http://www.w3.org/ns/lemon/lime#language</literal>)</para>
<para><literal>dmlex:langCode</literal> REQUIRED (exactly 1) of type <literal>http://www.w3.org/2001/XMLSchema#language</literal> (subproperty of <literal>http://www.w3.org/ns/lemon/lime#language</literal>)</para>
</listitem>
</itemizedlist>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,10 @@
<para><literal>dmlex:listingOrder</literal> REQUIRED (exactly 1) of type <literal>http://www.w3.org/2001/XMLSchema#nonNegativeInteger</literal></para>
</listitem>
<listitem>
<para><literal>dmlex:ref</literal> REQUIRED (exactly 1) of type
<literal>http://www.w3.org/2001/XMLSchema#string</literal></para>
<para><literal>dmlex:ref</literal> REQUIRED (exactly 1) of type <literal>http://www.w3.org/2001/XMLSchema#string</literal></para>
</listitem>
<listitem>
<para><literal>dmlex:obverseListingOrder</literal> OPTIONAL (at most 1) of type
<literal>http://www.w3.org/2001/XMLSchema#integer</literal></para>
<para><literal>dmlex:obverseListingOrder</literal> OPTIONAL (at most 1) of type <literal>http://www.w3.org/2001/XMLSchema#integer</literal></para>
</listitem>
<listitem>
<para><literal>dmlex:role</literal> OPTIONAL (at most 1) of type <literal>http://www.w3.org/2001/XMLSchema#string</literal></para>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<para><literal>dmlex:description</literal> OPTIONAL (at most 1) of type <literal>http://www.w3.org/2000/01/rdf-schema#Literal</literal></para>
</listitem>
<listitem>
<para><literal>dmlex:type</literal> OPTIONAL of type <literal>http://www.w3.org/2001/XMLSchema#string</literal></para>
<para><literal>dmlex:type</literal> REQUIRED (exactly 1) of type <literal>http://www.w3.org/2001/XMLSchema#string</literal></para>
</listitem>
<listitem>
<para><literal>dmlex:role</literal> OPTIONAL (at most 1) of type <literal>http://www.w3.org/2001/XMLSchema#string</literal></para>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<para><literal>dmlex:label</literal> OPTIONAL reference to <olink targetptr="rdf_Label">Label</olink></para>
</listitem>
<listitem>
<para><literal>dmlex:indicator</literal> OPTIONAL (at most 1) reference to <olink targetptr="rdf_Indicator">Indicator</olink></para>
<para><literal>dmlex:indicator</literal> OPTIONAL (at most 1) of type <literal>http://www.w3.org/2000/01/rdf-schema#Literal</literal></para>
</listitem>
<listitem>
<para><literal>dmlex:definition</literal> OPTIONAL reference to <olink targetptr="rdf_Definition">Definition</olink></para>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<para><literal>dmlex:listingOrder</literal> REQUIRED (exactly 1) of type <literal>http://www.w3.org/2001/XMLSchema#nonNegativeInteger</literal></para>
</listitem>
<listitem>
<para><literal>dmlex:langCode</literal> REQUIRED (exactly 1) of type <literal>http://www.w3.org/2001/XMLSchema#language</literal></para>
<para><literal>dmlex:langCode</literal> REQUIRED (exactly 1) of type <literal>http://www.w3.org/2001/XMLSchema#language</literal> (subproperty of <literal>http://www.w3.org/ns/lemon/lime#language</literal>)</para>
</listitem>
</itemizedlist>

Expand Down
87 changes: 87 additions & 0 deletions dmlex-v1.0/specification/serializations/RDF/gen_shacl_from_rdf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import rdflib
from collections import defaultdict
from rdflib.namespace import RDF, RDFS, OWL, URIRef
from rdflib.collection import Collection

DMLEX = "http://www.oasis-open.org/to-be-confirmed/dmlex#"
DMLEX_SHACL = "http://www.oasis-open.org/to-be-confirmed/dmlex-shacl#"

def parse_rdf():
g = rdflib.Graph()
g.parse("ontology/dmlex.ttl", format="turtle")

props = defaultdict(list)
for s, p, o in g.triples((None, RDFS.domain, None)):
if isinstance(o, rdflib.term.URIRef):
if str(o).startswith(DMLEX + "Has"):
for domain_class in g.subjects(RDFS.subClassOf, o):
props[domain_class].append(s)
else:
props[o].append(s)
else:
for listname in g.objects(o, OWL.unionOf):
for item in Collection(g, listname):
props[item].append(s)

ranges = defaultdict(list)
for s, p, o in g.triples((None, RDFS.range, None)):
if isinstance(o, rdflib.term.URIRef):
ranges[s].append(o)

with open("ontology/dmlex.shacl", "w") as file:
file.write("# This file was generated from dmlex.ttl by " +
"gen_shacl_from_rdf.py\n")
file.write("@prefix sh: <http://www.w3.org/ns/shacl#> .\n")
file.write(f"@prefix dmlex: <{DMLEX}> .\n")
file.write(f"@prefix : <{DMLEX_SHACL}> .\n\n")
for class_uri in g.subjects(RDF.type, OWL.Class):
if (isinstance(class_uri, rdflib.term.URIRef) and
not str(class_uri).startswith(DMLEX + "Has")):
uri = str(class_uri)
name = uri.split("#")[-1]

subclasses = []
restrictions = defaultdict(lambda: defaultdict(lambda: [0,-1]))
for o in g.objects(class_uri, RDFS.subClassOf):
if (isinstance(o, rdflib.term.URIRef) and
not str(o).startswith(DMLEX + "Has")):
subclasses.append(str(o))
elif isinstance(o, rdflib.term.BNode):
for o2 in g.objects(o, OWL.onProperty):
for o3 in g.objects(o, OWL.cardinality):
restrictions[class_uri][o2] = [o3, o3]
for o3 in g.objects(o, OWL.maxCardinality):
restrictions[class_uri][o2] = [0, o3]
for o3 in g.objects(o, OWL.minCardinality):
restrictions[class_uri][o2] = [o3, -1]
file.write(f"""
:{name}Shape ;
a sh:NodeShape ;
sh:targetClass dmlex:{name} ;
sh:closed false""")
for prop in props[class_uri]:
file.write(f""" ;
sh:property [
sh:path dmlex:{prop.split("#")[-1]} """)
if prop in restrictions[class_uri]:
min_card, max_card = restrictions[class_uri][prop]
if min_card >= 0:
file.write(f""" ;
sh:minCount {min_card}""")
if max_card >= 0:
file.write(f""" ;
sh:maxCount {max_card}""")
for range in ranges[prop]:
if range.startswith(DMLEX):
file.write(f""" ;
sh:class dmlex:{range.split("#")[-1]} """)
file.write(" ]")

file.write(" .\n\n")





if __name__ == "__main__":
parse_rdf()
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ dmlex:LexicographicResource a owl:Class ;
rdfs:label "Lexicographic resource"@en ;
rdfs:subClassOf [
a owl:Restriction ;
owl:onProperty dmlex:language ;
owl:onProperty dmlex:langCode ;
owl:cardinality 1 ] , [
a owl:Restriction ;
owl:onProperty dmlex:title ;
Expand All @@ -59,17 +59,17 @@ dmlex:uri a owl:DatatypeProperty ;
rdfs:domain dmlex:LexicographicResource ;
rdfs:range xsd:anyURI .

dmlex:language a owl:DatatypeProperty ;
dmlex:langCode a owl:DatatypeProperty ;
rdfs:label "Language"@en ;
rdfs:domain dmlex:HasLanguage ;
rdfs:domain dmlex:HasLangCode ;
rdfs:range xsd:language ;
rdfs:subPropertyOf lime:language .

dmlex:LexicographicResource rdfs:subClassOf dmlex:HasLanguage .
dmlex:HeadwordTranslation rdfs:subClassOf dmlex:HasLanguage .
dmlex:HeadwordExplanation rdfs:subClassOf dmlex:HasLanguage .
dmlex:ExampleTranslation rdfs:subClassOf dmlex:HasLanguage .
dmlex:EtymonUnit rdfs:subClassOf dmlex:HasLanguage .
dmlex:LexicographicResource rdfs:subClassOf dmlex:HasLangCode .
dmlex:HeadwordTranslation rdfs:subClassOf dmlex:HasLangCode .
dmlex:HeadwordExplanation rdfs:subClassOf dmlex:HasLangCode .
dmlex:ExampleTranslation rdfs:subClassOf dmlex:HasLangCode .
dmlex:EtymonUnit rdfs:subClassOf dmlex:HasLangCode .

dmlex:entry a owl:ObjectProperty ;
rdfs:label "Entry"@en ;
Expand Down Expand Up @@ -217,7 +217,7 @@ dmlex:Sense a owl:Class ;
dmlex:indicator a owl:ObjectProperty ;
rdfs:label "Indicator"@en ;
rdfs:domain dmlex:Sense ;
rdfs:range dmlex:Indicator .
rdfs:range rdfs:Literal .

dmlex:definition a owl:ObjectProperty ;
rdfs:label "Definition"@en ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ dmlex:Member a owl:Class ;
rdfs:label "Member"@en ;
rdfs:subClassOf [
a owl:Restriction ;
owl:onProperty dmlex:memberID ;
owl:onProperty dmlex:ref ;
owl:cardinality 1 ] , [
a owl:Restriction ;
owl:onProperty dmlex:role ;
Expand All @@ -67,10 +67,10 @@ dmlex:Member a owl:Class ;
owl:cardinality 1 ] , [
a owl:Restriction ;
owl:onProperty dmlex:obverseListingOrder ;
owl:cardinality 1 ] .
owl:maxCardinality 1 ] .

dmlex:memberID a owl:DatatypeProperty ;
rdfs:label "Member ID"@en ;
dmlex:ref a owl:DatatypeProperty ;
rdfs:label "Ref"@en ;
rdfs:domain dmlex:Member ;
rdfs:range xsd:string .

Expand Down
Loading
Loading