Skip to content

Commit cd0b442

Browse files
aucampiaGraham Higgins
and
Graham Higgins
authored
fix: bugs with rdflib.extras.infixowl (RDFLib#2390)
Fix the following issues in `rdflib.extras.infixowl`: - getting and setting of max cardinality only considered identifiers and not other RDF terms. - The return value of `manchesterSyntax` was wrong for some cases. - The way that `BooleanClass` was generating its string representation (i.e. `BooleanClass.__repr__`) was wrong for some cases. Other changes: - Added an example for using infixowl to create an ontology. - Updated infixowl tests. - Updated infixowl documentation. This code is based on code from: - <RDFLib#2307> Changes are primarily authored by <https://github.com/gjhiggins>. --------- Co-authored-by: Graham Higgins <[email protected]>
1 parent e103078 commit cd0b442

File tree

4 files changed

+488
-93
lines changed

4 files changed

+488
-93
lines changed
+280
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
from rdflib import Graph, Literal, Namespace, URIRef
2+
from rdflib.extras.infixowl import Class, Ontology, Property, min, only, some
3+
4+
CPR = Namespace("http://purl.org/cpr/0.75#")
5+
INF = Namespace("http://www.loa-cnr.it/ontologies/InformationObjects.owl#")
6+
EDNS = Namespace("http://www.loa-cnr.it/ontologies/ExtendedDnS.owl#")
7+
DOLCE = Namespace("http://www.loa-cnr.it/ontologies/DOLCE-Lite.owl#")
8+
REL = Namespace("http://www.geneontology.org/owl#")
9+
GALEN = Namespace("http://www.co-ode.org/ontologies/galen#")
10+
TIME = Namespace("http://www.w3.org/2006/time#")
11+
CYC = Namespace("http://sw.cyc.com/2006/07/27/cyc/")
12+
13+
14+
def infixowl_example():
15+
g = Graph()
16+
g.bind("cpr", CPR, override=False)
17+
g.bind("ro", REL, override=False)
18+
g.bind("inf", INF, override=False)
19+
g.bind("edns", EDNS, override=False)
20+
g.bind("dol", DOLCE, override=False)
21+
g.bind("time", TIME, override=False)
22+
g.bind("galen", GALEN, override=False)
23+
24+
Class.factoryGraph = g
25+
Property.factoryGraph = g
26+
Ontology.factoryGraph = g
27+
28+
cprOntology = Ontology(URIRef("http://purl.org/cpr/owl")) # noqa: N806
29+
cprOntology.imports = [
30+
URIRef("http://obo.sourceforge.net/relationship/relationship.owl"),
31+
URIRef(DOLCE),
32+
URIRef(EDNS),
33+
URIRef("http://www.w3.org/2006/time#"),
34+
]
35+
cprOntology.comment = [
36+
Literal(
37+
"""This OWL ontology was generated by Fuxi 0.85b.dev-r107
38+
(with newly added Infix OWL syntax library). It imports the
39+
OBO relationship ontology, DOLCE, and OWL time. It formally
40+
defines a focused, core set of archetypes [Jung, C.]
41+
replicated in various patient record terminology. This core is
42+
defined in RDF and follows the normalization principles
43+
of "rigorous formal ontologies" [Rector, A.]."""
44+
)
45+
]
46+
cprOntology.setVersion(Literal("0.75"))
47+
48+
# Relations
49+
# represented-by
50+
representationOf = Property( # noqa: N806
51+
CPR["representation-of"],
52+
inverseOf=Property(CPR["represented-by"]),
53+
comment=[
54+
Literal(
55+
"""Patient records stand in the cpr:representation-of relation
56+
with patients"""
57+
)
58+
],
59+
)
60+
representedBy = Property( # noqa: F841, N806
61+
CPR["represented-by"], inverseOf=representationOf
62+
)
63+
# description-of
64+
descrOf = Property( # noqa: N806
65+
CPR["description-of"],
66+
comment=[
67+
Literal(
68+
"""Clinical descriptions stand in the cpr:description-of
69+
relation with various clinical phenomenon"""
70+
)
71+
],
72+
domain=[Class(CPR["clinical-description"])],
73+
)
74+
# cpr:interpreted-by
75+
interpretedBy = Property( # noqa: F841, N806
76+
CPR["interpreted-by"],
77+
comment=[
78+
Literal(
79+
"""Signs and symptoms are interpreted by rational physical
80+
objects (people)"""
81+
)
82+
],
83+
domain=[Class(CPR["medical-sign"]) | Class(CPR["symptom"])],
84+
range=[Class(CPR.person)],
85+
)
86+
# cpr:realized-by
87+
realizedBy = Property( # noqa: N806
88+
CPR["realized-by"],
89+
comment=[
90+
Literal(
91+
"""The epistemological relation in which screening acts and
92+
the problems they realize stand to each other"""
93+
)
94+
],
95+
inverseOf=Property(CPR["realizes"]),
96+
domain=[Class(CPR["medical-problem"])],
97+
range=[Class(CPR["screening-act"])],
98+
)
99+
# cpr:realizes
100+
realizes = Property(CPR["realizes"], inverseOf=realizedBy) # noqa: F841
101+
102+
# Classes
103+
# cpr:person
104+
person = Class(CPR.person)
105+
person.comment = [
106+
Literal(
107+
"""A class which directly corresponds with the “Person” class in
108+
both GALEN and Cyc"""
109+
)
110+
]
111+
person.subClassOf = [Class(EDNS["rational-physical-object"])]
112+
person.equivalentClass = [Class(GALEN.Person), Class(CYC.Person)]
113+
114+
# cpr:patient
115+
patient = Class(CPR.patient)
116+
patient.comment = [
117+
Literal(
118+
"""A class which directly corresponds with the “Patient”
119+
and “MedicalPatient” classes in GALEN / Cyc"""
120+
)
121+
]
122+
# patient.equivalentClass = [Class(GALEN.Patient),Class(CYC.MedicalPatient)]
123+
patient.subClassOf = [CPR["represented-by"] @ some @ Class(CPR["patient-record"])]
124+
person += patient
125+
126+
# cpr:clinician
127+
clinician = Class(CPR.person)
128+
clinician.comment = [
129+
Literal(
130+
"""A person who plays the clinician role (typically Nurse,
131+
Physician / Doctor, etc.)"""
132+
)
133+
]
134+
person += clinician
135+
136+
# bytes
137+
bytes = Class(CPR.bytes)
138+
bytes.comment = [
139+
Literal(
140+
"""The collection of physical objects which constitute a stream of
141+
bytes in memory, disk, etc."""
142+
)
143+
]
144+
bytes.subClassOf = [DOLCE["non-agentive-physical-object"]]
145+
146+
# cpr:patient-record
147+
patientRecord = Class(CPR["patient-record"]) # noqa: N806
148+
patientRecord.comment = [
149+
Literal(
150+
"""a class (a representational artifact [REFTERM]) depicting
151+
relevant clinical information about a specific patient and is
152+
primarily comprised of one or more
153+
cpr:clinical-descriptions."""
154+
)
155+
]
156+
patientRecord.seeAlso = [URIRef("")]
157+
patientRecord.subClassOf = [
158+
bytes,
159+
# Class(CYC.InformationBearingThing),
160+
CPR["representation-of"] @ only @ patient,
161+
REL.OBO_REL_has_proper_part @ some @ Class(CPR["clinical-description"]),
162+
]
163+
164+
# cpr:medical-problem
165+
problem = Class(
166+
CPR["medical-problem"],
167+
subClassOf=[
168+
Class(DOLCE.quality),
169+
realizedBy @ only @ Class(CPR["screening-act"]),
170+
],
171+
)
172+
problem.comment = [
173+
Literal(
174+
""".. problems that clearly require the intervention of a health
175+
care professional. These include acute problems requiring
176+
hospitalization and chronic problems requiring long-term
177+
management."""
178+
)
179+
]
180+
181+
# cpr:clinical-description
182+
clinDescr = Class(CPR["clinical-description"]) # noqa: N806
183+
clinDescr.disjointWith = [CPR["patient-record"]]
184+
clinDescr.comment = [
185+
Literal(
186+
"""A class which corresponds (at least syntactically) with the HL7
187+
RIM Act Class, insofar as its members consist of clinical
188+
recordings (representational artifacts) of natural phenomena
189+
of clinical significance"""
190+
)
191+
]
192+
clinDescr.subClassOf = [
193+
bytes,
194+
# Class(CYC.InformationBearingThing),
195+
DOLCE["has-quality"] @ some @ Class(TIME.TemporalEntity),
196+
descrOf @ min @ Literal(1),
197+
]
198+
199+
# cpr:medical-sign
200+
sign = Class(
201+
CPR["medical-sign"],
202+
subClassOf=[
203+
problem,
204+
Property(CPR["interpreted-by"]) @ only @ clinician,
205+
Property(CPR["interpreted-by"]) @ some @ clinician,
206+
],
207+
disjointWith=[CPR.symptom],
208+
)
209+
sign.comment = [
210+
Literal(
211+
"""A cpr:medical-problem which are specifically interpreted by a
212+
clinician. As such, this class is informally defined as an
213+
objective indication of a quality typically detected by a
214+
physician during a physical examination of a patient."""
215+
)
216+
]
217+
218+
symptom = Class(
219+
CPR["symptom"],
220+
subClassOf=[
221+
problem,
222+
Property(CPR["interpreted-by"]) @ only @ patient,
223+
Property(CPR["interpreted-by"]) @ some @ patient,
224+
],
225+
disjointWith=[sign],
226+
)
227+
symptom.comment = [
228+
Literal(
229+
"""(Medicine) any sensation or change in bodily function that is
230+
experienced by a patient and is associated with a particular
231+
disease."""
232+
)
233+
]
234+
235+
# clinical-act heriarchy
236+
clinicalAct = Class( # noqa: N806
237+
CPR["clinical-act"], subClassOf=[Class(EDNS.activity)]
238+
)
239+
240+
therapy = Class(CPR["therapeutic-act"], subClassOf=[clinicalAct])
241+
therapy += Class(CPR["physical-therapy"], disjointWith=[CPR["medical-therapy"]])
242+
therapy += Class(
243+
CPR["psychological-therapy"],
244+
disjointWith=[CPR["medical-therapy"], CPR["physical-therapy"]],
245+
)
246+
247+
medicalTherapy = Class( # noqa: N806
248+
CPR["medical-therapy"],
249+
disjointWith=[CPR["physical-therapy"], CPR["psychological-therapy"]],
250+
)
251+
therapy += medicalTherapy
252+
medicalTherapy += Class(CPR["substance-administration"])
253+
254+
diagnosticAct = Class(CPR["diagnostic-act"], subClassOf=[clinicalAct]) # noqa: N806
255+
diagnosticAct.disjointWith = [CPR["therapeutic-act"]]
256+
257+
screeningAct = Class(CPR["screening-act"]) # noqa: N806
258+
screeningAct += Class(CPR["laboratory-test"])
259+
260+
diagnosticAct += screeningAct
261+
262+
screeningAct += Class(
263+
CPR["medical-history-screening-act"],
264+
disjointWith=[CPR["clinical-examination"], CPR["laboratory-test"]],
265+
)
266+
267+
screeningAct += Class(
268+
CPR["clinical-examination"],
269+
disjointWith=[CPR["laboratory-test"], CPR["medical-history-screening-act"]],
270+
)
271+
272+
device = Class( # noqa: F841
273+
CPR["medical-device"], subClassOf=[Class(GALEN.Device)]
274+
)
275+
276+
print(g.serialize(format="turtle"))
277+
278+
279+
if __name__ == "__main__":
280+
infixowl_example()

0 commit comments

Comments
 (0)