Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: bugs with
rdflib.extras.infixowl
(#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: - <#2307> Changes are primarily authored by <https://github.com/gjhiggins>. --------- Co-authored-by: Graham Higgins <gjh@bel-epa.com>
- Loading branch information
Showing
4 changed files
with
488 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,280 @@ | ||
from rdflib import Graph, Literal, Namespace, URIRef | ||
from rdflib.extras.infixowl import Class, Ontology, Property, min, only, some | ||
|
||
CPR = Namespace("http://purl.org/cpr/0.75#") | ||
INF = Namespace("http://www.loa-cnr.it/ontologies/InformationObjects.owl#") | ||
EDNS = Namespace("http://www.loa-cnr.it/ontologies/ExtendedDnS.owl#") | ||
DOLCE = Namespace("http://www.loa-cnr.it/ontologies/DOLCE-Lite.owl#") | ||
REL = Namespace("http://www.geneontology.org/owl#") | ||
GALEN = Namespace("http://www.co-ode.org/ontologies/galen#") | ||
TIME = Namespace("http://www.w3.org/2006/time#") | ||
CYC = Namespace("http://sw.cyc.com/2006/07/27/cyc/") | ||
|
||
|
||
def infixowl_example(): | ||
g = Graph() | ||
g.bind("cpr", CPR, override=False) | ||
g.bind("ro", REL, override=False) | ||
g.bind("inf", INF, override=False) | ||
g.bind("edns", EDNS, override=False) | ||
g.bind("dol", DOLCE, override=False) | ||
g.bind("time", TIME, override=False) | ||
g.bind("galen", GALEN, override=False) | ||
|
||
Class.factoryGraph = g | ||
Property.factoryGraph = g | ||
Ontology.factoryGraph = g | ||
|
||
cprOntology = Ontology(URIRef("http://purl.org/cpr/owl")) # noqa: N806 | ||
cprOntology.imports = [ | ||
URIRef("http://obo.sourceforge.net/relationship/relationship.owl"), | ||
URIRef(DOLCE), | ||
URIRef(EDNS), | ||
URIRef("http://www.w3.org/2006/time#"), | ||
] | ||
cprOntology.comment = [ | ||
Literal( | ||
"""This OWL ontology was generated by Fuxi 0.85b.dev-r107 | ||
(with newly added Infix OWL syntax library). It imports the | ||
OBO relationship ontology, DOLCE, and OWL time. It formally | ||
defines a focused, core set of archetypes [Jung, C.] | ||
replicated in various patient record terminology. This core is | ||
defined in RDF and follows the normalization principles | ||
of "rigorous formal ontologies" [Rector, A.].""" | ||
) | ||
] | ||
cprOntology.setVersion(Literal("0.75")) | ||
|
||
# Relations | ||
# represented-by | ||
representationOf = Property( # noqa: N806 | ||
CPR["representation-of"], | ||
inverseOf=Property(CPR["represented-by"]), | ||
comment=[ | ||
Literal( | ||
"""Patient records stand in the cpr:representation-of relation | ||
with patients""" | ||
) | ||
], | ||
) | ||
representedBy = Property( # noqa: F841, N806 | ||
CPR["represented-by"], inverseOf=representationOf | ||
) | ||
# description-of | ||
descrOf = Property( # noqa: N806 | ||
CPR["description-of"], | ||
comment=[ | ||
Literal( | ||
"""Clinical descriptions stand in the cpr:description-of | ||
relation with various clinical phenomenon""" | ||
) | ||
], | ||
domain=[Class(CPR["clinical-description"])], | ||
) | ||
# cpr:interpreted-by | ||
interpretedBy = Property( # noqa: F841, N806 | ||
CPR["interpreted-by"], | ||
comment=[ | ||
Literal( | ||
"""Signs and symptoms are interpreted by rational physical | ||
objects (people)""" | ||
) | ||
], | ||
domain=[Class(CPR["medical-sign"]) | Class(CPR["symptom"])], | ||
range=[Class(CPR.person)], | ||
) | ||
# cpr:realized-by | ||
realizedBy = Property( # noqa: N806 | ||
CPR["realized-by"], | ||
comment=[ | ||
Literal( | ||
"""The epistemological relation in which screening acts and | ||
the problems they realize stand to each other""" | ||
) | ||
], | ||
inverseOf=Property(CPR["realizes"]), | ||
domain=[Class(CPR["medical-problem"])], | ||
range=[Class(CPR["screening-act"])], | ||
) | ||
# cpr:realizes | ||
realizes = Property(CPR["realizes"], inverseOf=realizedBy) # noqa: F841 | ||
|
||
# Classes | ||
# cpr:person | ||
person = Class(CPR.person) | ||
person.comment = [ | ||
Literal( | ||
"""A class which directly corresponds with the “Person” class in | ||
both GALEN and Cyc""" | ||
) | ||
] | ||
person.subClassOf = [Class(EDNS["rational-physical-object"])] | ||
person.equivalentClass = [Class(GALEN.Person), Class(CYC.Person)] | ||
|
||
# cpr:patient | ||
patient = Class(CPR.patient) | ||
patient.comment = [ | ||
Literal( | ||
"""A class which directly corresponds with the “Patient” | ||
and “MedicalPatient” classes in GALEN / Cyc""" | ||
) | ||
] | ||
# patient.equivalentClass = [Class(GALEN.Patient),Class(CYC.MedicalPatient)] | ||
patient.subClassOf = [CPR["represented-by"] @ some @ Class(CPR["patient-record"])] | ||
person += patient | ||
|
||
# cpr:clinician | ||
clinician = Class(CPR.person) | ||
clinician.comment = [ | ||
Literal( | ||
"""A person who plays the clinician role (typically Nurse, | ||
Physician / Doctor, etc.)""" | ||
) | ||
] | ||
person += clinician | ||
|
||
# bytes | ||
bytes = Class(CPR.bytes) | ||
bytes.comment = [ | ||
Literal( | ||
"""The collection of physical objects which constitute a stream of | ||
bytes in memory, disk, etc.""" | ||
) | ||
] | ||
bytes.subClassOf = [DOLCE["non-agentive-physical-object"]] | ||
|
||
# cpr:patient-record | ||
patientRecord = Class(CPR["patient-record"]) # noqa: N806 | ||
patientRecord.comment = [ | ||
Literal( | ||
"""a class (a representational artifact [REFTERM]) depicting | ||
relevant clinical information about a specific patient and is | ||
primarily comprised of one or more | ||
cpr:clinical-descriptions.""" | ||
) | ||
] | ||
patientRecord.seeAlso = [URIRef("")] | ||
patientRecord.subClassOf = [ | ||
bytes, | ||
# Class(CYC.InformationBearingThing), | ||
CPR["representation-of"] @ only @ patient, | ||
REL.OBO_REL_has_proper_part @ some @ Class(CPR["clinical-description"]), | ||
] | ||
|
||
# cpr:medical-problem | ||
problem = Class( | ||
CPR["medical-problem"], | ||
subClassOf=[ | ||
Class(DOLCE.quality), | ||
realizedBy @ only @ Class(CPR["screening-act"]), | ||
], | ||
) | ||
problem.comment = [ | ||
Literal( | ||
""".. problems that clearly require the intervention of a health | ||
care professional. These include acute problems requiring | ||
hospitalization and chronic problems requiring long-term | ||
management.""" | ||
) | ||
] | ||
|
||
# cpr:clinical-description | ||
clinDescr = Class(CPR["clinical-description"]) # noqa: N806 | ||
clinDescr.disjointWith = [CPR["patient-record"]] | ||
clinDescr.comment = [ | ||
Literal( | ||
"""A class which corresponds (at least syntactically) with the HL7 | ||
RIM Act Class, insofar as its members consist of clinical | ||
recordings (representational artifacts) of natural phenomena | ||
of clinical significance""" | ||
) | ||
] | ||
clinDescr.subClassOf = [ | ||
bytes, | ||
# Class(CYC.InformationBearingThing), | ||
DOLCE["has-quality"] @ some @ Class(TIME.TemporalEntity), | ||
descrOf @ min @ Literal(1), | ||
] | ||
|
||
# cpr:medical-sign | ||
sign = Class( | ||
CPR["medical-sign"], | ||
subClassOf=[ | ||
problem, | ||
Property(CPR["interpreted-by"]) @ only @ clinician, | ||
Property(CPR["interpreted-by"]) @ some @ clinician, | ||
], | ||
disjointWith=[CPR.symptom], | ||
) | ||
sign.comment = [ | ||
Literal( | ||
"""A cpr:medical-problem which are specifically interpreted by a | ||
clinician. As such, this class is informally defined as an | ||
objective indication of a quality typically detected by a | ||
physician during a physical examination of a patient.""" | ||
) | ||
] | ||
|
||
symptom = Class( | ||
CPR["symptom"], | ||
subClassOf=[ | ||
problem, | ||
Property(CPR["interpreted-by"]) @ only @ patient, | ||
Property(CPR["interpreted-by"]) @ some @ patient, | ||
], | ||
disjointWith=[sign], | ||
) | ||
symptom.comment = [ | ||
Literal( | ||
"""(Medicine) any sensation or change in bodily function that is | ||
experienced by a patient and is associated with a particular | ||
disease.""" | ||
) | ||
] | ||
|
||
# clinical-act heriarchy | ||
clinicalAct = Class( # noqa: N806 | ||
CPR["clinical-act"], subClassOf=[Class(EDNS.activity)] | ||
) | ||
|
||
therapy = Class(CPR["therapeutic-act"], subClassOf=[clinicalAct]) | ||
therapy += Class(CPR["physical-therapy"], disjointWith=[CPR["medical-therapy"]]) | ||
therapy += Class( | ||
CPR["psychological-therapy"], | ||
disjointWith=[CPR["medical-therapy"], CPR["physical-therapy"]], | ||
) | ||
|
||
medicalTherapy = Class( # noqa: N806 | ||
CPR["medical-therapy"], | ||
disjointWith=[CPR["physical-therapy"], CPR["psychological-therapy"]], | ||
) | ||
therapy += medicalTherapy | ||
medicalTherapy += Class(CPR["substance-administration"]) | ||
|
||
diagnosticAct = Class(CPR["diagnostic-act"], subClassOf=[clinicalAct]) # noqa: N806 | ||
diagnosticAct.disjointWith = [CPR["therapeutic-act"]] | ||
|
||
screeningAct = Class(CPR["screening-act"]) # noqa: N806 | ||
screeningAct += Class(CPR["laboratory-test"]) | ||
|
||
diagnosticAct += screeningAct | ||
|
||
screeningAct += Class( | ||
CPR["medical-history-screening-act"], | ||
disjointWith=[CPR["clinical-examination"], CPR["laboratory-test"]], | ||
) | ||
|
||
screeningAct += Class( | ||
CPR["clinical-examination"], | ||
disjointWith=[CPR["laboratory-test"], CPR["medical-history-screening-act"]], | ||
) | ||
|
||
device = Class( # noqa: F841 | ||
CPR["medical-device"], subClassOf=[Class(GALEN.Device)] | ||
) | ||
|
||
print(g.serialize(format="turtle")) | ||
|
||
|
||
if __name__ == "__main__": | ||
infixowl_example() |
Oops, something went wrong.