ontoripple 0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ontoripple/__init__.py +142 -0
- ontoripple/__main__.py +94 -0
- ontoripple/constants.py +265 -0
- ontoripple/evol_kg.py +1956 -0
- ontoripple-0.1.dist-info/LICENSE +201 -0
- ontoripple-0.1.dist-info/METADATA +57 -0
- ontoripple-0.1.dist-info/RECORD +8 -0
- ontoripple-0.1.dist-info/WHEEL +4 -0
ontoripple/evol_kg.py
ADDED
@@ -0,0 +1,1956 @@
|
|
1
|
+
from rdflib import URIRef, Variable
|
2
|
+
from .constants import *
|
3
|
+
import os
|
4
|
+
|
5
|
+
|
6
|
+
# ---------------------------------------------------------------------------------------------------------------------------
|
7
|
+
|
8
|
+
def add_class_rml(change, change_data, output_mappings):
|
9
|
+
"""
|
10
|
+
Adds a class defined in the change KG into the output_mappings.
|
11
|
+
If there is a TriplesMap that creates instances of that class, the TriplesMap is not created
|
12
|
+
Args:
|
13
|
+
change: the URI of the change which needs to be of the type AddClass
|
14
|
+
Returns:
|
15
|
+
the output_mappings updated with a new class
|
16
|
+
"""
|
17
|
+
select_change = f' SELECT DISTINCT ?class WHERE {{' \
|
18
|
+
f' <{change}> {OCH_ADDED_CLASS} ?class .}} '
|
19
|
+
|
20
|
+
results = change_data.query(select_change)
|
21
|
+
added_class = results.bindings[0][Variable('class')]
|
22
|
+
check_query = f'ASK {{ ?triples_map {RDF_TYPE} {R2RML_TRIPLES_MAP} .' \
|
23
|
+
f' ?triples_map {R2RML_SUBJECT} ?subject . ' \
|
24
|
+
f' ?subject {R2RML_CLASS} {added_class} }}'
|
25
|
+
#print(check_query)
|
26
|
+
check_res = output_mappings.query(check_query)
|
27
|
+
if not check_res.askAnswer:
|
28
|
+
if added_class.startswith('http://') or added_class.startswith('https://'):
|
29
|
+
triples_map_id = f'{added_class.split("#")[1]}_TM'
|
30
|
+
else:
|
31
|
+
triples_map_id = added_class+"_TM"
|
32
|
+
insert_class_query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
33
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
34
|
+
f' INSERT DATA {{' \
|
35
|
+
f' <{EXAMPLE_URI}{triples_map_id}> {RDF_TYPE} {R2RML_TRIPLES_MAP}; ' \
|
36
|
+
f' {RML_LOGICAL_SOURCE} [ ' \
|
37
|
+
f' {RML_SOURCE} "XXX"; ' \
|
38
|
+
f' {RML_REFERENCE_FORMULATION} "XXX" ' \
|
39
|
+
f' ]; ' \
|
40
|
+
f' {R2RML_SUBJECT} [ ' \
|
41
|
+
f' {R2RML_TEMPLATE} "XXX"; ' \
|
42
|
+
f' {R2RML_CLASS} <{added_class}> ' \
|
43
|
+
f' ]. }} '
|
44
|
+
output_mappings.update(insert_class_query)
|
45
|
+
else:
|
46
|
+
print(f'The input mappings already has rules to create instances of {added_class}.')
|
47
|
+
|
48
|
+
|
49
|
+
# ---------------------------------------------------------------------------------------------------------------------------
|
50
|
+
def remove_class_rml(change,change_data, output_mappings, review_mappings, ontology):
|
51
|
+
"""
|
52
|
+
Remove a class defined in the change KG into the output_mappings.
|
53
|
+
If there is a TriplesMap that creates instances of that class, the TriplesMap and associated POM are removed.
|
54
|
+
Referenced TriplesMaps POMs are also removed.
|
55
|
+
When the removed class is the sbclass of another class then the deleted PredicateObjectMaps are inserted into a different
|
56
|
+
document so that the KGE can review it, and move those to the parent class.
|
57
|
+
Args:
|
58
|
+
change: the URI of the change which needs to be of the type AddClass
|
59
|
+
Returns:
|
60
|
+
the output_mappings updated with the data
|
61
|
+
"""
|
62
|
+
query = f' SELECT DISTINCT ?class_name WHERE {{ ' \
|
63
|
+
f' <{change}> {OCH_DELETED_CLASS} ?class_name . }}'
|
64
|
+
|
65
|
+
for result in change_data.query(query):
|
66
|
+
class_name = result["class_name"]
|
67
|
+
query = f' ASK {{<{class_name}> {RDFS_SUBCLASS} ?parent}} '
|
68
|
+
for result in ontology.query(query):
|
69
|
+
if result is True:
|
70
|
+
query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
71
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
72
|
+
f' CONSTRUCT {{' \
|
73
|
+
f' ?triples_map {RDF_TYPE} {R2RML_TRIPLES_MAP}.' \
|
74
|
+
f' ?triples_map {R2RML_SUBJECT} ?subject.' \
|
75
|
+
f' ?subject ?subject_term ?subject_value .' \
|
76
|
+
f' ?subject {R2RML_CLASS} <{class_name}> .' \
|
77
|
+
f' ?triples_map {RML_LOGICAL_SOURCE} ?logical_source .' \
|
78
|
+
f' ?logical_source ?logical_source_term ?logical_source_value .' \
|
79
|
+
f' ?triples_map {R2RML_PREDICATE_OBJECT_MAP} ?pom. ' \
|
80
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} ?predicate . ' \
|
81
|
+
f' ?pom {R2RML_PREDICATE} ?predicate_bn . ' \
|
82
|
+
f' ?predicate_bn ?predicate_term ?predicate_value . ' \
|
83
|
+
f' ?pom {R2RML_SHORTCUT_OBJECT} ?object. ' \
|
84
|
+
f' ?pom {R2RML_OBJECT} ?object_bn . ' \
|
85
|
+
f' ?object_bn ?object_term ?object_value.' \
|
86
|
+
f' ?object_bn {R2RML_PARENT_TRIPLESMAP} ?parent_tm . ' \
|
87
|
+
f' ?object_bn {R2RML_JOIN_CONDITION} ?join_condition . ' \
|
88
|
+
f' ?join_condition ?condition_term ?condition_value . ' \
|
89
|
+
f' ?parent_triples_map {R2RML_PREDICATE_OBJECT_MAP} ?parent_pom . ' \
|
90
|
+
f' ?parent_pom {R2RML_SHORTCUT_PREDICATE} ?parent_predicate .' \
|
91
|
+
f' ?parent_pom {R2RML_PREDICATE} ?parent_predicate_bn .' \
|
92
|
+
f' ?parent_predicate_bn ?parent_predicate_term ?parent_predicate_value .' \
|
93
|
+
f' ?parent_pom {R2RML_OBJECT} ?parent_object . ' \
|
94
|
+
f' ?parent_object {R2RML_PARENT_TRIPLESMAP} ?triples_map . ' \
|
95
|
+
f' ?parent_object {R2RML_JOIN_CONDITION} ?parent_join_conditions . ' \
|
96
|
+
f' ?parent_join_conditions ?parent_condition_term ?parent_conditions_value .}} ' \
|
97
|
+
f' WHERE {{ ' \
|
98
|
+
f' ?triples_map {RDF_TYPE} {R2RML_TRIPLES_MAP}.' \
|
99
|
+
f' ?triples_map {R2RML_SUBJECT} ?subject.' \
|
100
|
+
f' ?subject ?subject_term ?subject_value .' \
|
101
|
+
f' ?subject {R2RML_CLASS} <{class_name}> .' \
|
102
|
+
f' ?triples_map {RML_LOGICAL_SOURCE} ?logical_source .' \
|
103
|
+
f' ?logical_source ?logical_source_term ?logical_source_value .' \
|
104
|
+
f' OPTIONAL {{ ' \
|
105
|
+
f' ?triples_map {R2RML_PREDICATE_OBJECT_MAP} ?pom.' \
|
106
|
+
f' OPTIONAL {{?pom {R2RML_SHORTCUT_PREDICATE} ?predicate . }}' \
|
107
|
+
f' OPTIONAL {{ ?pom {R2RML_PREDICATE} ?predicate_bn.'\
|
108
|
+
f' ?predicate_bn ?predicate_term ?predicate_value . }}' \
|
109
|
+
f' OPTIONAL {{?pom {R2RML_SHORTCUT_OBJECT} ?object .}}' \
|
110
|
+
f' OPTIONAL {{?pom {R2RML_OBJECT} ?object_bn .' \
|
111
|
+
f' ?object_bn ?object_term ?object_value. }}' \
|
112
|
+
f' OPTIONAL {{' \
|
113
|
+
f' ?object_bn {R2RML_PARENT_TRIPLESMAP} ?parent_tm .' \
|
114
|
+
f' OPTIONAL {{ ' \
|
115
|
+
f' ?object_bn {R2RML_JOIN_CONDITION} ?join_condition . ' \
|
116
|
+
f' ?join_condition ?condition_term ?condition_value .' \
|
117
|
+
f' }}' \
|
118
|
+
f' }}' \
|
119
|
+
f' }}' \
|
120
|
+
f' OPTIONAL {{ ' \
|
121
|
+
f' ?parent_triples_map {R2RML_PREDICATE_OBJECT_MAP} ?parent_pom.' \
|
122
|
+
f' OPTIONAL {{?parent_pom {R2RML_SHORTCUT_PREDICATE} ?parent_predicate .}}' \
|
123
|
+
f' OPTIONAL {{ ?parent_pom {R2RML_PREDICATE} ?parent_predicate_bn.'\
|
124
|
+
f' ?parent_predicate_bn ?parent_predicate_term ?parent_predicate_value . }}' \
|
125
|
+
f' ?parent_pom {R2RML_OBJECT} ?parent_object .' \
|
126
|
+
f' ?parent_object {R2RML_PARENT_TRIPLESMAP} ?triples_map .' \
|
127
|
+
f' OPTIONAL {{ ' \
|
128
|
+
f' ?parent_object {R2RML_JOIN_CONDITION} ?parent_join_conditions . ' \
|
129
|
+
f' ?parent_join_conditions ?parent_condition_term ?parent_conditions_value .' \
|
130
|
+
f' }}' \
|
131
|
+
f' }} ' \
|
132
|
+
f' }}'
|
133
|
+
hola=output_mappings.query(query)
|
134
|
+
for row in hola:
|
135
|
+
review_mappings.add(row)
|
136
|
+
|
137
|
+
query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
138
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
139
|
+
f' DELETE {{' \
|
140
|
+
f' ?triples_map {RDF_TYPE} {R2RML_TRIPLES_MAP}.' \
|
141
|
+
f' ?triples_map {R2RML_SUBJECT} ?subject.' \
|
142
|
+
f' ?subject ?subject_term ?subject_value .' \
|
143
|
+
f' ?subject {R2RML_CLASS} <{class_name}> .' \
|
144
|
+
f' ?triples_map {RML_LOGICAL_SOURCE} ?logical_source .' \
|
145
|
+
f' ?logical_source ?logical_source_term ?logical_source_value .' \
|
146
|
+
f' ?triples_map {R2RML_PREDICATE_OBJECT_MAP} ?pom. ' \
|
147
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} ?predicate . ' \
|
148
|
+
f' ?pom {R2RML_PREDICATE} ?predicate_bn . ' \
|
149
|
+
f' ?predicate_bn ?predicate_term ?predicate_value . ' \
|
150
|
+
f' ?pom {R2RML_SHORTCUT_OBJECT} ?object. ' \
|
151
|
+
f' ?pom {R2RML_OBJECT} ?object_bn . ' \
|
152
|
+
f' ?object_bn ?object_term ?object_value.' \
|
153
|
+
f' ?object_bn {R2RML_PARENT_TRIPLESMAP} ?parent_tm . ' \
|
154
|
+
f' ?object_bn {R2RML_JOIN_CONDITION} ?join_condition . ' \
|
155
|
+
f' ?join_condition ?condition_term ?condition_value . ' \
|
156
|
+
f' ?parent_triples_map {R2RML_PREDICATE_OBJECT_MAP} ?parent_pom . ' \
|
157
|
+
f' ?parent_pom {R2RML_SHORTCUT_PREDICATE} ?parent_predicate .' \
|
158
|
+
f' ?parent_pom {R2RML_PREDICATE} ?parent_predicate_bn .' \
|
159
|
+
f' ?parent_predicate_bn ?parent_predicate_term ?parent_predicate_value .' \
|
160
|
+
f' ?parent_pom {R2RML_OBJECT} ?parent_object . ' \
|
161
|
+
f' ?parent_object {R2RML_PARENT_TRIPLESMAP} ?triples_map . ' \
|
162
|
+
f' ?parent_object {R2RML_JOIN_CONDITION} ?parent_join_conditions . ' \
|
163
|
+
f' ?parent_join_conditions ?parent_condition_term ?parent_conditions_value .}} ' \
|
164
|
+
f' WHERE {{ ' \
|
165
|
+
f' ?triples_map {RDF_TYPE} {R2RML_TRIPLES_MAP}.' \
|
166
|
+
f' ?triples_map {R2RML_SUBJECT} ?subject.' \
|
167
|
+
f' ?subject ?subject_term ?subject_value .' \
|
168
|
+
f' ?subject {R2RML_CLASS} <{class_name}> .' \
|
169
|
+
f' ?triples_map {RML_LOGICAL_SOURCE} ?logical_source .' \
|
170
|
+
f' ?logical_source ?logical_source_term ?logical_source_value .' \
|
171
|
+
f' OPTIONAL {{ ' \
|
172
|
+
f' ?triples_map {R2RML_PREDICATE_OBJECT_MAP} ?pom.' \
|
173
|
+
f' OPTIONAL {{?pom {R2RML_SHORTCUT_PREDICATE} ?predicate . }}' \
|
174
|
+
f' OPTIONAL {{ ?pom {R2RML_PREDICATE} ?predicate_bn.'\
|
175
|
+
f' ?predicate_bn ?predicate_term ?predicate_value . }}' \
|
176
|
+
f' OPTIONAL {{?pom {R2RML_SHORTCUT_OBJECT} ?object .}}' \
|
177
|
+
f' OPTIONAL {{?pom {R2RML_OBJECT} ?object_bn .' \
|
178
|
+
f' ?object_bn ?object_term ?object_value. }}' \
|
179
|
+
f' OPTIONAL {{' \
|
180
|
+
f' ?object_bn {R2RML_PARENT_TRIPLESMAP} ?parent_tm .' \
|
181
|
+
f' OPTIONAL {{ ' \
|
182
|
+
f' ?object_bn {R2RML_JOIN_CONDITION} ?join_condition . ' \
|
183
|
+
f' ?join_condition ?condition_term ?condition_value .' \
|
184
|
+
f' }}' \
|
185
|
+
f' }}' \
|
186
|
+
f' }}' \
|
187
|
+
f' OPTIONAL {{ ' \
|
188
|
+
f' ?parent_triples_map {R2RML_PREDICATE_OBJECT_MAP} ?parent_pom.' \
|
189
|
+
f' OPTIONAL {{?parent_pom {R2RML_SHORTCUT_PREDICATE} ?parent_predicate .}}' \
|
190
|
+
f' OPTIONAL {{ ?parent_pom {R2RML_PREDICATE} ?parent_predicate_bn.'\
|
191
|
+
f' ?parent_predicate_bn ?parent_predicate_term ?parent_predicate_value . }}' \
|
192
|
+
f' ?parent_pom {R2RML_OBJECT} ?parent_object .' \
|
193
|
+
f' ?parent_object {R2RML_PARENT_TRIPLESMAP} ?triples_map .' \
|
194
|
+
f' OPTIONAL {{ ' \
|
195
|
+
f' ?parent_object {R2RML_JOIN_CONDITION} ?parent_join_conditions . ' \
|
196
|
+
f' ?parent_join_conditions ?parent_condition_term ?parent_conditions_value .' \
|
197
|
+
f' }}' \
|
198
|
+
f' }} ' \
|
199
|
+
f' }}'
|
200
|
+
output_mappings.update(query)
|
201
|
+
|
202
|
+
# ---------------------------------------------------------------------------------------------------------------------------------
|
203
|
+
|
204
|
+
def add_super_class_rml(change,change_data, output_mappings):
|
205
|
+
"""
|
206
|
+
Adds a superclass and its properties into the TriplesMap that instantiate the subclass .
|
207
|
+
Args:
|
208
|
+
change: the URI of the change which needs to be of the type add_sub_class
|
209
|
+
Returns:
|
210
|
+
the output_mappings updated with the TriplesMap of child adding the parent class and its properties
|
211
|
+
"""
|
212
|
+
super_class = None
|
213
|
+
sub_class = None
|
214
|
+
query = f' SELECT DISTINCT ?super_class ?sub_class WHERE {{ ' \
|
215
|
+
f' <{change}> {OCH_ADD_SUBCLASS_SOURCE} ?sub_class. ' \
|
216
|
+
f' <{change}> {OCH_ADD_SUBCLASS_TARGET} ?super_class. }}'
|
217
|
+
|
218
|
+
for result in change_data.query(query):
|
219
|
+
sub_class = result["sub_class"]
|
220
|
+
super_class = result["super_class"]
|
221
|
+
insert_super_class_query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
222
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
223
|
+
f' INSERT {{ ?subjectMap {R2RML_CLASS} <{super_class}>. }}' \
|
224
|
+
f' WHERE {{' \
|
225
|
+
f' ?triplesMap {R2RML_SUBJECT} ?subjectMap. ' \
|
226
|
+
f' ?subjectMap {R2RML_CLASS} <{sub_class}>. }}'
|
227
|
+
#print(insert_super_class_query)
|
228
|
+
output_mappings.update(insert_super_class_query)
|
229
|
+
|
230
|
+
# Query that takes the Predicate Object Maps from the parent class triples map and inserts them into the child triples map.
|
231
|
+
""""
|
232
|
+
insert_super_class_pom_query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
233
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
234
|
+
f' INSERT {{' \
|
235
|
+
f' ?subclass_triples_map {R2RML_PREDICATE_OBJECT_MAP} ?pom. ' \
|
236
|
+
f' ?pom ?predicate_property ?predicate . ' \
|
237
|
+
f' ?predicate ?predicate_term ?predicate_value . ' \
|
238
|
+
f' ?pom ?object_property ?object. ' \
|
239
|
+
f' ?object ?object_term ?object_value.' \
|
240
|
+
f' ?object {R2RML_PARENT_TRIPLESMAP} ?parent_tm . ' \
|
241
|
+
f' ?object {R2RML_JOIN_CONDITION} ?join_condition . ' \
|
242
|
+
f' ?join_condition ?condition_term ?condition_value . ' \
|
243
|
+
f' ?parent_triples_map {R2RML_PREDICATE_OBJECT_MAP} ?parent_pom . ' \
|
244
|
+
f' ?parent_pom ?parent_predicate_property ?parent_predicate .' \
|
245
|
+
f' ?parent_predicate ?parent_predicate_term ?parent_predicate_value .' \
|
246
|
+
f' ?parent_pom {R2RML_OBJECT} ?parent_object . ' \
|
247
|
+
f' ?parent_object {R2RML_PARENT_TRIPLESMAP} ?triples_map . ' \
|
248
|
+
f' ?parent_object {R2RML_JOIN_CONDITION} ?parent_join_conditions.'\
|
249
|
+
f' ?parent_join_conditions ?parent_condition_term ?parent_conditions_value .}} '\
|
250
|
+
f' WHERE {{ ' \
|
251
|
+
f' ?subclass_triples_map {R2RML_SUBJECT} ?subclass_subject.' \
|
252
|
+
f' ?subclass_subject {R2RML_CLASS} <{sub_class}>.' \
|
253
|
+
f' ?triples_map {R2RML_SUBJECT} ?subject.' \
|
254
|
+
f' ?subject {R2RML_CLASS} <{super_class}> .' \
|
255
|
+
f' OPTIONAL {{ ' \
|
256
|
+
f' ?triples_map {R2RML_PREDICATE_OBJECT_MAP} ?pom.' \
|
257
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE}|{R2RML_PREDICATE} ?predicate .' \
|
258
|
+
f' OPTIONAL {{ ?predicate ?predicate_term ?predicate_value . }}' \
|
259
|
+
f' ?pom {R2RML_SHORTCUT_OBJECT}|{R2RML_OBJECT} ?object .' \
|
260
|
+
f' OPTIONAL {{ ?object ?object_term ?object_value. }}' \
|
261
|
+
f' OPTIONAL {{' \
|
262
|
+
f' ?object {R2RML_PARENT_TRIPLESMAP} ?parent_tm .' \
|
263
|
+
f' OPTIONAL {{ ' \
|
264
|
+
f' ?object {R2RML_JOIN_CONDITION} ?join_condition . ' \
|
265
|
+
f' ?join_condition ?condition_term ?condition_value .' \
|
266
|
+
f' }}' \
|
267
|
+
f' }}' \
|
268
|
+
f' }} ' \
|
269
|
+
f' OPTIONAL {{ ' \
|
270
|
+
f' ?parent_triples_map {R2RML_PREDICATE_OBJECT_MAP} ?parent_pom.' \
|
271
|
+
f' ?parent_pom {R2RML_SHORTCUT_PREDICATE}|{R2RML_PREDICATE} ?parent_predicate .' \
|
272
|
+
f' OPTIONAL {{ ?parent_predicate ?parent_predicate_term ?parent_predicate_value . }}' \
|
273
|
+
f' ?parent_pom {R2RML_OBJECT} ?parent_object .' \
|
274
|
+
f' ?parent_object {R2RML_PARENT_TRIPLESMAP} ?triples_map .' \
|
275
|
+
f' OPTIONAL {{ ' \
|
276
|
+
f' ?parent_object {R2RML_JOIN_CONDITION} ?parent_join_conditions . ' \
|
277
|
+
f' ?parent_join_conditions ?parent_condition_term ?parent_conditions_value .' \
|
278
|
+
f' }}' \
|
279
|
+
f' }} ' \
|
280
|
+
f' }}'
|
281
|
+
print(insert_super_class_pom_query)
|
282
|
+
output_mappings.update(insert_super_class_pom_query)
|
283
|
+
"""
|
284
|
+
|
285
|
+
# --------------------------------------------------------------------------------------------------------------
|
286
|
+
def remove_super_class_rml(change,change_data, output_mappings):
|
287
|
+
"""
|
288
|
+
Removes superclass and its properties from the TriplesMap that instantiate the subclass .
|
289
|
+
Args:
|
290
|
+
change: the URI of the change which needs to be of the type remove_sub_class
|
291
|
+
Returns:
|
292
|
+
the output_mappings updated with the TriplesMap of child removing the parent class and its properties
|
293
|
+
"""
|
294
|
+
# When removing the subclass relationship between two classes the child one loses the parent in the rr:class part.
|
295
|
+
query = f'SELECT DISTINCT ?super_class ?sub_class WHERE {{ ' \
|
296
|
+
f' <{change}> {OCH_REMOVE_SUBCLASS_SOURCE} ?sub_class.' \
|
297
|
+
f' <{change}> {OCH_REMOVE_SUBCLASS_TARGET} ?super_class. }}'
|
298
|
+
|
299
|
+
for result in change_data.query(query):
|
300
|
+
super_class = result["super_class"]
|
301
|
+
sub_class = result["sub_class"]
|
302
|
+
delete_super_class_query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
303
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
304
|
+
f' DELETE {{ ?subjectMap {R2RML_CLASS} <{super_class}> }}' \
|
305
|
+
f' WHERE {{' \
|
306
|
+
f' ?triplesMap {R2RML_SUBJECT} ?subjectMap . ' \
|
307
|
+
f' ?subjectMap {R2RML_CLASS} <{super_class}>, <{sub_class}> .}}'
|
308
|
+
#print(delete_super_class_query)
|
309
|
+
output_mappings.update(delete_super_class_query)
|
310
|
+
|
311
|
+
#Query that takes the Predicate Object Maps from the parent class triples map and inserts them into the child triples map.
|
312
|
+
"""
|
313
|
+
remove_super_class_pom_query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
314
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
315
|
+
f' DELETE {{' \
|
316
|
+
f' ?subclass_triples_map {R2RML_PREDICATE_OBJECT_MAP} ?pom. ' \
|
317
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} ?parent_predicate . ' \
|
318
|
+
f' ?pom {R2RML_PREDICATE} ?predicate_bn . ' \
|
319
|
+
f' ?predicate_bn ?parent_predicate_term ?parent_predicate_value . ' \
|
320
|
+
f' ?pom {R2RML_SHORTCUT_OBJECT} ?parent_object. ' \
|
321
|
+
f' ?pom {R2RML_OBJECT} ?object_bn . ' \
|
322
|
+
f' ?object_bn ?parent_object_term ?parent_object_value.' \
|
323
|
+
f' ?object_bn {R2RML_PARENT_TRIPLESMAP} ?parent_tm . ' \
|
324
|
+
f' ?object_bn {R2RML_JOIN_CONDITION} ?join_condition . ' \
|
325
|
+
f' ?join_condition ?parent_condition_term ?parent_condition_value . }} ' \
|
326
|
+
f' WHERE {{ ' \
|
327
|
+
f' ?subclass_triples_map {R2RML_SUBJECT} ?subclass_subject.' \
|
328
|
+
f' ?subclass_subject {R2RML_CLASS} <{sub_class}>.' \
|
329
|
+
f' ?parent_triples_map {R2RML_SUBJECT} ?parent_subject.' \
|
330
|
+
f' ?parent_subject {R2RML_CLASS} <{super_class}> .' \
|
331
|
+
f' OPTIONAL {{ ' \
|
332
|
+
f' ?subclass_triples_map {R2RML_PREDICATE_OBJECT_MAP} ?pom.' \
|
333
|
+
f' OPTIONAL {{?pom {R2RML_SHORTCUT_PREDICATE} ?parent_predicate }}' \
|
334
|
+
f' OPTIONAL {{ '\
|
335
|
+
f' ?pom {R2RML_PREDICATE} ?predicate_bn . ' \
|
336
|
+
f' ?predicate_bn ?parent_predicate_term ?parent_predicate_value . }}' \
|
337
|
+
f' OPTIONAL {{?pom {R2RML_SHORTCUT_OBJECT} ?parent_object }}' \
|
338
|
+
f' OPTIONAL {{ '\
|
339
|
+
f' ?pom {R2RML_OBJECT} ?object_bn . ' \
|
340
|
+
f' ?object_bn ?parent_object_term ?parent_object_value. ' \
|
341
|
+
f' OPTIONAL {{' \
|
342
|
+
f' ?object_bn {R2RML_PARENT_TRIPLESMAP} ?parent_tm .' \
|
343
|
+
f' OPTIONAL {{ ' \
|
344
|
+
f' ?object_bn {R2RML_JOIN_CONDITION} ?join_condition . ' \
|
345
|
+
f' ?join_condition ?parent_condition_term ?parent_condition_value .' \
|
346
|
+
f' }}' \
|
347
|
+
f' }}' \
|
348
|
+
f' }} ' \
|
349
|
+
f' }} ' \
|
350
|
+
f' OPTIONAL {{ ' \
|
351
|
+
f' ?parent_triples_map {R2RML_PREDICATE_OBJECT_MAP} ?parent_pom.' \
|
352
|
+
f' OPTIONAL {{?parent_pom {R2RML_SHORTCUT_PREDICATE} ?parent_predicate }}' \
|
353
|
+
f' OPTIONAL {{ '\
|
354
|
+
f' ?parent_pom {R2RML_PREDICATE} ?parent_predicate_bn . ' \
|
355
|
+
f' ?parent_predicate_bn ?parent_predicate_term ?parent_predicate_value . }}' \
|
356
|
+
f' OPTIONAL {{?parent_pom {R2RML_SHORTCUT_OBJECT} ?parent_object }}' \
|
357
|
+
f' OPTIONAL {{ '\
|
358
|
+
f' ?parent_pom {R2RML_OBJECT} ?parent_object_bn . ' \
|
359
|
+
f' ?parent_object_bn ?parent_object_term ?parent_object_value. ' \
|
360
|
+
f' OPTIONAL {{' \
|
361
|
+
f' ?parent_object_bn {R2RML_PARENT_TRIPLESMAP} ?parent_tm .' \
|
362
|
+
f' OPTIONAL {{ ' \
|
363
|
+
f' ?object_bn_bn {R2RML_JOIN_CONDITION} ?parent_join_condition . ' \
|
364
|
+
f' ?parent_join_condition ?parent_condition_term ?parent_condition_value .' \
|
365
|
+
f' }}' \
|
366
|
+
f' }}' \
|
367
|
+
f' }} ' \
|
368
|
+
f' }} ' \
|
369
|
+
f' }}'
|
370
|
+
print(remove_super_class_pom_query)
|
371
|
+
output_mappings.update(remove_super_class_pom_query)
|
372
|
+
"""
|
373
|
+
|
374
|
+
def add_object_property_rml(change, change_data, output_mappings):
|
375
|
+
"""
|
376
|
+
Adds an object property to the TriplesMap indicated in the domain. For a change in the predicate object map the domain, property and range additions are needed.
|
377
|
+
Args:
|
378
|
+
change: the URI of the change which needs to be of the type addObjectProperty
|
379
|
+
Returns:
|
380
|
+
the output_mappings updated with the added predicate object maps.
|
381
|
+
"""
|
382
|
+
query = f' SELECT DISTINCT ?domain ?property ?range WHERE {{ ' \
|
383
|
+
f' <{change}> {OCH_ADDED_OBJECT_PROPERTY} ?property .' \
|
384
|
+
f' ?domainchange {OCH_ADDED_DOMAIN_TO_PROPERTY} ?property.' \
|
385
|
+
f' ?domainchange {OCH_ADDED_DOMAIN} ?domain.' \
|
386
|
+
f' ?rangechange {OCH_ADDED_RANGE_TO_PROPERTY} ?property.' \
|
387
|
+
f' ?rangechange {OCH_ADDED_OBJECT_RANGE} ?range. }}'
|
388
|
+
|
389
|
+
for result in change_data.query(query):
|
390
|
+
property_domain = result["domain"]
|
391
|
+
property_predicate = result["property"]
|
392
|
+
property_range = result["range"]
|
393
|
+
|
394
|
+
insert_object_property_query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
395
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
396
|
+
f' INSERT {{ ' \
|
397
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} [ ' \
|
398
|
+
f' {R2RML_SHORTCUT_PREDICATE} <{property_predicate}> ; ' \
|
399
|
+
f' {R2RML_OBJECT} [ ' \
|
400
|
+
f' {R2RML_PARENT_TRIPLESMAP} ?parent_triplesMap;' \
|
401
|
+
f' {R2RML_JOIN_CONDITION} [ ' \
|
402
|
+
f' {R2RML_CHILD} "XXX"; {R2RML_PARENT} "XXX" ' \
|
403
|
+
f' ] ] ]. }}' \
|
404
|
+
f' WHERE {{' \
|
405
|
+
f' ?triplesMap {R2RML_SUBJECT} ?subjectMap . ' \
|
406
|
+
f' ?subjectMap {R2RML_CLASS} <{property_domain}> .' \
|
407
|
+
f' ?parent_triplesMap {R2RML_SUBJECT} ?parent_subjectMap . ' \
|
408
|
+
f' ?parent_subjectMap {R2RML_CLASS} <{property_range}> }}'
|
409
|
+
output_mappings.update(insert_object_property_query)
|
410
|
+
|
411
|
+
|
412
|
+
# --------------------------------------------------------------------------------------------------------------------------------------------------
|
413
|
+
def remove_object_property_rml(change, change_data, output_mappings):
|
414
|
+
"""
|
415
|
+
Removes the object property indicated in the change as property from its domain. For a change in the predicate object map the domain, property and range additions are needed.
|
416
|
+
Args:
|
417
|
+
change: the URI of the change which needs to be of the type addObjectProperty
|
418
|
+
Returns:
|
419
|
+
the output_mappings updated with the reference predicate object mapping removed
|
420
|
+
"""
|
421
|
+
query = f' SELECT DISTINCT ?domain ?property ?range WHERE {{ ' \
|
422
|
+
f' <{change}> {OCH_REMOVED_OBJECT_PROPERTY} ?property .' \
|
423
|
+
f' ?domainchange {OCH_REMOVED_DOMAIN_TO_PROPERTY} ?property.' \
|
424
|
+
f' ?domainchange {OCH_REMOVED_DOMAIN} ?domain.' \
|
425
|
+
f' ?rangechange {OCH_REMOVED_RANGE_TO_PROPERTY} ?property.' \
|
426
|
+
f' ?rangechange {OCH_REMOVED_OBJECT_RANGE} ?range. }}'
|
427
|
+
|
428
|
+
#print(query)
|
429
|
+
for result in change_data.query(query):
|
430
|
+
property_domain = result["domain"]
|
431
|
+
property_predicate = result["property"]
|
432
|
+
property_range = result["range"]
|
433
|
+
remove_object_property_query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
434
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
435
|
+
f' DELETE {{' \
|
436
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} ?pom.' \
|
437
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} <{property_predicate}> .' \
|
438
|
+
f' ?pom {R2RML_OBJECT} ?objectMap.' \
|
439
|
+
f' ?objectMap {R2RML_PARENT_TRIPLESMAP} ?parentTriplesMap . ' \
|
440
|
+
f' ?objectMap {R2RML_JOIN_CONDITION} ?joinConditions . ' \
|
441
|
+
f' ?joinConditions ?conditions ?condition_values }} ' \
|
442
|
+
f' WHERE {{' \
|
443
|
+
f' ?triplesMap {R2RML_SUBJECT} ?subjectMap.' \
|
444
|
+
f' ?subjectMap {R2RML_CLASS} <{property_domain}> . ' \
|
445
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} ?pom .' \
|
446
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} <{property_predicate}> .' \
|
447
|
+
f' ?pom {R2RML_OBJECT} ?objectMap .' \
|
448
|
+
f' ?objectMap {R2RML_PARENT_TRIPLESMAP} ?parentTriplesMap .' \
|
449
|
+
f' ?parent_triplesMap {R2RML_SUBJECT} ?parent_subjectMap . ' \
|
450
|
+
f' ?parent_subjectMap {R2RML_CLASS} <{property_range}> ' \
|
451
|
+
f' OPTIONAL {{ ?objectMap {R2RML_JOIN_CONDITION} ?joinConditions .' \
|
452
|
+
f' ?joinConditions ?conditions ?condition_values }} . }}'
|
453
|
+
#print(remove_object_property_query)
|
454
|
+
output_mappings.update(remove_object_property_query)
|
455
|
+
|
456
|
+
|
457
|
+
# -------------------------------------------------------------------------------------------------------------------------
|
458
|
+
def add_data_property_rml(change,change_data, output_mappings):
|
459
|
+
"""
|
460
|
+
Adds a data property to the TriplesMap indicated in the domain. For a change in the predicate object map the domain, property and range additions are needed.
|
461
|
+
Args:
|
462
|
+
change: the URI of the change which needs to be of the type addObjectProperty
|
463
|
+
Returns:
|
464
|
+
the output_mappings updated with the new predicate object map with empty reference
|
465
|
+
"""
|
466
|
+
query = f' SELECT DISTINCT ?domain ?property ?range WHERE {{ ' \
|
467
|
+
f' <{change}> {OCH_ADDED_DATA_PROPERTY} ?property .' \
|
468
|
+
f' ?domainchange {OCH_ADDED_DOMAIN_TO_PROPERTY} ?property.' \
|
469
|
+
f' ?domainchange {OCH_ADDED_DOMAIN} ?domain.' \
|
470
|
+
f' ?rangechange {OCH_ADDED_RANGE_TO_PROPERTY} ?property.' \
|
471
|
+
f' ?rangechange {OCH_ADDED_DATA_RANGE} ?range. }}'
|
472
|
+
#print(query)
|
473
|
+
for result in change_data.query(query):
|
474
|
+
property_domain = result["domain"]
|
475
|
+
property_predicate = result["property"]
|
476
|
+
property_range = result["range"]
|
477
|
+
insert_data_property_query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
478
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
479
|
+
f' INSERT {{ ' \
|
480
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} [ ' \
|
481
|
+
f' {R2RML_SHORTCUT_PREDICATE} <{property_predicate}> ; ' \
|
482
|
+
f' {R2RML_OBJECT} [ ' \
|
483
|
+
f' {RML_REFERENCE} "XXX";' \
|
484
|
+
f' {R2RML_DATATYPE} <{property_range}>' \
|
485
|
+
f' ] ]. }}' \
|
486
|
+
f' WHERE {{' \
|
487
|
+
f' ?triplesMap {R2RML_SUBJECT} ?subjectMap . ' \
|
488
|
+
f' ?subjectMap {R2RML_CLASS} <{property_domain}> . }} '
|
489
|
+
#print(insert_data_property_query)
|
490
|
+
output_mappings.update(insert_data_property_query)
|
491
|
+
|
492
|
+
|
493
|
+
# -----------------------------------------------------------------------------------------------------------------------------------
|
494
|
+
def remove_data_property_rml(change,change_data, output_mappings):
|
495
|
+
"""
|
496
|
+
Removes the data property indicated in the change as property from its domain. For a change in the predicate object map the domain, property and range additions are needed.
|
497
|
+
Args:
|
498
|
+
change: the URI of the change which needs to be of the type addObjectProperty
|
499
|
+
Returns:
|
500
|
+
the output_mappings updated with the predicate object mapping removed
|
501
|
+
"""
|
502
|
+
query = f' SELECT DISTINCT ?domain ?property ?range WHERE {{ ' \
|
503
|
+
f' <{change}> {OCH_REMOVED_DATA_PROPERTY} ?property .' \
|
504
|
+
f' ?domainchange {OCH_REMOVED_DOMAIN_TO_PROPERTY} ?property.' \
|
505
|
+
f' ?domainchange {OCH_REMOVED_DOMAIN} ?domain.' \
|
506
|
+
f' ?rangechange {OCH_REMOVED_RANGE_TO_PROPERTY} ?property.' \
|
507
|
+
f' ?rangechange {OCH_REMOVED_DATA_RANGE} ?range. }}'
|
508
|
+
#print(query)
|
509
|
+
for result in change_data.query(query):
|
510
|
+
property_domain = result["domain"]
|
511
|
+
property_predicate = result["property"]
|
512
|
+
property_range = result["range"]
|
513
|
+
|
514
|
+
remove_data_property_query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
515
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
516
|
+
f' DELETE {{' \
|
517
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} ?pom.' \
|
518
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} <{property_predicate}> .' \
|
519
|
+
f' ?pom {R2RML_SHORTCUT_OBJECT} ?object.' \
|
520
|
+
f' ?pom {R2RML_OBJECT} ?objectMap.' \
|
521
|
+
f' ?objectMap ?object_term ?objectValue .}}' \
|
522
|
+
f' WHERE {{' \
|
523
|
+
f' ?triplesMap {R2RML_SUBJECT} ?subjectMap.' \
|
524
|
+
f' ?subjectMap {R2RML_CLASS} <{property_domain}> . ' \
|
525
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} ?pom .' \
|
526
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} <{property_predicate}> .' \
|
527
|
+
f' OPTIONAL {{?pom {R2RML_SHORTCUT_OBJECT} ?object .}}' \
|
528
|
+
f' OPTIONAL {{ '\
|
529
|
+
f' ?pom {R2RML_OBJECT} ?objectMap .' \
|
530
|
+
f' ?objectMap ?object_term ?objectValue.' \
|
531
|
+
f' OPTIONAL {{ ?objectMap {R2RML_DATATYPE} <{property_range}>}} }} . }}'
|
532
|
+
#print(remove_data_property_query)
|
533
|
+
output_mappings.update(remove_data_property_query)
|
534
|
+
|
535
|
+
|
536
|
+
|
537
|
+
# -------------------------------------------------------------------------------------------------------------
|
538
|
+
|
539
|
+
def deprecate_entity_rml(change,change_data, output_mappings, deprecated_mappings,ontology):
|
540
|
+
"""
|
541
|
+
Deprecates an entity in the knowledge graph by removing its triples map and its subject.
|
542
|
+
Args:
|
543
|
+
change: the URI of the change which needs to be of the type deprecate_entity
|
544
|
+
"""
|
545
|
+
query = f' SELECT DISTINCT ?entity WHERE {{ ' \
|
546
|
+
f' <{change}> {OCH_DEPRECATED_ENTITY} ?entity. }}'
|
547
|
+
#print(query)
|
548
|
+
for result in change_data.query(query):
|
549
|
+
entity = result["entity"]
|
550
|
+
query = f' SELECT DISTINCT ?type WHERE {{ ' \
|
551
|
+
f' <{entity}> {RDF_TYPE} ?type. }}'
|
552
|
+
#print(query)
|
553
|
+
for result in ontology.query(query):
|
554
|
+
entity_type = result["type"]
|
555
|
+
#print(f'Entity type: {entity_type}')
|
556
|
+
if entity_type == URIRef(OWL_CLASS_URI):
|
557
|
+
# Remove the triples map for the class entity
|
558
|
+
query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
559
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
560
|
+
f' CONSTRUCT {{' \
|
561
|
+
f' ?triples_map {RDF_TYPE} {R2RML_TRIPLES_MAP}.' \
|
562
|
+
f' ?triples_map {R2RML_SUBJECT} ?subject.' \
|
563
|
+
f' ?subject ?subject_term ?subject_value .' \
|
564
|
+
f' ?subject {R2RML_CLASS} <{entity}> .' \
|
565
|
+
f' ?triples_map {RML_LOGICAL_SOURCE} ?logical_source .' \
|
566
|
+
f' ?logical_source ?logical_source_term ?logical_source_value .' \
|
567
|
+
f' ?triples_map {R2RML_PREDICATE_OBJECT_MAP} ?pom. ' \
|
568
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} ?predicate . ' \
|
569
|
+
f' ?pom {R2RML_PREDICATE} ?predicate_bn . ' \
|
570
|
+
f' ?predicate_bn ?predicate_term ?predicate_value . ' \
|
571
|
+
f' ?pom {R2RML_SHORTCUT_OBJECT} ?object. ' \
|
572
|
+
f' ?pom {R2RML_OBJECT} ?object_bn . ' \
|
573
|
+
f' ?object_bn ?object_term ?object_value.' \
|
574
|
+
f' ?object_bn {R2RML_PARENT_TRIPLESMAP} ?parent_tm . ' \
|
575
|
+
f' ?object_bn {R2RML_JOIN_CONDITION} ?join_condition . ' \
|
576
|
+
f' ?join_condition ?condition_term ?condition_value . ' \
|
577
|
+
f' ?parent_triples_map {R2RML_PREDICATE_OBJECT_MAP} ?parent_pom . ' \
|
578
|
+
f' ?parent_pom {R2RML_SHORTCUT_PREDICATE} ?parent_predicate .' \
|
579
|
+
f' ?parent_pom {R2RML_PREDICATE} ?parent_predicate_bn .' \
|
580
|
+
f' ?parent_predicate_bn ?parent_predicate_term ?parent_predicate_value .' \
|
581
|
+
f' ?parent_pom {R2RML_OBJECT} ?parent_object . ' \
|
582
|
+
f' ?parent_object {R2RML_PARENT_TRIPLESMAP} ?parent_triples_map . ' \
|
583
|
+
f' ?parent_object {R2RML_JOIN_CONDITION} ?parent_join_conditions . ' \
|
584
|
+
f' ?parent_join_conditions ?parent_condition_term ?parent_conditions_value .}} ' \
|
585
|
+
f' WHERE {{ ' \
|
586
|
+
f' ?triples_map {RDF_TYPE} {R2RML_TRIPLES_MAP}.' \
|
587
|
+
f' ?triples_map {R2RML_SUBJECT} ?subject.' \
|
588
|
+
f' ?subject ?subject_term ?subject_value .' \
|
589
|
+
f' ?subject {R2RML_CLASS} <{entity}> .' \
|
590
|
+
f' ?triples_map {RML_LOGICAL_SOURCE} ?logical_source .' \
|
591
|
+
f' ?logical_source ?logical_source_term ?logical_source_value .' \
|
592
|
+
f' OPTIONAL {{ ' \
|
593
|
+
f' ?triples_map {R2RML_PREDICATE_OBJECT_MAP} ?pom.' \
|
594
|
+
f' OPTIONAL {{?pom {R2RML_SHORTCUT_PREDICATE} ?predicate . }}' \
|
595
|
+
f' OPTIONAL {{ ?pom {R2RML_PREDICATE} ?predicate_bn.'\
|
596
|
+
f' ?predicate_bn ?predicate_term ?predicate_value . }}' \
|
597
|
+
f' OPTIONAL {{?pom {R2RML_SHORTCUT_OBJECT} ?object .}}' \
|
598
|
+
f' OPTIONAL {{?pom {R2RML_OBJECT} ?object_bn .' \
|
599
|
+
f' ?object_bn ?object_term ?object_value. }}' \
|
600
|
+
f' OPTIONAL {{' \
|
601
|
+
f' ?object_bn {R2RML_PARENT_TRIPLESMAP} ?parent_tm .' \
|
602
|
+
f' OPTIONAL {{ ' \
|
603
|
+
f' ?object_bn {R2RML_JOIN_CONDITION} ?join_condition . ' \
|
604
|
+
f' ?join_condition ?condition_term ?condition_value .' \
|
605
|
+
f' }}' \
|
606
|
+
f' }}' \
|
607
|
+
f' }}' \
|
608
|
+
f' OPTIONAL {{ ' \
|
609
|
+
f' ?parent_triples_map {R2RML_PREDICATE_OBJECT_MAP} ?parent_pom.' \
|
610
|
+
f' OPTIONAL {{?parent_pom {R2RML_SHORTCUT_PREDICATE} ?parent_predicate .}}' \
|
611
|
+
f' OPTIONAL {{ ?parent_pom {R2RML_PREDICATE} ?parent_predicate_bn.'\
|
612
|
+
f' ?parent_predicate_bn ?parent_predicate_term ?parent_predicate_value . }}' \
|
613
|
+
f' ?parent_pom {R2RML_OBJECT} ?parent_object .' \
|
614
|
+
f' ?parent_object {R2RML_PARENT_TRIPLESMAP} ?parent_triples_map .' \
|
615
|
+
f' OPTIONAL {{ ' \
|
616
|
+
f' ?parent_object {R2RML_JOIN_CONDITION} ?parent_join_conditions . ' \
|
617
|
+
f' ?parent_join_conditions ?parent_condition_term ?parent_conditions_value .' \
|
618
|
+
f' }}' \
|
619
|
+
f' }} ' \
|
620
|
+
f' }}'
|
621
|
+
#print(query)
|
622
|
+
deprecated_triples=output_mappings.query(query)
|
623
|
+
for row in deprecated_triples:
|
624
|
+
deprecated_mappings.add(row)
|
625
|
+
query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
626
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
627
|
+
f' DELETE {{' \
|
628
|
+
f' ?triples_map {RDF_TYPE} {R2RML_TRIPLES_MAP}.' \
|
629
|
+
f' ?triples_map {R2RML_SUBJECT} ?subject.' \
|
630
|
+
f' ?subject ?subject_term ?subject_value .' \
|
631
|
+
f' ?subject {R2RML_CLASS} <{entity}> .' \
|
632
|
+
f' ?triples_map {RML_LOGICAL_SOURCE} ?logical_source .' \
|
633
|
+
f' ?logical_source ?logical_source_term ?logical_source_value .' \
|
634
|
+
f' ?triples_map {R2RML_PREDICATE_OBJECT_MAP} ?pom. ' \
|
635
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} ?predicate . ' \
|
636
|
+
f' ?pom {R2RML_PREDICATE} ?predicate_bn . ' \
|
637
|
+
f' ?predicate_bn ?predicate_term ?predicate_value . ' \
|
638
|
+
f' ?pom {R2RML_SHORTCUT_OBJECT} ?object. ' \
|
639
|
+
f' ?pom {R2RML_OBJECT} ?object_bn . ' \
|
640
|
+
f' ?object_bn ?object_term ?object_value.' \
|
641
|
+
f' ?object_bn {R2RML_PARENT_TRIPLESMAP} ?parent_tm . ' \
|
642
|
+
f' ?object_bn {R2RML_JOIN_CONDITION} ?join_condition . ' \
|
643
|
+
f' ?join_condition ?condition_term ?condition_value . ' \
|
644
|
+
f' ?parent_triples_map {R2RML_PREDICATE_OBJECT_MAP} ?parent_pom . ' \
|
645
|
+
f' ?parent_pom {R2RML_SHORTCUT_PREDICATE} ?parent_predicate .' \
|
646
|
+
f' ?parent_pom {R2RML_PREDICATE} ?parent_predicate_bn .' \
|
647
|
+
f' ?parent_predicate_bn ?parent_predicate_term ?parent_predicate_value .' \
|
648
|
+
f' ?parent_pom {R2RML_OBJECT} ?parent_object . ' \
|
649
|
+
f' ?parent_object {R2RML_PARENT_TRIPLESMAP} ?triples_map . ' \
|
650
|
+
f' ?parent_object {R2RML_JOIN_CONDITION} ?parent_join_conditions . ' \
|
651
|
+
f' ?parent_join_conditions ?parent_condition_term ?parent_conditions_value .}} ' \
|
652
|
+
f' WHERE {{ ' \
|
653
|
+
f' ?triples_map {RDF_TYPE} {R2RML_TRIPLES_MAP}.' \
|
654
|
+
f' ?triples_map {R2RML_SUBJECT} ?subject.' \
|
655
|
+
f' ?subject ?subject_term ?subject_value .' \
|
656
|
+
f' ?subject {R2RML_CLASS} <{entity}> .' \
|
657
|
+
f' ?triples_map {RML_LOGICAL_SOURCE} ?logical_source .' \
|
658
|
+
f' ?logical_source ?logical_source_term ?logical_source_value .' \
|
659
|
+
f' OPTIONAL {{ ' \
|
660
|
+
f' ?triples_map {R2RML_PREDICATE_OBJECT_MAP} ?pom.' \
|
661
|
+
f' OPTIONAL {{?pom {R2RML_SHORTCUT_PREDICATE} ?predicate . }}' \
|
662
|
+
f' OPTIONAL {{ ?pom {R2RML_PREDICATE} ?predicate_bn.'\
|
663
|
+
f' ?predicate_bn ?predicate_term ?predicate_value . }}' \
|
664
|
+
f' OPTIONAL {{?pom {R2RML_SHORTCUT_OBJECT} ?object .}}' \
|
665
|
+
f' OPTIONAL {{?pom {R2RML_OBJECT} ?object_bn .' \
|
666
|
+
f' ?object_bn ?object_term ?object_value. }}' \
|
667
|
+
f' OPTIONAL {{' \
|
668
|
+
f' ?object_bn {R2RML_PARENT_TRIPLESMAP} ?parent_tm .' \
|
669
|
+
f' OPTIONAL {{ ' \
|
670
|
+
f' ?object_bn {R2RML_JOIN_CONDITION} ?join_condition . ' \
|
671
|
+
f' ?join_condition ?condition_term ?condition_value .' \
|
672
|
+
f' }}' \
|
673
|
+
f' }}' \
|
674
|
+
f' }}' \
|
675
|
+
f' OPTIONAL {{ ' \
|
676
|
+
f' ?parent_triples_map {R2RML_PREDICATE_OBJECT_MAP} ?parent_pom.' \
|
677
|
+
f' OPTIONAL {{?parent_pom {R2RML_SHORTCUT_PREDICATE} ?parent_predicate .}}' \
|
678
|
+
f' OPTIONAL {{ ?parent_pom {R2RML_PREDICATE} ?parent_predicate_bn.'\
|
679
|
+
f' ?parent_predicate_bn ?parent_predicate_term ?parent_predicate_value . }}' \
|
680
|
+
f' ?parent_pom {R2RML_OBJECT} ?parent_object .' \
|
681
|
+
f' ?parent_object {R2RML_PARENT_TRIPLESMAP} ?triples_map .' \
|
682
|
+
f' OPTIONAL {{ ' \
|
683
|
+
f' ?parent_object {R2RML_JOIN_CONDITION} ?parent_join_conditions . ' \
|
684
|
+
f' ?parent_join_conditions ?parent_condition_term ?parent_conditions_value .' \
|
685
|
+
f' }}' \
|
686
|
+
f' }} ' \
|
687
|
+
f' }}'
|
688
|
+
#print(query)
|
689
|
+
output_mappings.update(query)
|
690
|
+
|
691
|
+
elif entity_type == URIRef(OWL_OBJECT_PROPERTY_URI):
|
692
|
+
# Remove all predicate-object maps using this object property
|
693
|
+
query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
694
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
695
|
+
f' CONSTRUCT {{' \
|
696
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} ?pom.' \
|
697
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} <{entity}> .' \
|
698
|
+
f' ?pom {R2RML_OBJECT} ?objectMap.' \
|
699
|
+
f' ?objectMap {R2RML_PARENT_TRIPLESMAP} ?parentTriplesMap . ' \
|
700
|
+
f' ?objectMap {R2RML_JOIN_CONDITION} ?joinConditions . ' \
|
701
|
+
f' ?joinConditions ?conditions ?condition_values }} ' \
|
702
|
+
f' WHERE {{' \
|
703
|
+
f' ?triplesMap {R2RML_SUBJECT} ?subjectMap.' \
|
704
|
+
f' ?subjectMap {R2RML_CLASS} ?domain . ' \
|
705
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} ?pom .' \
|
706
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} <{entity}> .' \
|
707
|
+
f' ?pom {R2RML_OBJECT} ?objectMap .' \
|
708
|
+
f' ?objectMap {R2RML_PARENT_TRIPLESMAP} ?parentTriplesMap .' \
|
709
|
+
f' ?parent_triplesMap {R2RML_SUBJECT} ?parent_subjectMap . ' \
|
710
|
+
f' ?parent_subjectMap {R2RML_CLASS} ?range. ' \
|
711
|
+
f' OPTIONAL {{ ?objectMap {R2RML_JOIN_CONDITION} ?joinConditions .' \
|
712
|
+
f' ?joinConditions ?conditions ?condition_values }} . }}'
|
713
|
+
#print(query)
|
714
|
+
deprecated_triples=output_mappings.query(query)
|
715
|
+
for row in deprecated_triples:
|
716
|
+
deprecated_mappings.add(row)
|
717
|
+
query= f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
718
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
719
|
+
f' DELETE {{' \
|
720
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} ?pom.' \
|
721
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} <{entity}> .' \
|
722
|
+
f' ?pom {R2RML_OBJECT} ?objectMap.' \
|
723
|
+
f' ?objectMap {R2RML_PARENT_TRIPLESMAP} ?parentTriplesMap . ' \
|
724
|
+
f' ?objectMap {R2RML_JOIN_CONDITION} ?joinConditions . ' \
|
725
|
+
f' ?joinConditions ?conditions ?condition_values }} ' \
|
726
|
+
f' WHERE {{' \
|
727
|
+
f' ?triplesMap {R2RML_SUBJECT} ?subjectMap.' \
|
728
|
+
f' ?subjectMap {R2RML_CLASS} ?domain . ' \
|
729
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} ?pom .' \
|
730
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} <{entity}> .' \
|
731
|
+
f' ?pom {R2RML_OBJECT} ?objectMap .' \
|
732
|
+
f' ?objectMap {R2RML_PARENT_TRIPLESMAP} ?parentTriplesMap .' \
|
733
|
+
f' ?parent_triplesMap {R2RML_SUBJECT} ?parent_subjectMap . ' \
|
734
|
+
f' ?parent_subjectMap {R2RML_CLASS} ?range. ' \
|
735
|
+
f' OPTIONAL {{ ?objectMap {R2RML_JOIN_CONDITION} ?joinConditions .' \
|
736
|
+
f' ?joinConditions ?conditions ?condition_values }} . }}'
|
737
|
+
#print(query)
|
738
|
+
output_mappings.update(query)
|
739
|
+
|
740
|
+
elif entity_type == URIRef(OWL_DATA_PROPERTY_URI):
|
741
|
+
# Remove all predicate-object maps using this data property
|
742
|
+
query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
743
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
744
|
+
f' CONSTRUCT {{' \
|
745
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} ?pom.' \
|
746
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} <{entity}> .' \
|
747
|
+
f' ?pom {R2RML_SHORTCUT_OBJECT} ?object.' \
|
748
|
+
f' ?pom {R2RML_OBJECT} ?objectMap.' \
|
749
|
+
f' ?objectMap ?object_term ?objectValue .}}' \
|
750
|
+
f' WHERE {{' \
|
751
|
+
f' ?triplesMap {R2RML_SUBJECT} ?subjectMap.' \
|
752
|
+
f' ?subjectMap {R2RML_CLASS} ?domain . ' \
|
753
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} ?pom .' \
|
754
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} <{entity}> .' \
|
755
|
+
f' OPTIONAL {{?pom {R2RML_SHORTCUT_OBJECT} ?object .}}' \
|
756
|
+
f' OPTIONAL {{ '\
|
757
|
+
f' ?pom {R2RML_OBJECT} ?objectMap .' \
|
758
|
+
f' ?objectMap ?object_term ?objectValue.' \
|
759
|
+
f' OPTIONAL {{ ?objectMap {R2RML_DATATYPE} ?range}} }} . }}'
|
760
|
+
deprecated_triples=output_mappings.query(query)
|
761
|
+
for row in deprecated_triples:
|
762
|
+
deprecated_mappings.add(row)
|
763
|
+
query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
764
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
765
|
+
f' DELETE {{' \
|
766
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} ?pom.' \
|
767
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} <{entity}> .' \
|
768
|
+
f' ?pom {R2RML_SHORTCUT_OBJECT} ?object.' \
|
769
|
+
f' ?pom {R2RML_OBJECT} ?objectMap.' \
|
770
|
+
f' ?objectMap ?object_term ?objectValue .}}' \
|
771
|
+
f' WHERE {{' \
|
772
|
+
f' ?triplesMap {R2RML_SUBJECT} ?subjectMap.' \
|
773
|
+
f' ?subjectMap {R2RML_CLASS} ?domain . ' \
|
774
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} ?pom .' \
|
775
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} <{entity}> .' \
|
776
|
+
f' OPTIONAL {{?pom {R2RML_SHORTCUT_OBJECT} ?object .}}' \
|
777
|
+
f' OPTIONAL {{ '\
|
778
|
+
f' ?pom {R2RML_OBJECT} ?objectMap .' \
|
779
|
+
f' ?objectMap ?object_term ?objectValue.' \
|
780
|
+
f' OPTIONAL {{ ?objectMap {R2RML_DATATYPE} ?range}} }} . }}'
|
781
|
+
output_mappings.update(query)
|
782
|
+
|
783
|
+
def revoke_deprecate_entity_rml(change, change_data, output_mappings, deprecated_mappings, ontology):
|
784
|
+
"""
|
785
|
+
Reverts the deprecation of an entity in the knowledge graph by restoring its triples map and its subject from deprecated_mappings.
|
786
|
+
Args:
|
787
|
+
change: the URI of the change which needs to be of the type revoke_deprecate_entity
|
788
|
+
"""
|
789
|
+
query = f' SELECT DISTINCT ?entity WHERE {{ ' \
|
790
|
+
f' <{change}> {OCH_UNDEPRECATED_ELEMENT} ?entity. }}'
|
791
|
+
#print(query)
|
792
|
+
for result in change_data.query(query):
|
793
|
+
entity = result["entity"]
|
794
|
+
query = f' SELECT DISTINCT ?type WHERE {{ ' \
|
795
|
+
f' <{entity}> {RDF_TYPE} ?type. }}'
|
796
|
+
#print(query)
|
797
|
+
for result in ontology.query(query):
|
798
|
+
entity_type = result["type"]
|
799
|
+
#print(f'Entity type: {entity_type}')
|
800
|
+
if entity_type == URIRef(OWL_CLASS_URI):
|
801
|
+
# Restore the triples map for the class entity from deprecated_mappings to output_mappings
|
802
|
+
query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
803
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
804
|
+
f' CONSTRUCT {{' \
|
805
|
+
f' ?triples_map {RDF_TYPE} {R2RML_TRIPLES_MAP}.' \
|
806
|
+
f' ?triples_map {R2RML_SUBJECT} ?subject.' \
|
807
|
+
f' ?subject ?subject_term ?subject_value .' \
|
808
|
+
f' ?subject {R2RML_CLASS} <{entity}> .' \
|
809
|
+
f' ?triples_map {RML_LOGICAL_SOURCE} ?logical_source .' \
|
810
|
+
f' ?logical_source ?logical_source_term ?logical_source_value .' \
|
811
|
+
f' ?triples_map {R2RML_PREDICATE_OBJECT_MAP} ?pom. ' \
|
812
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} ?predicate . ' \
|
813
|
+
f' ?pom {R2RML_PREDICATE} ?predicate_bn . ' \
|
814
|
+
f' ?predicate_bn ?predicate_term ?predicate_value . ' \
|
815
|
+
f' ?pom {R2RML_SHORTCUT_OBJECT} ?object. ' \
|
816
|
+
f' ?pom {R2RML_OBJECT} ?object_bn . ' \
|
817
|
+
f' ?object_bn ?object_term ?object_value.' \
|
818
|
+
f' ?object_bn {R2RML_PARENT_TRIPLESMAP} ?parent_tm . ' \
|
819
|
+
f' ?object_bn {R2RML_JOIN_CONDITION} ?join_condition . ' \
|
820
|
+
f' ?join_condition ?condition_term ?condition_value . ' \
|
821
|
+
f' ?parent_triples_map {R2RML_PREDICATE_OBJECT_MAP} ?parent_pom . ' \
|
822
|
+
f' ?parent_pom {R2RML_SHORTCUT_PREDICATE} ?parent_predicate .' \
|
823
|
+
f' ?parent_pom {R2RML_PREDICATE} ?parent_predicate_bn .' \
|
824
|
+
f' ?parent_predicate_bn ?parent_predicate_term ?parent_predicate_value .' \
|
825
|
+
f' ?parent_pom {R2RML_OBJECT} ?parent_object . ' \
|
826
|
+
f' ?parent_object {R2RML_PARENT_TRIPLESMAP} ?triples_map . ' \
|
827
|
+
f' ?parent_object {R2RML_JOIN_CONDITION} ?parent_join_conditions . ' \
|
828
|
+
f' ?parent_join_conditions ?parent_condition_term ?parent_conditions_value .}} ' \
|
829
|
+
f' WHERE {{ ' \
|
830
|
+
f' ?triples_map {RDF_TYPE} {R2RML_TRIPLES_MAP}.' \
|
831
|
+
f' ?triples_map {R2RML_SUBJECT} ?subject.' \
|
832
|
+
f' ?subject ?subject_term ?subject_value .' \
|
833
|
+
f' ?subject {R2RML_CLASS} <{entity}> .' \
|
834
|
+
f' ?triples_map {RML_LOGICAL_SOURCE} ?logical_source .' \
|
835
|
+
f' ?logical_source ?logical_source_term ?logical_source_value .' \
|
836
|
+
f' OPTIONAL {{ ' \
|
837
|
+
f' ?triples_map {R2RML_PREDICATE_OBJECT_MAP} ?pom.' \
|
838
|
+
f' OPTIONAL {{?pom {R2RML_SHORTCUT_PREDICATE} ?predicate . }}' \
|
839
|
+
f' OPTIONAL {{ ?pom {R2RML_PREDICATE} ?predicate_bn.'\
|
840
|
+
f' ?predicate_bn ?predicate_term ?predicate_value . }}' \
|
841
|
+
f' OPTIONAL {{?pom {R2RML_SHORTCUT_OBJECT} ?object .}}' \
|
842
|
+
f' OPTIONAL {{?pom {R2RML_OBJECT} ?object_bn .' \
|
843
|
+
f' ?object_bn ?object_term ?object_value. }}' \
|
844
|
+
f' OPTIONAL {{' \
|
845
|
+
f' ?object_bn {R2RML_PARENT_TRIPLESMAP} ?parent_tm .' \
|
846
|
+
f' OPTIONAL {{ ' \
|
847
|
+
f' ?object_bn {R2RML_JOIN_CONDITION} ?join_condition . ' \
|
848
|
+
f' ?join_condition ?condition_term ?condition_value .' \
|
849
|
+
f' }}' \
|
850
|
+
f' }}' \
|
851
|
+
f' }}' \
|
852
|
+
f' OPTIONAL {{ ' \
|
853
|
+
f' ?parent_triples_map {R2RML_PREDICATE_OBJECT_MAP} ?parent_pom.' \
|
854
|
+
f' OPTIONAL {{?parent_pom {R2RML_SHORTCUT_PREDICATE} ?parent_predicate .}}' \
|
855
|
+
f' OPTIONAL {{ ?parent_pom {R2RML_PREDICATE} ?parent_predicate_bn.'\
|
856
|
+
f' ?parent_predicate_bn ?parent_predicate_term ?parent_predicate_value . }}' \
|
857
|
+
f' ?parent_pom {R2RML_OBJECT} ?parent_object .' \
|
858
|
+
f' ?parent_object {R2RML_PARENT_TRIPLESMAP} ?triples_map .' \
|
859
|
+
f' OPTIONAL {{ ' \
|
860
|
+
f' ?parent_object {R2RML_JOIN_CONDITION} ?parent_join_conditions . ' \
|
861
|
+
f' ?parent_join_conditions ?parent_condition_term ?parent_conditions_value .' \
|
862
|
+
f' }}' \
|
863
|
+
f' }} ' \
|
864
|
+
f' }}'
|
865
|
+
#print(query)
|
866
|
+
restored_triples = deprecated_mappings.query(query)
|
867
|
+
for row in restored_triples:
|
868
|
+
output_mappings.add(row)
|
869
|
+
# Remove from deprecated_mappings
|
870
|
+
deprecated_mappings.update(query.replace("CONSTRUCT", "DELETE", 1))
|
871
|
+
elif entity_type == URIRef(OWL_OBJECT_PROPERTY_URI):
|
872
|
+
# Restore all predicate-object maps using this object property
|
873
|
+
query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
874
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
875
|
+
f' CONSTRUCT {{' \
|
876
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} ?pom.' \
|
877
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} <{entity}> .' \
|
878
|
+
f' ?pom {R2RML_OBJECT} ?objectMap.' \
|
879
|
+
f' ?objectMap {R2RML_PARENT_TRIPLESMAP} ?parentTriplesMap . ' \
|
880
|
+
f' ?objectMap {R2RML_JOIN_CONDITION} ?joinConditions . ' \
|
881
|
+
f' ?joinConditions ?conditions ?condition_values }} ' \
|
882
|
+
f' WHERE {{' \
|
883
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} ?pom .' \
|
884
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} <{entity}> .' \
|
885
|
+
f' ?pom {R2RML_OBJECT} ?objectMap .' \
|
886
|
+
f' ?objectMap {R2RML_PARENT_TRIPLESMAP} ?parentTriplesMap .' \
|
887
|
+
f' OPTIONAL {{ ?objectMap {R2RML_JOIN_CONDITION} ?joinConditions .' \
|
888
|
+
f' ?joinConditions ?conditions ?condition_values }} . }}'
|
889
|
+
#print(query)
|
890
|
+
restored_triples = deprecated_mappings.query(query)
|
891
|
+
for row in restored_triples:
|
892
|
+
output_mappings.add(row)
|
893
|
+
deprecated_mappings.update(query.replace("CONSTRUCT", "DELETE", 1))
|
894
|
+
elif entity_type == URIRef(OWL_DATA_PROPERTY_URI):
|
895
|
+
# Restore all predicate-object maps using this data property
|
896
|
+
query = f' PREFIX {R2RML_PREFIX}: <{R2RML_URI}>' \
|
897
|
+
f' PREFIX {RML_PREFIX}: <{RML_URI}>' \
|
898
|
+
f' CONSTRUCT {{' \
|
899
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} ?pom.' \
|
900
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} <{entity}> .' \
|
901
|
+
f' ?pom {R2RML_SHORTCUT_OBJECT} ?object.' \
|
902
|
+
f' ?pom {R2RML_OBJECT} ?objectMap.' \
|
903
|
+
f' ?objectMap ?object_term ?objectValue .}}' \
|
904
|
+
f' WHERE {{' \
|
905
|
+
f' ?triplesMap {R2RML_PREDICATE_OBJECT_MAP} ?pom .' \
|
906
|
+
f' ?pom {R2RML_SHORTCUT_PREDICATE} <{entity}> .' \
|
907
|
+
f' OPTIONAL {{?pom {R2RML_SHORTCUT_OBJECT} ?object .}}' \
|
908
|
+
f' OPTIONAL {{ '\
|
909
|
+
f' ?pom {R2RML_OBJECT} ?objectMap .' \
|
910
|
+
f' ?objectMap ?object_term ?objectValue.' \
|
911
|
+
f' OPTIONAL {{ ?objectMap {R2RML_DATATYPE} ?range}} }} . }}'
|
912
|
+
#print(query)
|
913
|
+
restored_triples = deprecated_mappings.query(query)
|
914
|
+
for row in restored_triples:
|
915
|
+
output_mappings.add(row)
|
916
|
+
deprecated_mappings.update(query.replace("CONSTRUCT", "DELETE", 1))
|
917
|
+
|
918
|
+
def rename_entity(change, change_data, output_mappings):
|
919
|
+
"""
|
920
|
+
Renames a term (class, property, etc.) in the output_mappings.
|
921
|
+
Args:
|
922
|
+
change: the URI of the change which needs to be of the type RenameEntity
|
923
|
+
"""
|
924
|
+
query = f'SELECT DISTINCT ?old_entity ?new_entity WHERE {{ ' \
|
925
|
+
f'<{change}> {OCH_OLD_NAME} ?old_entity. ' \
|
926
|
+
f'<{change}> {OCH_NEW_NAME} ?new_entity. }}'
|
927
|
+
for result in change_data.query(query):
|
928
|
+
old_entity = result["old_entity"]
|
929
|
+
new_entity = result["new_entity"]
|
930
|
+
# Update all triples where old_entity appears as subject, predicate, or object
|
931
|
+
update_query = f' DELETE {{ ?s ?p ?o. }} ' \
|
932
|
+
f' INSERT {{ ?s_new ?p_new ?o_new. }} ' \
|
933
|
+
f' WHERE {{ ' \
|
934
|
+
f' ?s ?p ?o. ' \
|
935
|
+
f' BIND(IF(?s = <{old_entity}>, <{new_entity}>, ?s) AS ?s_new) ' \
|
936
|
+
f' BIND(IF(?p = <{old_entity}>, <{new_entity}>, ?p) AS ?p_new) ' \
|
937
|
+
f' BIND(IF(?o = <{old_entity}>, <{new_entity}>, ?o) AS ?o_new) ' \
|
938
|
+
f' FILTER(?s != ?s_new || ?p != ?p_new || ?o != ?o_new) ' \
|
939
|
+
f' }}'
|
940
|
+
output_mappings.update(update_query)
|
941
|
+
|
942
|
+
#---------------------------------------SHACL CHANGES-------------------------------------------------------------
|
943
|
+
|
944
|
+
|
945
|
+
def deprecate_entity_shacl(change,change_data,output_shacl):
|
946
|
+
"""
|
947
|
+
Deprecates an entity in the SHACL shape by adding the "sh:deactivated true" to the corresponding shape.
|
948
|
+
Args:
|
949
|
+
change: the URI of the change which needs to be of the type deprecate_entity
|
950
|
+
"""
|
951
|
+
query = f' SELECT DISTINCT ?entity WHERE {{ ' \
|
952
|
+
f' <{change}> {OCH_DEPRECATED_ENTITY} ?entity. }}'
|
953
|
+
#print(query)
|
954
|
+
for result in change_data.query(query):
|
955
|
+
entity = result["entity"]
|
956
|
+
query = (
|
957
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}> '
|
958
|
+
f' INSERT {{ '
|
959
|
+
f' ?shape {SHACL_DEACTIVATED} true . '
|
960
|
+
f' }} '
|
961
|
+
f' WHERE {{ '
|
962
|
+
f' {{ '
|
963
|
+
f' ?shape a {SHACL_NODE_SHAPE} ; '
|
964
|
+
f' {SHACL_TARGET_CLASS} <{entity}> . '
|
965
|
+
f' }} '
|
966
|
+
f' UNION '
|
967
|
+
f' {{ '
|
968
|
+
f' ?shape {SHACL_PATH} <{entity}> . '
|
969
|
+
f' }} '
|
970
|
+
f' FILTER NOT EXISTS {{ ?shape {SHACL_DEACTIVATED} true }} '
|
971
|
+
f' }}'
|
972
|
+
)
|
973
|
+
#print(query)
|
974
|
+
output_shacl.update(query)
|
975
|
+
|
976
|
+
#-----------------------------------------------------------------------------------------------------------------
|
977
|
+
|
978
|
+
def revoke_deprecate_entity_shacl(change,change_data,output_shacl):
|
979
|
+
"""
|
980
|
+
Revokes the deprecation of an entity in the SHACL shape by removing the "sh:deactivated true" from the corresponding shape.
|
981
|
+
Args:
|
982
|
+
change: the URI of the change which needs to be of the type revoke_deprecate_entity
|
983
|
+
"""
|
984
|
+
query = f' SELECT DISTINCT ?entity WHERE {{ ' \
|
985
|
+
f' <{change}> {OCH_UNDEPRECATED_ELEMENT} ?entity. }}'
|
986
|
+
#print(query)
|
987
|
+
for result in change_data.query(query):
|
988
|
+
entity = result["entity"]
|
989
|
+
query = (
|
990
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}> '
|
991
|
+
f' DELETE {{ '
|
992
|
+
f' ?shape {SHACL_DEACTIVATED} true . '
|
993
|
+
f' }} '
|
994
|
+
f' WHERE {{ '
|
995
|
+
f' {{ '
|
996
|
+
f' ?shape a {SHACL_NODE_SHAPE} ; '
|
997
|
+
f' {SHACL_TARGET_CLASS} <{entity}> . '
|
998
|
+
f' }} '
|
999
|
+
f' UNION '
|
1000
|
+
f' {{ '
|
1001
|
+
f' ?shape {SHACL_PATH} <{entity}> . '
|
1002
|
+
f' }} '
|
1003
|
+
f' }}'
|
1004
|
+
)
|
1005
|
+
#print(query)
|
1006
|
+
output_shacl.update(query)
|
1007
|
+
|
1008
|
+
#-----------------------------------------------------------------------------------------------------------------
|
1009
|
+
|
1010
|
+
def add_class_shacl(change, change_data, output_shapes):
|
1011
|
+
"""
|
1012
|
+
Adds a class defined in the change KG into the shacl shape. This takes the form of adding NodeShape with the class as targetClass.
|
1013
|
+
Args:
|
1014
|
+
change: the URI of the change which needs to be of the type AddClass
|
1015
|
+
Returns:
|
1016
|
+
the output_shapes updated with a new class
|
1017
|
+
"""
|
1018
|
+
select_change = f' SELECT DISTINCT ?class WHERE {{' \
|
1019
|
+
f' <{change}> {OCH_ADDED_CLASS} ?class .}} '
|
1020
|
+
|
1021
|
+
for result in change_data.query(select_change):
|
1022
|
+
added_class = result["class"]
|
1023
|
+
if "#" in added_class:
|
1024
|
+
class_local = added_class.split("#")[-1]
|
1025
|
+
elif "/" in added_class:
|
1026
|
+
class_local = added_class.split("/")[-1]
|
1027
|
+
else:
|
1028
|
+
class_local = added_class
|
1029
|
+
insert_class_query = (
|
1030
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1031
|
+
f' INSERT DATA {{ '
|
1032
|
+
f' <{EXAMPLE_URI}{class_local}Shape> '
|
1033
|
+
f' a {SHACL_NODE_SHAPE} ; '
|
1034
|
+
f' {SHACL_TARGET_CLASS} <{added_class}> ; '
|
1035
|
+
f' }}'
|
1036
|
+
)
|
1037
|
+
#print(insert_class_query)
|
1038
|
+
output_shapes.update(insert_class_query)
|
1039
|
+
|
1040
|
+
def remove_class_shacl(change, change_data, output_mappings):
|
1041
|
+
"""
|
1042
|
+
Removes a class defined in the change KG from the SHACL shape. This deletes the NodeShape with the class as targetClass and all related property shapes and nested shapes.
|
1043
|
+
Args:
|
1044
|
+
change: the URI of the change which needs to be of the type RemoveClass
|
1045
|
+
Returns:
|
1046
|
+
the output_shapes updated with the class and its related shapes removed
|
1047
|
+
"""
|
1048
|
+
select_change = f' SELECT DISTINCT ?class WHERE {{' \
|
1049
|
+
f' <{change}> {OCH_DELETED_CLASS} ?class .}} '
|
1050
|
+
|
1051
|
+
for result in change_data.query(select_change):
|
1052
|
+
removed_class = result["class"]
|
1053
|
+
delete_class_query = (
|
1054
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>\n'
|
1055
|
+
f' PREFIX {RDF_PREFIX}: <{RDF_URI}>\n'
|
1056
|
+
f' DELETE {{\n'
|
1057
|
+
f' ?shape ?p ?o .\n'
|
1058
|
+
f' ?propShape ?pp ?po .\n'
|
1059
|
+
f' ?list ?lp ?lo .\n'
|
1060
|
+
f' ?listItem ?listItemP ?listItemO .\n'
|
1061
|
+
f' ?restNode ?restP ?restO .\n'
|
1062
|
+
f' }}\n'
|
1063
|
+
f' WHERE {{\n'
|
1064
|
+
f' ?shape a {SHACL_NODE_SHAPE} ;\n'
|
1065
|
+
f' {SHACL_TARGET_CLASS} <{removed_class}> ;\n'
|
1066
|
+
f' ?p ?o .\n'
|
1067
|
+
f' OPTIONAL {{\n'
|
1068
|
+
f' ?shape {SHACL_PROPERTY_SHAPE} ?propShape .\n'
|
1069
|
+
f' FILTER (isBlank(?propShape))\n'
|
1070
|
+
f' ?propShape ?pp ?po .\n'
|
1071
|
+
f' OPTIONAL {{\n'
|
1072
|
+
f' ?propShape ?listPred ?list .\n'
|
1073
|
+
f' FILTER(?listPred IN ({SHACL_IN}, {SHACL_OR}, {SHACL_AND}, {SHACL_XONE}))\n'
|
1074
|
+
f' ?list {RDF_REST}*/{RDF_FIRST} ?listItem .\n'
|
1075
|
+
f' ?list ?lp ?lo .\n'
|
1076
|
+
f' OPTIONAL {{ ?listItem ?listItemP ?listItemO . }}\n'
|
1077
|
+
f' ?list {RDF_REST}* ?restNode .\n'
|
1078
|
+
f' ?restNode ?restP ?restO .\n'
|
1079
|
+
f' }}\n'
|
1080
|
+
f' }}\n'
|
1081
|
+
f' }}'
|
1082
|
+
)
|
1083
|
+
#print(delete_class_query)
|
1084
|
+
output_mappings.update(delete_class_query)
|
1085
|
+
|
1086
|
+
|
1087
|
+
def add_super_class_shacl(change, change_data, output_shapes):
|
1088
|
+
"""
|
1089
|
+
Adds a subclass to the SHACL NodeShape of the superclass by inserting the subclas as an additional sh:targetClass.
|
1090
|
+
Args:
|
1091
|
+
change: the URI of the change which needs to be of the type add_sub_class
|
1092
|
+
Returns:
|
1093
|
+
The output_shapes updated with the NodeShape of the superclass including the subclass as targetClass.
|
1094
|
+
"""
|
1095
|
+
query = (
|
1096
|
+
f' SELECT DISTINCT ?super_class ?sub_class WHERE {{ '
|
1097
|
+
f' <{change}> {OCH_ADD_SUBCLASS_SOURCE} ?sub_class. '
|
1098
|
+
f' <{change}> {OCH_ADD_SUBCLASS_TARGET} ?super_class. }}'
|
1099
|
+
)
|
1100
|
+
for result in change_data.query(query):
|
1101
|
+
sub_class = result["sub_class"]
|
1102
|
+
super_class = result["super_class"]
|
1103
|
+
insert_super_class_query = (
|
1104
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1105
|
+
f' INSERT {{ '
|
1106
|
+
f' ?shape {SHACL_TARGET_CLASS} <{sub_class}> . '
|
1107
|
+
f' }} '
|
1108
|
+
f' WHERE {{ '
|
1109
|
+
f' ?shape a {SHACL_NODE_SHAPE} ; '
|
1110
|
+
f' {SHACL_TARGET_CLASS} <{super_class}> . '
|
1111
|
+
f' FILTER NOT EXISTS {{ ?shape {SHACL_TARGET_CLASS} <{sub_class}> }} '
|
1112
|
+
f' }}'
|
1113
|
+
)
|
1114
|
+
output_shapes.update(insert_super_class_query)
|
1115
|
+
|
1116
|
+
def remove_super_class_shacl(change, change_data, output_shapes):
|
1117
|
+
"""
|
1118
|
+
Removes a subclass from the SHACL NodeShape of the superclass by deleting the subclass from sh:targetClass.
|
1119
|
+
Args:
|
1120
|
+
change: the URI of the change which needs to be of the type add_sub_class
|
1121
|
+
Returns:
|
1122
|
+
The output_shapes updated with the NodeShape of the superclass not including the subclass as targetClass.
|
1123
|
+
"""
|
1124
|
+
query = (
|
1125
|
+
f' SELECT DISTINCT ?super_class ?sub_class WHERE {{ '
|
1126
|
+
f' <{change}> {OCH_REMOVE_SUBCLASS_SOURCE} ?sub_class. '
|
1127
|
+
f' <{change}> {OCH_REMOVE_SUBCLASS_TARGET} ?super_class. }}'
|
1128
|
+
)
|
1129
|
+
for result in change_data.query(query):
|
1130
|
+
sub_class = result["sub_class"]
|
1131
|
+
super_class = result["super_class"]
|
1132
|
+
remove_super_class_query = (
|
1133
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1134
|
+
f' DELETE {{ '
|
1135
|
+
f' ?shape {SHACL_TARGET_CLASS} <{sub_class}> . '
|
1136
|
+
f' }} '
|
1137
|
+
f' WHERE {{ '
|
1138
|
+
f' ?shape a {SHACL_NODE_SHAPE} ; '
|
1139
|
+
f' {SHACL_TARGET_CLASS} <{super_class}>, <{sub_class}> . '
|
1140
|
+
f' }}'
|
1141
|
+
)
|
1142
|
+
output_shapes.update(remove_super_class_query)
|
1143
|
+
|
1144
|
+
def add_equivalent_class_shacl(change, change_data, output_shapes):
|
1145
|
+
"""
|
1146
|
+
Adds an equivalent class to the SHACL NodeShape of the class by inserting the equivalent class as an additional sh:targetClass.
|
1147
|
+
Args:
|
1148
|
+
change: the URI of the change which needs to be of the type add_equivalent_class
|
1149
|
+
Returns:
|
1150
|
+
The output_shapes updated with the NodeShape of the class including the equivalent class as targetClass.
|
1151
|
+
"""
|
1152
|
+
query = (
|
1153
|
+
f' SELECT DISTINCT ?source_class ?target_class WHERE {{ '
|
1154
|
+
f' <{change}> {OCH_ADD_EQUIVALENT_CLASS_SOURCE} ?source_class. '
|
1155
|
+
f' <{change}> {OCH_ADD_EQUIVALENT_CLASS_TARGET} ?target_class. }}'
|
1156
|
+
)
|
1157
|
+
for result in change_data.query(query):
|
1158
|
+
source_class = result["source_class"]
|
1159
|
+
target_class = result["target_class"]
|
1160
|
+
insert_equivalent_class_query = (
|
1161
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1162
|
+
f' PREFIX {PROV_PREFIX}: <{PROV_URI}>'
|
1163
|
+
f' INSERT {{ '
|
1164
|
+
f' ?shape {SHACL_TARGET_CLASS} ?otherClass . '
|
1165
|
+
f' ?shape {PROV_WAS_DERIVED_FROM} ?originalClass . '
|
1166
|
+
f' }} '
|
1167
|
+
f' WHERE {{ '
|
1168
|
+
f' ?shape a {SHACL_NODE_SHAPE} ; '
|
1169
|
+
f' {SHACL_TARGET_CLASS} ?originalClass . '
|
1170
|
+
f' VALUES (?originalClass ?otherClass) {{ '
|
1171
|
+
f' (<{source_class}> <{target_class}>) '
|
1172
|
+
f' (<{target_class}> <{source_class}>) '
|
1173
|
+
f' }} '
|
1174
|
+
f' FILTER NOT EXISTS {{ ?shape {SHACL_TARGET_CLASS} ?otherClass }} '
|
1175
|
+
f' }}'
|
1176
|
+
)
|
1177
|
+
#print(insert_equivalent_class_query)
|
1178
|
+
output_shapes.update(insert_equivalent_class_query)
|
1179
|
+
|
1180
|
+
def remove_equivalent_class_shacl(change, change_data, output_shapes):
|
1181
|
+
"""
|
1182
|
+
Removes an equivalent class from the SHACL NodeShape of the class by deleting the equivalent class from the sh:targetClass.
|
1183
|
+
Args:
|
1184
|
+
change: the URI of the change which needs to be of the type remove_equivalent_class
|
1185
|
+
Returns:
|
1186
|
+
The output_shapes updated with the NodeShape of the class excluding the equivalent class as targetClass.
|
1187
|
+
"""
|
1188
|
+
query = (
|
1189
|
+
f' SELECT DISTINCT ?source_class ?target_class WHERE {{ '
|
1190
|
+
f' <{change}> {OCH_REMOVE_EQUIVALENT_CLASS_SOURCE} ?source_class. '
|
1191
|
+
f' <{change}> {OCH_REMOVE_EQUIVALENT_CLASS_TARGET} ?target_class. }}'
|
1192
|
+
)
|
1193
|
+
for result in change_data.query(query):
|
1194
|
+
source_class = result["source_class"]
|
1195
|
+
target_class = result["target_class"]
|
1196
|
+
delete_equivalent_class_query = (
|
1197
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>\n'
|
1198
|
+
f' PREFIX {PROV_PREFIX}: <{PROV_URI}>\n'
|
1199
|
+
f' DELETE {{\n'
|
1200
|
+
f' ?shape {SHACL_TARGET_CLASS} ?otherClass .\n'
|
1201
|
+
f' ?shape {PROV_WAS_DERIVED_FROM} ?originalClass .\n'
|
1202
|
+
f' }}\n'
|
1203
|
+
f' WHERE {{\n'
|
1204
|
+
f' ?shape a {SHACL_NODE_SHAPE} ;\n'
|
1205
|
+
f' {SHACL_TARGET_CLASS} ?originalClass, ?otherClass ;\n'
|
1206
|
+
f' {PROV_WAS_DERIVED_FROM} ?originalClass .\n'
|
1207
|
+
f' VALUES (?originalClass ?otherClass) {{\n'
|
1208
|
+
f' (<{source_class}> <{target_class}>)\n'
|
1209
|
+
f' (<{target_class}> <{source_class}>)\n'
|
1210
|
+
f' }}\n'
|
1211
|
+
f' }}'
|
1212
|
+
)
|
1213
|
+
#print(delete_equivalent_class_query)
|
1214
|
+
output_shapes.update(delete_equivalent_class_query)
|
1215
|
+
|
1216
|
+
|
1217
|
+
def add_disjoint_class_shacl(change, change_data, output_shapes):
|
1218
|
+
"""
|
1219
|
+
Adds a disjoint class restriction to the SHACL NodeShape via SHACL-SPARQL query.
|
1220
|
+
Args:
|
1221
|
+
change: the URI of the change which needs to be of the type add_disjoint_class
|
1222
|
+
Returns:
|
1223
|
+
The output_shapes updated with the constraints that enforce the disjointness of the classes.
|
1224
|
+
"""
|
1225
|
+
query = (
|
1226
|
+
f' SELECT DISTINCT ?source_class ?target_class WHERE {{ '
|
1227
|
+
f' <{change}> {OCH_ADD_DISJOINT_CLASS_SOURCE} ?source_class. '
|
1228
|
+
f' <{change}> {OCH_ADD_DISJOINT_CLASS_TARGET} ?target_class. }}'
|
1229
|
+
)
|
1230
|
+
for result in change_data.query(query):
|
1231
|
+
source_class = result["source_class"]
|
1232
|
+
target_class = result["target_class"]
|
1233
|
+
add_disjoint_class_query = (
|
1234
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>\n'
|
1235
|
+
f' INSERT {{\n'
|
1236
|
+
f' ?sourceShape {SHACL_NOT} [ {SHACL_CLASS} <{target_class}> ] .\n'
|
1237
|
+
f' ?targetShape {SHACL_NOT} [ {SHACL_CLASS} <{source_class}> ] .\n'
|
1238
|
+
f' }}\n'
|
1239
|
+
f' WHERE {{\n'
|
1240
|
+
f' ?sourceShape a {SHACL_NODE_SHAPE} ;\n'
|
1241
|
+
f' {SHACL_TARGET_CLASS} <{source_class}> .\n'
|
1242
|
+
f' ?targetShape a {SHACL_NODE_SHAPE} ;\n'
|
1243
|
+
f' {SHACL_TARGET_CLASS} <{target_class}> .\n'
|
1244
|
+
f'}}'
|
1245
|
+
)
|
1246
|
+
print(add_disjoint_class_query)
|
1247
|
+
output_shapes.update(add_disjoint_class_query)
|
1248
|
+
|
1249
|
+
def remove_disjoint_class_shacl(change, change_data, output_shapes):
|
1250
|
+
"""
|
1251
|
+
Removes a disjoint class restriction from the SHACL NodeShape via SHACL-SPARQL query.
|
1252
|
+
Args:
|
1253
|
+
change: the URI of the change which needs to be of the type remove_disjoint_class
|
1254
|
+
Returns:
|
1255
|
+
The output_shapes updated without the constraints that enforce the disjointness of the classes.
|
1256
|
+
"""
|
1257
|
+
query = (
|
1258
|
+
f' SELECT DISTINCT ?source_class ?target_class WHERE {{ '
|
1259
|
+
f' <{change}> {OCH_REMOVE_DISJOINT_CLASS_SOURCE} ?source_class. '
|
1260
|
+
f' <{change}> {OCH_REMOVE_DISJOINT_CLASS_TARGET} ?target_class. }}'
|
1261
|
+
)
|
1262
|
+
for result in change_data.query(query):
|
1263
|
+
source_class = result["source_class"]
|
1264
|
+
target_class = result["target_class"]
|
1265
|
+
remove_disjoint_class_query = (
|
1266
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>\n'
|
1267
|
+
f' DELETE {{\n'
|
1268
|
+
f' ?sourceShape {SHACL_NOT} ?propertyShapeSource.\n'
|
1269
|
+
f' ?propertyShapeSource {SHACL_CLASS} <{target_class}>.\n'
|
1270
|
+
f' ?targetShape {SHACL_NOT} ?propertyShapeTarget. \n'
|
1271
|
+
f' ?propertyShapeTarget {SHACL_CLASS} <{source_class}>.\n'
|
1272
|
+
f' }}\n'
|
1273
|
+
f' WHERE {{\n'
|
1274
|
+
f' ?sourceShape a {SHACL_NODE_SHAPE} ;\n'
|
1275
|
+
f' {SHACL_TARGET_CLASS} <{source_class}> .\n'
|
1276
|
+
f' ?targetShape a {SHACL_NODE_SHAPE} ;\n'
|
1277
|
+
f' {SHACL_TARGET_CLASS} <{target_class}> .\n'
|
1278
|
+
f' ?sourceShape {SHACL_NOT} ?propertyShapeSource.\n'
|
1279
|
+
f' ?propertyShapeSource {SHACL_CLASS} <{target_class}>.\n'
|
1280
|
+
f' ?targetShape {SHACL_NOT} ?propertyShapeTarget. \n'
|
1281
|
+
f' ?propertyShapeTarget {SHACL_CLASS} <{source_class}>.\n'
|
1282
|
+
f'}}'
|
1283
|
+
)
|
1284
|
+
#print(remove_disjoint_class_query)
|
1285
|
+
output_shapes.update(remove_disjoint_class_query)
|
1286
|
+
|
1287
|
+
def add_object_property_shacl(change,change_data, output_shapes):
|
1288
|
+
"""
|
1289
|
+
Adds an object property to the NodeShape indicated in the domain. For a full change in the Property Shape the domain, property and range additions are needed.
|
1290
|
+
Args:
|
1291
|
+
change: the URI of the change which needs to be of the type addObjectProperty
|
1292
|
+
Returns:
|
1293
|
+
the output_shapes updated with the added predicate object maps.
|
1294
|
+
"""
|
1295
|
+
query = f' SELECT DISTINCT ?domain ?property ?range WHERE {{ ' \
|
1296
|
+
f' <{change}> {OCH_ADDED_OBJECT_PROPERTY} ?property .' \
|
1297
|
+
f' ?domainchange {OCH_ADDED_DOMAIN_TO_PROPERTY} ?property.' \
|
1298
|
+
f' ?domainchange {OCH_ADDED_DOMAIN} ?domain.' \
|
1299
|
+
f' ?rangechange {OCH_ADDED_RANGE_TO_PROPERTY} ?property.' \
|
1300
|
+
f' ?rangechange {OCH_ADDED_OBJECT_RANGE} ?range. }}'
|
1301
|
+
|
1302
|
+
for result in change_data.query(query):
|
1303
|
+
property_domain = result["domain"]
|
1304
|
+
property_predicate = result["property"]
|
1305
|
+
property_range = result["range"]
|
1306
|
+
if "#" in property_predicate:
|
1307
|
+
property_local = property_predicate.split("#")[-1]
|
1308
|
+
elif "/" in property_predicate:
|
1309
|
+
property_local = property_predicate.split("/")[-1]
|
1310
|
+
else:
|
1311
|
+
property_local = property_predicate
|
1312
|
+
insert_object_property_query = (
|
1313
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1314
|
+
f' PREFIX {EXAMPLE_PREFIX}: <{EXAMPLE_URI}>'
|
1315
|
+
f' INSERT {{ '
|
1316
|
+
f' ?nodeShape {SHACL_PROPERTY} {EXAMPLE_PREFIX}:{property_local}Shape . '
|
1317
|
+
f' {EXAMPLE_PREFIX}:{property_local}Shape {SHACL_PATH} <{property_predicate}> ; '
|
1318
|
+
f' {SHACL_CLASS} <{property_range}> . '
|
1319
|
+
f' }} '
|
1320
|
+
f' WHERE {{ '
|
1321
|
+
f' ?nodeShape a {SHACL_NODE_SHAPE} ; '
|
1322
|
+
f' {SHACL_TARGET_CLASS} <{property_domain}> . '
|
1323
|
+
f' }}'
|
1324
|
+
)
|
1325
|
+
#print(insert_object_property_query)
|
1326
|
+
output_shapes.update(insert_object_property_query)
|
1327
|
+
|
1328
|
+
def remove_object_property_shacl(change, change_data, output_shapes):
|
1329
|
+
"""
|
1330
|
+
Removes an object property from the NodeShape indicated in the domain. For a full change in the Property Shape the domain, property and range removals are needed.
|
1331
|
+
Args:
|
1332
|
+
change: the URI of the change which needs to be of the type removeObjectProperty
|
1333
|
+
Returns:
|
1334
|
+
the output_shapes updated with the property shape removed.
|
1335
|
+
"""
|
1336
|
+
query = f' SELECT DISTINCT ?domain ?property ?range WHERE {{ ' \
|
1337
|
+
f' <{change}> {OCH_REMOVED_OBJECT_PROPERTY} ?property .' \
|
1338
|
+
f' ?domainchange {OCH_REMOVED_DOMAIN_TO_PROPERTY} ?property.' \
|
1339
|
+
f' ?domainchange {OCH_REMOVED_DOMAIN} ?domain.' \
|
1340
|
+
f' ?rangechange {OCH_REMOVED_RANGE_TO_PROPERTY} ?property.' \
|
1341
|
+
f' ?rangechange {OCH_REMOVED_OBJECT_RANGE} ?range. }}'
|
1342
|
+
|
1343
|
+
for result in change_data.query(query):
|
1344
|
+
property_domain = result["domain"]
|
1345
|
+
property_predicate = result["property"]
|
1346
|
+
property_range = result["range"]
|
1347
|
+
|
1348
|
+
# Remove property shape whether it is a blank node (sh:property) or a full PropertyShape (URI)
|
1349
|
+
delete_object_property_query = (
|
1350
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>\n'
|
1351
|
+
f' DELETE {{\n'
|
1352
|
+
f' ?nodeShape {SHACL_PROPERTY} ?propertyShape .\n'
|
1353
|
+
f' ?propertyShape {SHACL_PATH} <{property_predicate}> ;\n'
|
1354
|
+
f' {SHACL_CLASS} <{property_range}> .\n'
|
1355
|
+
f' ?propertyShape ?pp ?po .\n'
|
1356
|
+
f' ?list ?lp ?lo .\n'
|
1357
|
+
f' ?listItem ?listItemP ?listItemO .\n'
|
1358
|
+
f' ?restNode ?restP ?restO .\n'
|
1359
|
+
f' }}\n'
|
1360
|
+
f' WHERE {{\n'
|
1361
|
+
f' ?nodeShape a {SHACL_NODE_SHAPE} ;\n'
|
1362
|
+
f' {SHACL_TARGET_CLASS} <{property_domain}> ;\n'
|
1363
|
+
f' {SHACL_PROPERTY} ?propertyShape .\n'
|
1364
|
+
f' ?propertyShape {SHACL_PATH} <{property_predicate}> ;\n'
|
1365
|
+
f' {SHACL_CLASS} <{property_range}> .\n'
|
1366
|
+
f' OPTIONAL {{ ?propertyShape ?pp ?po .\n'
|
1367
|
+
f' OPTIONAL {{\n'
|
1368
|
+
f' ?propertyShape ?listPred ?list .\n'
|
1369
|
+
f' FILTER(?listPred IN ({SHACL_IN}, {SHACL_OR}, {SHACL_AND}, {SHACL_XONE}))\n'
|
1370
|
+
f' ?list {RDF_REST}*/{RDF_FIRST} ?listItem .\n'
|
1371
|
+
f' ?list ?lp ?lo .\n'
|
1372
|
+
f' OPTIONAL {{ ?listItem ?listItemP ?listItemO . }}\n'
|
1373
|
+
f' ?list {RDF_REST}* ?restNode .\n'
|
1374
|
+
f' ?restNode ?restP ?restO .\n'
|
1375
|
+
f' }}\n'
|
1376
|
+
f' }}\n'
|
1377
|
+
f'}}'
|
1378
|
+
)
|
1379
|
+
#print(delete_object_property_query)
|
1380
|
+
output_shapes.update(delete_object_property_query)
|
1381
|
+
|
1382
|
+
def add_data_property_shacl(change, change_data, output_shapes):
|
1383
|
+
"""
|
1384
|
+
Adds a data property to the NodeShape indicated in the domain. For a full change in the Property Shape the domain, property and range additions are needed.
|
1385
|
+
Args:
|
1386
|
+
change: the URI of the change which needs to be of the type addDataProperty
|
1387
|
+
Returns:
|
1388
|
+
the output_shapes updated with the added data property shape.
|
1389
|
+
"""
|
1390
|
+
query = f' SELECT DISTINCT ?domain ?property ?range WHERE {{ ' \
|
1391
|
+
f' <{change}> {OCH_ADDED_DATA_PROPERTY} ?property .' \
|
1392
|
+
f' ?domainchange {OCH_ADDED_DOMAIN_TO_PROPERTY} ?property.' \
|
1393
|
+
f' ?domainchange {OCH_ADDED_DOMAIN} ?domain.' \
|
1394
|
+
f' ?rangechange {OCH_ADDED_RANGE_TO_PROPERTY} ?property.' \
|
1395
|
+
f' ?rangechange {OCH_ADDED_DATA_RANGE} ?range. }}'
|
1396
|
+
|
1397
|
+
for result in change_data.query(query):
|
1398
|
+
property_domain = result["domain"]
|
1399
|
+
property_predicate = result["property"]
|
1400
|
+
property_range = result["range"]
|
1401
|
+
if "#" in property_predicate:
|
1402
|
+
property_local = property_predicate.split("#")[-1]
|
1403
|
+
elif "/" in property_predicate:
|
1404
|
+
property_local = property_predicate.split("/")[-1]
|
1405
|
+
else:
|
1406
|
+
property_local = property_predicate
|
1407
|
+
insert_data_property_query = (
|
1408
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1409
|
+
f' PREFIX {EXAMPLE_PREFIX}: <{EXAMPLE_URI}>'
|
1410
|
+
f' INSERT {{ '
|
1411
|
+
f' ?nodeShape {SHACL_PROPERTY} {EXAMPLE_PREFIX}:{property_local}Shape . '
|
1412
|
+
f' {EXAMPLE_PREFIX}:{property_local}Shape {SHACL_PATH} <{property_predicate}> ; '
|
1413
|
+
f' {SHACL_DATATYPE} <{property_range}> . '
|
1414
|
+
f' }} '
|
1415
|
+
f' WHERE {{ '
|
1416
|
+
f' ?nodeShape a {SHACL_NODE_SHAPE} ; '
|
1417
|
+
f' {SHACL_TARGET_CLASS} <{property_domain}> . '
|
1418
|
+
f' }}'
|
1419
|
+
)
|
1420
|
+
print(insert_data_property_query)
|
1421
|
+
output_shapes.update(insert_data_property_query)
|
1422
|
+
|
1423
|
+
def remove_data_property_shacl(change, change_data, output_shapes):
|
1424
|
+
"""
|
1425
|
+
Removes a data property from the NodeShape indicated in the domain. For a full change in the Property Shape the domain, property and range removals are needed.
|
1426
|
+
Args:
|
1427
|
+
change: the URI of the change which needs to be of the type removeDataProperty
|
1428
|
+
Returns:
|
1429
|
+
the output_shapes updated with the data property shape removed.
|
1430
|
+
"""
|
1431
|
+
query = f' SELECT DISTINCT ?domain ?property ?range WHERE {{ ' \
|
1432
|
+
f' <{change}> {OCH_REMOVED_DATA_PROPERTY} ?property .' \
|
1433
|
+
f' ?domainchange {OCH_REMOVED_DOMAIN_TO_PROPERTY} ?property.' \
|
1434
|
+
f' ?domainchange {OCH_REMOVED_DOMAIN} ?domain.' \
|
1435
|
+
f' ?rangechange {OCH_REMOVED_RANGE_TO_PROPERTY} ?property.' \
|
1436
|
+
f' ?rangechange {OCH_REMOVED_DATA_RANGE} ?range. }}'
|
1437
|
+
|
1438
|
+
for result in change_data.query(query):
|
1439
|
+
property_domain = result["domain"]
|
1440
|
+
property_predicate = result["property"]
|
1441
|
+
property_range = result["range"]
|
1442
|
+
|
1443
|
+
delete_data_property_query = (
|
1444
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>\n'
|
1445
|
+
f' DELETE {{\n'
|
1446
|
+
f' ?nodeShape {SHACL_PROPERTY} ?propertyShape .\n'
|
1447
|
+
f' ?propertyShape {SHACL_PATH} <{property_predicate}> ;\n'
|
1448
|
+
f' {SHACL_DATATYPE} <{property_range}> .\n'
|
1449
|
+
f' ?propertyShape ?pp ?po .\n'
|
1450
|
+
f' ?list ?lp ?lo .\n'
|
1451
|
+
f' ?listItem ?listItemP ?listItemO .\n'
|
1452
|
+
f' ?restNode ?restP ?restO .\n'
|
1453
|
+
f' }}\n'
|
1454
|
+
f' WHERE {{\n'
|
1455
|
+
f' ?nodeShape a {SHACL_NODE_SHAPE} ;\n'
|
1456
|
+
f' {SHACL_TARGET_CLASS} <{property_domain}> ;\n'
|
1457
|
+
f' {SHACL_PROPERTY} ?propertyShape .\n'
|
1458
|
+
f' ?propertyShape {SHACL_PATH} <{property_predicate}> ;\n'
|
1459
|
+
f' {SHACL_DATATYPE} <{property_range}> .\n'
|
1460
|
+
f' OPTIONAL {{ ?propertyShape ?pp ?po .\n'
|
1461
|
+
f' OPTIONAL {{\n'
|
1462
|
+
f' ?propertyShape ?listPred ?list .\n'
|
1463
|
+
f' FILTER(?listPred IN ({SHACL_IN}, {SHACL_OR}, {SHACL_AND}, {SHACL_XONE}))\n'
|
1464
|
+
f' ?list {RDF_REST}*/{RDF_FIRST} ?listItem .\n'
|
1465
|
+
f' ?list ?lp ?lo .\n'
|
1466
|
+
f' OPTIONAL {{ ?listItem ?listItemP ?listItemO . }}\n'
|
1467
|
+
f' ?list {RDF_REST}* ?restNode .\n'
|
1468
|
+
f' ?restNode ?restP ?restO .\n'
|
1469
|
+
f' }}\n'
|
1470
|
+
f' }}\n'
|
1471
|
+
f'}}'
|
1472
|
+
)
|
1473
|
+
print(delete_data_property_query)
|
1474
|
+
output_shapes.update(delete_data_property_query)
|
1475
|
+
|
1476
|
+
def add_characteristic_shacl(change, change_data, output_shapes):
|
1477
|
+
"""
|
1478
|
+
Modifies the property shape corresponding to a given property to add restrictions based on the added characteristic.
|
1479
|
+
Args:
|
1480
|
+
change: the URI of the change which needs to be of the type addCharacteristic
|
1481
|
+
Returns:
|
1482
|
+
the output_shapes updated with the data property shape modified.
|
1483
|
+
"""
|
1484
|
+
print("Entra en la función add_characteristic_shacl")
|
1485
|
+
query = f' SELECT DISTINCT ?property ?characteristic WHERE {{ ' \
|
1486
|
+
f' <{change}> {OCH_ADDED_CHARACTERISTIC_TO_PROPERTY} ?property ;' \
|
1487
|
+
f' {OCH_ADDED_CHARACTERISTIC} ?characteristic }}'
|
1488
|
+
print(query)
|
1489
|
+
for result in change_data.query(query):
|
1490
|
+
property = result["property"]
|
1491
|
+
characteristic = result["characteristic"]
|
1492
|
+
print(f"Property: {property}, Characteristic: {characteristic}")
|
1493
|
+
# Add SHACL restrictions for property characteristics
|
1494
|
+
if characteristic == URIRef(OWL_FUNCTIONAL_PROPERTY_URI):
|
1495
|
+
#print("Entra en la condición de OWL_FUNCTIONAL_PROPERTY")
|
1496
|
+
# Functional property: sh:maxCount 1
|
1497
|
+
insert_characteristic_query = (
|
1498
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1499
|
+
f' INSERT {{ ?propertyShape {SHACL_MAX_COUNT} 1 }}'
|
1500
|
+
f' WHERE {{ ?propertyShape {SHACL_PATH} <{property}> }}'
|
1501
|
+
)
|
1502
|
+
print(insert_characteristic_query)
|
1503
|
+
output_shapes.update(insert_characteristic_query)
|
1504
|
+
elif characteristic == URIRef(OWL_SYMMETRIC_PROPERTY_URI):
|
1505
|
+
# Symmetric property: custom SHACL-SPARQL constraint
|
1506
|
+
insert_characteristic_query = (
|
1507
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1508
|
+
f' INSERT {{ ?propertyShape {SHACL_SPARQL} [ a {SHACL_SPARQL_CONSTRAINT} ; {SHACL_SPARQL_SELECT} "SELECT $this WHERE {{ $this <{property}> ?v . FILTER NOT EXISTS {{ ?v <{property}> $this }} }}" ] }}'
|
1509
|
+
f' WHERE {{ ?propertyShape {SHACL_PATH} <{property}> }}'
|
1510
|
+
)
|
1511
|
+
print(insert_characteristic_query)
|
1512
|
+
output_shapes.update(insert_characteristic_query)
|
1513
|
+
elif characteristic == URIRef(OWL_ASYMMETRIC_PROPERTY_URI):
|
1514
|
+
# Asymmetric property: custom SHACL-SPARQL constraint
|
1515
|
+
insert_characteristic_query = (
|
1516
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1517
|
+
f' INSERT {{ ?propertyShape {SHACL_SPARQL} [ a {SHACL_SPARQL_CONSTRAINT} ; {SHACL_SPARQL_SELECT} "SELECT $this WHERE {{ $this <{property}> ?v . FILTER EXISTS {{ ?v <{property}> $this }} }}" ] }}'
|
1518
|
+
f' WHERE {{ ?propertyShape {SHACL_PATH} <{property}> }}'
|
1519
|
+
)
|
1520
|
+
print(insert_characteristic_query)
|
1521
|
+
output_shapes.update(insert_characteristic_query)
|
1522
|
+
elif characteristic == URIRef(OWL_REFLEXIVE_PROPERTY_URI):
|
1523
|
+
# Reflexive property: custom SHACL-SPARQL constraint
|
1524
|
+
insert_characteristic_query = (
|
1525
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1526
|
+
f' INSERT {{ ?propertyShape {SHACL_SPARQL} [ a {SHACL_SPARQL_CONSTRAINT} ; {SHACL_SPARQL_SELECT} "SELECT $this WHERE {{ FILTER NOT EXISTS {{ $this <{property}> $this }} }}" ] }}'
|
1527
|
+
f' WHERE {{ ?propertyShape {SHACL_PATH} <{property}> }}'
|
1528
|
+
)
|
1529
|
+
print(insert_characteristic_query)
|
1530
|
+
output_shapes.update(insert_characteristic_query)
|
1531
|
+
elif characteristic == URIRef(OWL_IRREFLEXIVE_PROPERTY_URI):
|
1532
|
+
# Irreflexive property: custom SHACL-SPARQL constraint
|
1533
|
+
insert_characteristic_query = (
|
1534
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1535
|
+
f' INSERT {{ ?propertyShape {SHACL_SPARQL} [ a {SHACL_SPARQL_CONSTRAINT} ; {SHACL_SPARQL_SELECT} "SELECT $this WHERE {{ $this <{property}> $this }}" ] }}'
|
1536
|
+
f' WHERE {{ ?propertyShape {SHACL_PATH} <{property}> }}'
|
1537
|
+
)
|
1538
|
+
print(insert_characteristic_query)
|
1539
|
+
output_shapes.update(insert_characteristic_query)
|
1540
|
+
elif characteristic == URIRef(OWL_INVERSE_FUNCTIONAL_PROPERTY_URI):
|
1541
|
+
# Inverse functional property: sh:maxCount 1 on inverse path
|
1542
|
+
# Use a blank node for the property shape and avoid using a URI for the shape
|
1543
|
+
if "#" in property:
|
1544
|
+
property_local = property.split("#")[-1]
|
1545
|
+
elif "/" in property:
|
1546
|
+
property_local = property.split("/")[-1]
|
1547
|
+
else:
|
1548
|
+
property_local = property
|
1549
|
+
insert_characteristic_query = (
|
1550
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1551
|
+
f' PREFIX {EXAMPLE_PREFIX}: <{EXAMPLE_URI}>'
|
1552
|
+
f' INSERT DATA {{ '
|
1553
|
+
f' {EXAMPLE_PREFIX}:{property_local}InvFunctShape a {SHACL_PROPERTY_SHAPE} ; '
|
1554
|
+
f' {SHACL_PATH} [ {SHACL_INVERSE_PATH} <{property}> ] ; '
|
1555
|
+
f' {SHACL_MAX_COUNT} 1 . '
|
1556
|
+
f' }} '
|
1557
|
+
)
|
1558
|
+
print(insert_characteristic_query)
|
1559
|
+
output_shapes.update(insert_characteristic_query)
|
1560
|
+
elif characteristic == URIRef(OWL_TRANSITIVE_PROPERTY_URI):
|
1561
|
+
# Transitive property: custom SHACL-SPARQL constraint
|
1562
|
+
insert_characteristic_query = (
|
1563
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1564
|
+
f' INSERT {{ ?propertyShape {SHACL_SPARQL} [ a {SHACL_SPARQL_CONSTRAINT} ; {SHACL_SPARQL_SELECT} "SELECT $this WHERE {{ $this <{property}> ?v1 . ?v1 <{property}> ?v2 . FILTER NOT EXISTS {{ $this <{property}> ?v2 }} }}" ] }}'
|
1565
|
+
f' WHERE {{ ?propertyShape {SHACL_PATH} <{property}> }}'
|
1566
|
+
)
|
1567
|
+
print(insert_characteristic_query)
|
1568
|
+
output_shapes.update(insert_characteristic_query)
|
1569
|
+
|
1570
|
+
def remove_characteristic_shacl(change, change_data, output_shapes):
|
1571
|
+
#print("Entra en la función remove_characteristic_shacl")
|
1572
|
+
"""
|
1573
|
+
Modifies the property shape corresponding to a given property to remove restrictions based on the removed characteristic.
|
1574
|
+
Args:
|
1575
|
+
change: the URI of the change which needs to be of the type removeCharacteristic
|
1576
|
+
Returns:
|
1577
|
+
the output_shapes updated with the data property shape modified.
|
1578
|
+
"""
|
1579
|
+
query = f' SELECT DISTINCT ?property ?characteristic WHERE {{ ' \
|
1580
|
+
f' <{change}> {OCH_REMOVED_CHARACTERISTIC_FROM_PROPERTY} ?property ;' \
|
1581
|
+
f' {OCH_REMOVED_CHARACTERISTIC} ?characteristic }}'
|
1582
|
+
print(query)
|
1583
|
+
for result in change_data.query(query):
|
1584
|
+
property = result["property"]
|
1585
|
+
characteristic = result["characteristic"]
|
1586
|
+
print(f"Property: {property}, Characteristic: {characteristic}")
|
1587
|
+
# Remove SHACL restrictions for property characteristics
|
1588
|
+
if characteristic == URIRef(OWL_FUNCTIONAL_PROPERTY_URI):
|
1589
|
+
#print("Entra en la condición de OWL_FUNCTIONAL_PROPERTY")
|
1590
|
+
# Functional property: sh:maxCount 1
|
1591
|
+
delete_characteristic_query = (
|
1592
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1593
|
+
f' DELETE {{ ?propertyShape {SHACL_MAX_COUNT} 1 }}'
|
1594
|
+
f' WHERE {{ ?propertyShape {SHACL_PATH} <{property}> }}'
|
1595
|
+
)
|
1596
|
+
print(delete_characteristic_query)
|
1597
|
+
output_shapes.update(delete_characteristic_query)
|
1598
|
+
elif characteristic == URIRef(OWL_SYMMETRIC_PROPERTY_URI):
|
1599
|
+
print(f"Entra en la condición de remove OWL_SYMMETRIC_PROPERTY: {property}")
|
1600
|
+
# Symmetric property: custom SHACL-SPARQL constraint
|
1601
|
+
delete_characteristic_query = (
|
1602
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1603
|
+
f' DELETE {{ ?propertyShape {SHACL_SPARQL} ?constraintNode .'
|
1604
|
+
f' ?constraintNode a {SHACL_SPARQL_CONSTRAINT} ; '
|
1605
|
+
f' {SHACL_SPARQL_SELECT} "SELECT $this WHERE {{ $this <{property}> ?v . FILTER NOT EXISTS {{ ?v <{property}> $this }} }}" }}'
|
1606
|
+
f' WHERE {{ ?propertyShape {SHACL_PATH} <{property}> . '
|
1607
|
+
f' ?propertyShape {SHACL_SPARQL} ?constraintNode . '
|
1608
|
+
f' ?constraintNode a {SHACL_SPARQL_CONSTRAINT} ; '
|
1609
|
+
f' {SHACL_SPARQL_SELECT} "SELECT $this WHERE {{ $this <{property}> ?v . FILTER NOT EXISTS {{ ?v <{property}> $this }} }}" }}'
|
1610
|
+
)
|
1611
|
+
print(delete_characteristic_query)
|
1612
|
+
output_shapes.update(delete_characteristic_query)
|
1613
|
+
elif characteristic == URIRef(OWL_ASYMMETRIC_PROPERTY_URI):
|
1614
|
+
# Asymmetric property: custom SHACL-SPARQL constraint
|
1615
|
+
#print(f"Entra en la condición de remove OWL_ASYMMETRIC_PROPERTY: {property}")
|
1616
|
+
delete_characteristic_query = (
|
1617
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1618
|
+
f' DELETE {{ ?propertyShape {SHACL_SPARQL} ?constraintNode .'
|
1619
|
+
f' ?constraintNode a {SHACL_SPARQL_CONSTRAINT} ; '
|
1620
|
+
f' {SHACL_SPARQL_SELECT} "SELECT $this WHERE {{ $this <{property}> ?v . FILTER EXISTS {{ ?v <{property}> $this }} }}" }}'
|
1621
|
+
f' WHERE {{ ?propertyShape {SHACL_PATH} <{property}> . '
|
1622
|
+
f' ?propertyShape {SHACL_SPARQL} ?constraintNode . '
|
1623
|
+
f' ?constraintNode a {SHACL_SPARQL_CONSTRAINT} ; '
|
1624
|
+
f' {SHACL_SPARQL_SELECT} "SELECT $this WHERE {{ $this <{property}> ?v . FILTER EXISTS {{ ?v <{property}> $this }} }}" }}'
|
1625
|
+
)
|
1626
|
+
print(delete_characteristic_query)
|
1627
|
+
output_shapes.update(delete_characteristic_query)
|
1628
|
+
elif characteristic == URIRef(OWL_REFLEXIVE_PROPERTY_URI):
|
1629
|
+
# Reflexive property: custom SHACL-SPARQL constraint
|
1630
|
+
delete_characteristic_query = (
|
1631
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1632
|
+
f' DELETE {{ ?propertyShape {SHACL_SPARQL} ?constraintNode .'
|
1633
|
+
f' ?constraintNode a {SHACL_SPARQL_CONSTRAINT} ; '
|
1634
|
+
f' {SHACL_SPARQL_SELECT} "SELECT $this WHERE {{ FILTER NOT EXISTS {{ $this <{property}> $this }} }}" }}'
|
1635
|
+
f' WHERE {{ ?propertyShape {SHACL_PATH} <{property}> . '
|
1636
|
+
f' ?propertyShape {SHACL_SPARQL} ?constraintNode . '
|
1637
|
+
f' ?constraintNode a {SHACL_SPARQL_CONSTRAINT} ; '
|
1638
|
+
f' {SHACL_SPARQL_SELECT} "SELECT $this WHERE {{ FILTER NOT EXISTS {{ $this <{property}> $this }} }}" }}'
|
1639
|
+
)
|
1640
|
+
print(delete_characteristic_query)
|
1641
|
+
output_shapes.update(delete_characteristic_query)
|
1642
|
+
elif characteristic == URIRef(OWL_IRREFLEXIVE_PROPERTY_URI):
|
1643
|
+
# Irreflexive property: custom SHACL-SPARQL constraint
|
1644
|
+
delete_characteristic_query = (
|
1645
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1646
|
+
f' DELETE {{ ?propertyShape {SHACL_SPARQL} ?constraintNode .'
|
1647
|
+
f' ?constraintNode a {SHACL_SPARQL_CONSTRAINT} ; '
|
1648
|
+
f' {SHACL_SPARQL_SELECT} "SELECT $this WHERE {{ $this <{property}> $this }}" }}'
|
1649
|
+
f' WHERE {{ ?propertyShape {SHACL_PATH} <{property}> . '
|
1650
|
+
f' ?propertyShape {SHACL_SPARQL} ?constraintNode . '
|
1651
|
+
f' ?constraintNode a {SHACL_SPARQL_CONSTRAINT} ; '
|
1652
|
+
f' {SHACL_SPARQL_SELECT} "SELECT $this WHERE {{ $this <{property}> $this }}" }}'
|
1653
|
+
)
|
1654
|
+
print(delete_characteristic_query)
|
1655
|
+
output_shapes.update(delete_characteristic_query)
|
1656
|
+
elif characteristic == URIRef(OWL_INVERSE_FUNCTIONAL_PROPERTY_URI):
|
1657
|
+
# Inverse functional property: sh:uniqueLang or custom constraint
|
1658
|
+
delete_characteristic_query = (
|
1659
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1660
|
+
f' PREFIX {EXAMPLE_PREFIX}: <{EXAMPLE_URI}>'
|
1661
|
+
f' DELETE {{ '
|
1662
|
+
f' ?shape a {SHACL_PROPERTY_SHAPE} ; '
|
1663
|
+
f' {SHACL_PATH} ?pathbnode . '
|
1664
|
+
f' ?pathbnode {SHACL_INVERSE_PATH} <{property}> . '
|
1665
|
+
f' ?shape {SHACL_MAX_COUNT} 1 . '
|
1666
|
+
f' }} '
|
1667
|
+
f' WHERE {{ ?shape a {SHACL_PROPERTY_SHAPE} ; '
|
1668
|
+
f' {SHACL_PATH} ?pathbnode . '
|
1669
|
+
f' ?pathbnode {SHACL_INVERSE_PATH} <{property}> . '
|
1670
|
+
f' ?shape {SHACL_MAX_COUNT} 1 . '
|
1671
|
+
f' }}'
|
1672
|
+
)
|
1673
|
+
print(delete_characteristic_query)
|
1674
|
+
output_shapes.update(delete_characteristic_query)
|
1675
|
+
elif characteristic == URIRef(OWL_TRANSITIVE_PROPERTY_URI):
|
1676
|
+
# Transitive property: custom SHACL-SPARQL constraint
|
1677
|
+
delete_characteristic_query = (
|
1678
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1679
|
+
f' DELETE {{ ?propertyShape {SHACL_SPARQL} ?constraintNode .'
|
1680
|
+
f' ?constraintNode a {SHACL_SPARQL_CONSTRAINT} ; '
|
1681
|
+
f' {SHACL_SPARQL_SELECT} "SELECT $this WHERE {{ $this <{property}> ?v1 . ?v1 <{property}> ?v2 . FILTER NOT EXISTS {{ $this <{property}> ?v2 }} }}" }}'
|
1682
|
+
f' WHERE {{ ?propertyShape {SHACL_PATH} <{property}> . '
|
1683
|
+
f' ?propertyShape {SHACL_SPARQL} ?constraintNode . '
|
1684
|
+
f' ?constraintNode a {SHACL_SPARQL_CONSTRAINT} ; '
|
1685
|
+
f' {SHACL_SPARQL_SELECT} "SELECT $this WHERE {{ $this <{property}> ?v1 . ?v1 <{property}> ?v2 . FILTER NOT EXISTS {{ $this <{property}> ?v2 }} }}" }}'
|
1686
|
+
)
|
1687
|
+
print(delete_characteristic_query)
|
1688
|
+
output_shapes.update(delete_characteristic_query)
|
1689
|
+
|
1690
|
+
def add_inverse_property_shacl(change, change_data, output_shapes):
|
1691
|
+
"""
|
1692
|
+
Adds an inverse property relationship to SHACL NodeShapes by inserting a SPARQL constraint that checks for the inverse property.
|
1693
|
+
Args:
|
1694
|
+
change: The URI of the change, which must be of the type add_inverse_property.
|
1695
|
+
change_data: The RDF graph or data source containing information about the change.
|
1696
|
+
output_shapes: The collection or graph to be updated with the new SHACL NodeShape including the inverse property restriction.
|
1697
|
+
Returns:
|
1698
|
+
The output_shapes updated with the data property shape modified.
|
1699
|
+
"""
|
1700
|
+
query = (
|
1701
|
+
f' SELECT DISTINCT ?source_prop ?target_prop WHERE {{ '
|
1702
|
+
f' <{change}> {OCH_ADD_INVERSE_PROPERTY_SOURCE} ?source_prop . '
|
1703
|
+
f' <{change}> {OCH_ADD_INVERSE_PROPERTY_TARGET} ?target_prop . }}'
|
1704
|
+
)
|
1705
|
+
for result in change_data.query(query):
|
1706
|
+
source_prop = result["source_prop"]
|
1707
|
+
target_prop = result["target_prop"]
|
1708
|
+
insert_inverse_property_query = (
|
1709
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1710
|
+
f' PREFIX {EXAMPLE_PREFIX}: <{EXAMPLE_URI}>'
|
1711
|
+
f' INSERT {{ '
|
1712
|
+
f' ?shapesource {SHACL_PATH} <{source_prop}> ; '
|
1713
|
+
f' {SHACL_SPARQL} [ a {SHACL_SPARQL_CONSTRAINT} ; {SHACL_SPARQL_SELECT} """ SELECT ?this WHERE {{ ?sub <{source_prop}> ?obj . FILTER NOT EXISTS {{ ?obj <{target_prop}> ?sub . }} }} """ ; ] . '
|
1714
|
+
f' ?shapetarget {SHACL_PATH} <{target_prop}> ; '
|
1715
|
+
f' {SHACL_SPARQL} [ a {SHACL_SPARQL_CONSTRAINT} ; {SHACL_SPARQL_SELECT} """ SELECT ?this WHERE {{ ?sub <{target_prop}> ?obj . FILTER NOT EXISTS {{ ?obj <{source_prop}> ?sub . }} }} """ ; ] . '
|
1716
|
+
f' }} WHERE {{ '
|
1717
|
+
f' ?shapesource {SHACL_PATH} <{source_prop}> . '
|
1718
|
+
f' ?shapetarget {SHACL_PATH} <{target_prop}> . '
|
1719
|
+
f' }}'
|
1720
|
+
)
|
1721
|
+
print(insert_inverse_property_query)
|
1722
|
+
output_shapes.update(insert_inverse_property_query)
|
1723
|
+
|
1724
|
+
def remove_inverse_property_shacl(change, change_data, output_shapes):
|
1725
|
+
"""
|
1726
|
+
Removes an inverse property relationship from SHACL NodeShapes by deleting the SPARQL constraint that checks for the inverse property.
|
1727
|
+
Args:
|
1728
|
+
change: The URI of the change, which must be of the type add_inverse_property.
|
1729
|
+
change_data: The RDF graph or data source containing information about the change.
|
1730
|
+
output_shapes: The collection or graph to be updated without the new SHACL NodeShape including the inverse property restriction.
|
1731
|
+
Returns:
|
1732
|
+
The output_shapes updated with the data property shape modified.
|
1733
|
+
"""
|
1734
|
+
query = (
|
1735
|
+
f' SELECT DISTINCT ?source_prop ?target_prop WHERE {{ '
|
1736
|
+
f' <{change}> {OCH_REMOVE_INVERSE_PROPERTY_SOURCE} ?source_prop . '
|
1737
|
+
f' <{change}> {OCH_REMOVE_INVERSE_PROPERTY_TARGET} ?target_prop . }}'
|
1738
|
+
)
|
1739
|
+
for result in change_data.query(query):
|
1740
|
+
source_prop = result["source_prop"]
|
1741
|
+
target_prop = result["target_prop"]
|
1742
|
+
remove_inverse_property_query = (
|
1743
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1744
|
+
f' PREFIX {EXAMPLE_PREFIX}: <{EXAMPLE_URI}>'
|
1745
|
+
f' DELETE {{ '
|
1746
|
+
f' ?shapesource {SHACL_SPARQL} ?constraintSource . '
|
1747
|
+
f' ?constraintSource a {SHACL_SPARQL_CONSTRAINT} ; '
|
1748
|
+
f' {SHACL_SPARQL_SELECT} "SELECT ?this WHERE {{ ?sub <{source_prop}> ?obj . FILTER NOT EXISTS {{ ?obj <{target_prop}> ?sub . }} }} " . '
|
1749
|
+
f' ?shapetarget {SHACL_SPARQL} ?constraintTarget . '
|
1750
|
+
f' ?constraintTarget a {SHACL_SPARQL_CONSTRAINT} ; '
|
1751
|
+
f' {SHACL_SPARQL_SELECT} "SELECT ?this WHERE {{ ?sub <{target_prop}> ?obj . FILTER NOT EXISTS {{ ?obj <{source_prop}> ?sub . }} }} " . '
|
1752
|
+
f' }} WHERE {{ '
|
1753
|
+
f' ?shapesource {SHACL_PATH} <{source_prop}> ; '
|
1754
|
+
f' {SHACL_SPARQL} ?constraintSource . '
|
1755
|
+
f' ?constraintSource a {SHACL_SPARQL_CONSTRAINT} ; '
|
1756
|
+
f' {SHACL_SPARQL_SELECT} "SELECT ?this WHERE {{ ?sub <{source_prop}> ?obj . FILTER NOT EXISTS {{ ?obj <{target_prop}> ?sub . }} }} " . '
|
1757
|
+
f' ?shapetarget {SHACL_PATH} <{target_prop}> ; '
|
1758
|
+
f' {SHACL_SPARQL} ?constraintTarget . '
|
1759
|
+
f' ?constraintTarget a {SHACL_SPARQL_CONSTRAINT} ; '
|
1760
|
+
f' {SHACL_SPARQL_SELECT} "SELECT ?this WHERE {{ ?sub <{target_prop}> ?obj . FILTER NOT EXISTS {{ ?obj <{source_prop}> ?sub . }} }} " . '
|
1761
|
+
f' }}'
|
1762
|
+
)
|
1763
|
+
print(remove_inverse_property_query)
|
1764
|
+
output_shapes.update(remove_inverse_property_query)
|
1765
|
+
|
1766
|
+
def add_disjoint_property_shacl(change, change_data, output_shapes):
|
1767
|
+
"""
|
1768
|
+
Adds a disjoint property restriction to the SHACL NodeShape via SHACL-SPARQL query.
|
1769
|
+
Args:
|
1770
|
+
change: the URI of the change which needs to be of the type add_disjoint_property
|
1771
|
+
Returns:
|
1772
|
+
The output_shapes updated with the constraints that enforce the disjointness of the properties.
|
1773
|
+
"""
|
1774
|
+
query = (
|
1775
|
+
f' SELECT DISTINCT ?source_property ?target_property WHERE {{ '
|
1776
|
+
f' <{change}> {OCH_ADD_DISJOINT_PROPERTY_SOURCE} ?source_property. '
|
1777
|
+
f' <{change}> {OCH_ADD_DISJOINT_PROPERTY_TARGET} ?target_property. }}'
|
1778
|
+
)
|
1779
|
+
for result in change_data.query(query):
|
1780
|
+
source_prop = result["source_property"]
|
1781
|
+
target_prop = result["target_property"]
|
1782
|
+
add_disjoint_property_query = (
|
1783
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1784
|
+
f' PREFIX {EXAMPLE_PREFIX}: <{EXAMPLE_URI}>'
|
1785
|
+
f' INSERT {{ '
|
1786
|
+
f' ?shapesource {SHACL_DISJOINT} <{target_prop}> . '
|
1787
|
+
f' ?shapetarget {SHACL_DISJOINT} <{source_prop}> . '
|
1788
|
+
f' }} WHERE {{ '
|
1789
|
+
f' ?shapesource {SHACL_PATH} <{source_prop}> . '
|
1790
|
+
f' ?shapetarget {SHACL_PATH} <{target_prop}> . '
|
1791
|
+
f' }}'
|
1792
|
+
)
|
1793
|
+
print(add_disjoint_property_query)
|
1794
|
+
output_shapes.update(add_disjoint_property_query)
|
1795
|
+
|
1796
|
+
def remove_disjoint_property_shacl(change, change_data, output_shapes):
|
1797
|
+
"""
|
1798
|
+
Removes a disjoint property restriction from the SHACL NodeShape via SHACL-SPARQL query.
|
1799
|
+
Args:
|
1800
|
+
change: the URI of the change which needs to be of the type remove_disjoint_property
|
1801
|
+
Returns:
|
1802
|
+
The output_shapes updated without the constraints that enforce the disjointness of the properties.
|
1803
|
+
"""
|
1804
|
+
query = (
|
1805
|
+
f' SELECT DISTINCT ?source_property ?target_property WHERE {{ '
|
1806
|
+
f' <{change}> {OCH_REMOVE_DISJOINT_PROPERTY_SOURCE} ?source_property. '
|
1807
|
+
f' <{change}> {OCH_REMOVE_DISJOINT_PROPERTY_TARGET} ?target_property. }}'
|
1808
|
+
)
|
1809
|
+
for result in change_data.query(query):
|
1810
|
+
source_prop = result["source_property"]
|
1811
|
+
target_prop = result["target_property"]
|
1812
|
+
remove_disjoint_property_query = (
|
1813
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1814
|
+
f' PREFIX {EXAMPLE_PREFIX}: <{EXAMPLE_URI}>'
|
1815
|
+
f' DELETE {{ '
|
1816
|
+
f' ?shapesource {SHACL_DISJOINT} <{target_prop}> . '
|
1817
|
+
f' ?shapetarget {SHACL_DISJOINT} <{source_prop}> . '
|
1818
|
+
f' }} WHERE {{ '
|
1819
|
+
f' ?shapesource {SHACL_PATH} <{source_prop}> . '
|
1820
|
+
f' ?shapetarget {SHACL_PATH} <{target_prop}> . '
|
1821
|
+
f' ?shapesource {SHACL_DISJOINT} <{target_prop}> . '
|
1822
|
+
f' ?shapetarget {SHACL_DISJOINT} <{source_prop}> . '
|
1823
|
+
f' }}'
|
1824
|
+
)
|
1825
|
+
print(remove_disjoint_property_query)
|
1826
|
+
output_shapes.update(remove_disjoint_property_query)
|
1827
|
+
|
1828
|
+
def add_superproperty_shacl(change, change_data, output_shapes):
|
1829
|
+
"""
|
1830
|
+
Adds a subproperty relationship to SHACL NodeShapes by inserting a SPARQL constraint that checks for the subproperty.
|
1831
|
+
Args:
|
1832
|
+
change: The URI of the change, which must be of the type add_subproperty.
|
1833
|
+
change_data: The RDF graph or data source containing information about the change.
|
1834
|
+
output_shapes: The collection or graph to be updated with the new SHACL NodeShape including the subproperty restriction.
|
1835
|
+
Returns:
|
1836
|
+
The output_shapes updated with the data property shape modified.
|
1837
|
+
"""
|
1838
|
+
query = (
|
1839
|
+
f' SELECT DISTINCT ?sub_property ?super_property WHERE {{ '
|
1840
|
+
f' <{change}> {OCH_ADD_SUBPROPERTY_SOURCE} ?sub_property . '
|
1841
|
+
f' <{change}> {OCH_ADD_SUBPROPERTY_TARGET} ?super_property . }}'
|
1842
|
+
)
|
1843
|
+
for result in change_data.query(query):
|
1844
|
+
sub_property = result["sub_property"]
|
1845
|
+
super_property = result["super_property"]
|
1846
|
+
insert_subproperty_query = (
|
1847
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1848
|
+
f' PREFIX {EXAMPLE_PREFIX}: <{EXAMPLE_URI}>'
|
1849
|
+
f' INSERT {{ '
|
1850
|
+
f' ?shapesub {SHACL_SPARQL} [ '
|
1851
|
+
f' a {SHACL_SPARQL_CONSTRAINT} ; '
|
1852
|
+
f' {SHACL_SPARQL_SELECT} "SELECT ?this WHERE {{ ?this <{sub_property}> ?v . FILTER NOT EXISTS {{ ?this <{super_property}> ?v }} }} " ; ] . '
|
1853
|
+
f' }} WHERE {{ '
|
1854
|
+
f' ?shapesub {SHACL_PATH} <{sub_property}> . '
|
1855
|
+
f' }}'
|
1856
|
+
)
|
1857
|
+
print(insert_subproperty_query)
|
1858
|
+
output_shapes.update(insert_subproperty_query)
|
1859
|
+
|
1860
|
+
def remove_superproperty_shacl(change, change_data, output_shapes):
|
1861
|
+
"""
|
1862
|
+
Removes a subproperty relationship to SHACL NodeShapes by inserting a SPARQL constraint that checks for the subproperty.
|
1863
|
+
Args:
|
1864
|
+
change: The URI of the change, which must be of the type add_subproperty.
|
1865
|
+
change_data: The RDF graph or data source containing information about the change.
|
1866
|
+
output_shapes: The collection or graph to be updated with the new SHACL NodeShape including the subproperty restriction.
|
1867
|
+
Returns:
|
1868
|
+
The output_shapes updated with the data property shape modified.
|
1869
|
+
"""
|
1870
|
+
query = (
|
1871
|
+
f' SELECT DISTINCT ?sub_property ?super_property WHERE {{ '
|
1872
|
+
f' <{change}> {OCH_REMOVE_SUBPROPERTY_SOURCE} ?sub_property . '
|
1873
|
+
f' <{change}> {OCH_REMOVE_SUBPROPERTY_TARGET} ?super_property . }}'
|
1874
|
+
)
|
1875
|
+
for result in change_data.query(query):
|
1876
|
+
sub_property = result["sub_property"]
|
1877
|
+
super_property = result["super_property"]
|
1878
|
+
remove_subproperty_query = (
|
1879
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1880
|
+
f' DELETE {{ '
|
1881
|
+
f' ?shapesub {SHACL_SPARQL} ?sparqlrestriction . '
|
1882
|
+
f' ?sparqlrestriction a {SHACL_SPARQL_CONSTRAINT} ; '
|
1883
|
+
f' {SHACL_SPARQL_SELECT} "SELECT ?this WHERE {{ ?this <{sub_property}> ?v . FILTER NOT EXISTS {{ ?this <{super_property}> ?v }} }} " ; '
|
1884
|
+
f' }} WHERE {{ '
|
1885
|
+
f' ?shapesub {SHACL_PATH} <{sub_property}> . '
|
1886
|
+
f' ?shapesub {SHACL_SPARQL} ?sparqlrestriction . '
|
1887
|
+
f' ?sparqlrestriction a {SHACL_SPARQL_CONSTRAINT} ; '
|
1888
|
+
f' {SHACL_SPARQL_SELECT} "SELECT ?this WHERE {{ ?this <{sub_property}> ?v . FILTER NOT EXISTS {{ ?this <{super_property}> ?v }} }} " ; '
|
1889
|
+
f' }}'
|
1890
|
+
)
|
1891
|
+
print(remove_subproperty_query)
|
1892
|
+
output_shapes.update(remove_subproperty_query)
|
1893
|
+
|
1894
|
+
def add_equivalent_property_shacl(change, change_data, output_shapes):
|
1895
|
+
"""
|
1896
|
+
Adds a sh:equals constraint to the property shapes involved in the relationship .
|
1897
|
+
Args:
|
1898
|
+
change: The URI of the change, which must be of the type add_subproperty.
|
1899
|
+
change_data: The RDF graph or data source containing information about the change.
|
1900
|
+
output_shapes: The collection or graph to be updated with the new SHACL NodeShape including the subproperty restriction.
|
1901
|
+
Returns:
|
1902
|
+
The output_shapes updated with the data property shape modified.
|
1903
|
+
"""
|
1904
|
+
query = (
|
1905
|
+
f' SELECT DISTINCT ?source_property ?target_property WHERE {{ '
|
1906
|
+
f' <{change}> {OCH_ADD_EQUIVALENT_PROPERTY_SOURCE} ?source_property . '
|
1907
|
+
f' <{change}> {OCH_ADD_EQUIVALENT_PROPERTY_TARGET} ?target_property . }}'
|
1908
|
+
)
|
1909
|
+
for result in change_data.query(query):
|
1910
|
+
source_property = result["source_property"]
|
1911
|
+
target_property = result["target_property"]
|
1912
|
+
insert_subproperty_query = (
|
1913
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1914
|
+
f' INSERT {{ '
|
1915
|
+
f' ?shape_source {SHACL_EQUALS} <{target_property}> . '
|
1916
|
+
f' ?shape_target {SHACL_EQUALS} <{source_property}> . '
|
1917
|
+
f' }} WHERE {{ '
|
1918
|
+
f' ?shape_source {SHACL_PATH} <{source_property}> . '
|
1919
|
+
f' ?shape_target {SHACL_PATH} <{target_property}> . '
|
1920
|
+
f' }}'
|
1921
|
+
)
|
1922
|
+
print(insert_subproperty_query)
|
1923
|
+
output_shapes.update(insert_subproperty_query)
|
1924
|
+
|
1925
|
+
def remove_equivalent_property_shacl(change, change_data, output_shapes):
|
1926
|
+
"""
|
1927
|
+
Removes a sh:equals constraint from the property shapes involved in the relationship.
|
1928
|
+
Args:
|
1929
|
+
change: The URI of the change, which must be of the type add_subproperty.
|
1930
|
+
change_data: The RDF graph or data source containing information about the change.
|
1931
|
+
output_shapes: The collection or graph to be updated with the new SHACL NodeShape including the subproperty restriction.
|
1932
|
+
Returns:
|
1933
|
+
The output_shapes updated with the data property shape modified.
|
1934
|
+
"""
|
1935
|
+
query = (
|
1936
|
+
f' SELECT DISTINCT ?source_property ?target_property WHERE {{ '
|
1937
|
+
f' <{change}> {OCH_REMOVE_EQUIVALENT_PROPERTY_SOURCE} ?source_property . '
|
1938
|
+
f' <{change}> {OCH_REMOVE_EQUIVALENT_PROPERTY_TARGET} ?target_property . }}'
|
1939
|
+
)
|
1940
|
+
for result in change_data.query(query):
|
1941
|
+
source_property = result["source_property"]
|
1942
|
+
target_property = result["target_property"]
|
1943
|
+
remove_subproperty_query = (
|
1944
|
+
f' PREFIX {SHACL_PREFIX}: <{SHACL_URI}>'
|
1945
|
+
f' DELETE {{ '
|
1946
|
+
f' ?shape_source {SHACL_EQUALS} <{target_property}> . '
|
1947
|
+
f' ?shape_target {SHACL_EQUALS} <{source_property}> . '
|
1948
|
+
f' }} WHERE {{ '
|
1949
|
+
f' ?shape_source {SHACL_PATH} <{source_property}> ; '
|
1950
|
+
f' {SHACL_EQUALS} <{target_property}> . '
|
1951
|
+
f' ?shape_target {SHACL_PATH} <{target_property}> ; '
|
1952
|
+
f' {SHACL_EQUALS} <{source_property}> . '
|
1953
|
+
f' }}'
|
1954
|
+
)
|
1955
|
+
print(remove_subproperty_query)
|
1956
|
+
output_shapes.update(remove_subproperty_query)
|