-
Notifications
You must be signed in to change notification settings - Fork 24
/
annotation.py
161 lines (127 loc) · 6.53 KB
/
annotation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# -*- coding: utf-8 -*-
# Owlready2
# Copyright (C) 2013-2019 Jean-Baptiste LAMY
# LIMICS (Laboratoire d'informatique médicale et d'ingénierie des connaissances en santé), UMR_S 1142
# University Paris 13, Sorbonne paris-Cité, Bobigny, France
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from owlready2.namespace import *
from owlready2.prop import *
from owlready2.prop import _CLASS_PROPS
# import weakref
# _annot_axiom_cache = weakref.WeakValueDictionary()
# class _AnnotAxiom(object):
# def __init__(self, source, property, target, target_d):
# self.namespace = source.namespace.ontology
# self.source = source
# self.property = property
# self.target = target
# self.target_d = target_d
# self.bnode = self.search_bnode()
# def search_bnode(self):
# if self.target_d is None:
# for bnode in self.namespace._get_obj_triples_po_s(rdf_type, owl_axiom):
# for p, o in self._get_obj_triples_s_po(bnode):
# if (p == owl_annotatedsource) and (o != self.source): break
# elif (p == owl_annotatedproperty) and (o != self.property): break
# elif (p == owl_annotatedtarget) and (o != self.target): break
# else:
# return bnode
# else:
# for bnode in self.namespace._get_obj_triples_po_s(rdf_type, owl_axiom):
# for p, o, d in self._get_triples_s_pod(bnode):
# if (p == owl_annotatedsource) and (o != self.source): break
# elif (p == owl_annotatedproperty) and (o != self.property): break
# elif (p == owl_annotatedtarget) and (o != self.target): break
# else:
# return bnode
class _AnnotList(CallbackListWithLanguage):
__slots__ = ["namespace", "_property", "_target", "_target_d", "_annot", "_od_2_bnode"]
def __init__(self, l, source, property, target, target_d, annot, namespace, od_2_bnode):
list.__init__(self, l)
self.namespace = namespace
self._obj = source
self._property = property
self._target = target
self._target_d = target_d
self._annot = annot
self._od_2_bnode = od_2_bnode
def _callback(self, obj, old):
old = set(old)
new = set(self)
if isinstance(obj, _AnnotList): # Annotate an annotation
storid = obj._od_2_bnode[self._target, self._target_d]
else:
storid = obj.storid
# Add before, in order to avoid destroying the axiom and then recreating, if all annotations are modified
for added in new - old:
o, d = obj.namespace.ontology._to_rdf(added)
bnode = obj.namespace.ontology._add_annotation_axiom(storid, self._property, self._target, self._target_d, self._annot, o, d)
self._od_2_bnode[o, d] = bnode
for removed in old - new:
obj.namespace.ontology._del_annotation_axiom(storid, self._property, self._target, self._target_d, self._annot, *obj.namespace.ontology._to_rdf(removed))
class AnnotationPropertyClass(PropertyClass):
_owl_type = owl_annotation_property
inverse_property = inverse = None
def __getitem__(Annot, entity):
if isinstance(entity, tuple):
source, property, target = entity
if hasattr(source, "storid"):
namespace = source.namespace # if Annot is in owl_world (e.g. comment), use the namespace of the source
elif isinstance(source, _AnnotList):
namespace = source._obj.namespace
else:
namespace = Annot.namespace
if hasattr(property, "storid"): property = property.storid
target, target_d = namespace.world._to_rdf(target)
if hasattr(source, "storid"):
source_orig = source
source = source.storid
elif isinstance(source, _AnnotList):
source_orig = source
source = source._od_2_bnode[target, target_d]
l = []
od_2_bnode = {}
for bnode in namespace.world._get_annotation_axioms(source, property, target, target_d):
for o, d in namespace.world._get_triples_sp_od(bnode, Annot.storid):
l.append(namespace.world._to_python(o, d))
od_2_bnode[o, d] = bnode
return _AnnotList(l, source_orig, property, target, target_d, Annot.storid, namespace, od_2_bnode)
else:
if Annot is entity.namespace.world._props.get(Annot._python_name) and not isinstance(entity, Construct): # use cached value
r = getattr(entity, Annot._python_name)
if isinstance(r, list): return r # May not be a list if hacked (e.g. Concept.terminology)
return Annot._get_values_for_individual(entity)
def __setitem__(Annot, index, values):
if not isinstance(values, list): values = [values]
Annot[index].reinit(values)
def __call__(Prop, type, c, *args):
raise ValueError("Cannot create a property value restriction on an annotation property!")
def _get_indirect_values_for_individual(Prop, entity):
values = [entity.namespace.ontology._to_python(o, d)
for P in Prop.descendants(world = entity.namespace.world)
for o, d in entity.namespace.world._get_triples_sp_od(entity.storid, P.storid)]
return values
_get_indirect_values_for_class = _get_indirect_values_for_individual
class AnnotationProperty(Property, metaclass = AnnotationPropertyClass):
namespace = owl
@classmethod
def is_functional_for(Prop, o): return False
_CLASS_PROPS.add(AnnotationProperty)
class comment (AnnotationProperty): namespace = rdfs
class label (AnnotationProperty): namespace = rdfs
class backwardCompatibleWith(AnnotationProperty): namespace = owl
class deprecated (AnnotationProperty): namespace = owl
class incompatibleWith (AnnotationProperty): namespace = owl
class isDefinedBy (AnnotationProperty): namespace = rdfs
class priorVersion (AnnotationProperty): namespace = owl
class seeAlso (AnnotationProperty): namespace = rdfs
class versionInfo (AnnotationProperty): namespace = owl