Skip to content

Commit 2a9d694

Browse files
authored
Merge pull request #47 from linkml/issue-46
issue 46
2 parents 0159462 + a6a67d1 commit 2a9d694

File tree

8 files changed

+422
-352
lines changed

8 files changed

+422
-352
lines changed

docs/tutorial/pizza01-toppings-model.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ classes:
2727
slot_uri: rdfs:label
2828
conforms_to:
2929
name: conforms_to
30+
range: string
3031
annotations:
3132
owl.fstring: AnnotationAssertion( dcterms:conformsTo {id} pizza:{V} )
3233
slot_uri: dcterms:conformsTo

linkml_owl/dumpers/owl_dumper.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
SubObjectPropertyOf, TransitiveObjectProperty, SymmetricObjectProperty, AsymmetricObjectProperty, \
3434
ReflexiveObjectProperty, IrreflexiveObjectProperty, Annotation, ObjectMinCardinality, ObjectHasValue, \
3535
NamedIndividual, DataSomeValuesFrom, DataHasValue, DataAllValuesFrom, AnnotationProperty, DataProperty, Datatype, \
36-
DisjointClasses, DisjointUnion
36+
DisjointClasses, DisjointUnion, DataPropertyAssertion
3737

3838
from linkml_runtime.dumpers.dumper_root import Dumper
3939
from linkml_runtime.utils.yamlutils import YAMLRoot
@@ -210,10 +210,23 @@ def transform(self, element: YAMLRoot, schema: SchemaDefinition, is_element_an_o
210210
if element is None:
211211
return None
212212
try:
213-
# translate Enum
213+
# naive method to test if an object is an enum:
214+
# try accessing the `meaning` field. If this fails,
215+
# an exception is thrown, and we carry on.
216+
# (when owl_duper is refactored to not be dependent on
217+
# python dataclasses this will no longer be necessary)
214218
meaning = element.meaning
215-
return self._get_IRI_str(meaning)
219+
if is_element_an_object:
220+
# enum is used in an object context: translate to URI
221+
if not meaning:
222+
enum_uri = schema.default_prefix + ":" + type(element).__name__
223+
meaning = enum_uri + "#" + str(element).replace(" ", "+")
224+
return self._get_IRI_str(meaning)
225+
else:
226+
# enum is used in a data context - stringify
227+
return str(element)
216228
except AttributeError:
229+
# not an enum - carry on
217230
pass
218231
if not self._instance_of_linkml_class(element):
219232
# TODO: better way of detecting atoms
@@ -324,6 +337,8 @@ def transform(self, element: YAMLRoot, schema: SchemaDefinition, is_element_an_o
324337
slot_interps = self._get_slot_interpretations(slot, linkml_class_name)
325338
logging.debug(f'OWL interpretations for {k}={slot_interps}')
326339
is_object_ref = slot.range in self.schema.classes
340+
if "ObjectPropertyAssertion" in slot_interps or "ObjectProperty" in slot_interps:
341+
is_object_ref = True
327342
# normalize input_vals to a list, then recursively transform
328343
if isinstance(v, list):
329344
input_vals = v
@@ -390,7 +405,7 @@ def transform(self, element: YAMLRoot, schema: SchemaDefinition, is_element_an_o
390405
# eai.add_operands((0, SubClassOf.__name__, ObjectUnionOf.__name__), parents, axiom_annotations)
391406
axiom_type = None
392407
# TODO: make this more generic / less repetitive
393-
axiom_types = [SubClassOf, SubObjectPropertyOf, ClassAssertion, ObjectPropertyAssertion, EquivalentClasses, InverseObjectProperties,ObjectPropertyDomain, ObjectPropertyRange, AnnotationAssertion]
408+
axiom_types = [SubClassOf, SubObjectPropertyOf, ClassAssertion, ObjectPropertyAssertion, DataPropertyAssertion, EquivalentClasses, InverseObjectProperties,ObjectPropertyDomain, ObjectPropertyRange, AnnotationAssertion]
394409
for candidate_axiom_type in axiom_types:
395410
if candidate_axiom_type.__name__ in slot_interps:
396411
axiom_type = candidate_axiom_type
@@ -445,6 +460,8 @@ def transform(self, element: YAMLRoot, schema: SchemaDefinition, is_element_an_o
445460
axiom = ClassAssertion(parent, subj)
446461
elif axiom_type == ObjectPropertyAssertion:
447462
axiom = ObjectPropertyAssertion(slot_uri, subj, parent)
463+
elif axiom_type == DataPropertyAssertion:
464+
axiom = DataPropertyAssertion(slot_uri, subj, parent)
448465
elif axiom_type == InverseObjectProperties:
449466
axiom = InverseObjectProperties(subj, parent)
450467
elif axiom_type == ObjectPropertyDomain:

poetry.lock

Lines changed: 114 additions & 226 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ python = "^3.8.1"
3939
click = "*"
4040
funowl = ">=0.2.3"
4141
Jinja2 = ">=3.0.3"
42-
linkml = ">=1.7.4"
42+
linkml = "^1.7.10"
4343
linkml-runtime = ">=1.7.0"
4444

4545
[tool.poetry.dev-dependencies]

tests/inputs/enum_model.yaml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
id: http://example.org/enum-test
2+
name: enum-test
3+
imports:
4+
- linkml:types
5+
prefixes:
6+
linkml: https://w3id.org/linkml/
7+
ex: http://example.org/enum-test/
8+
BFO: http://purl.obolibrary.org/obo/BFO_
9+
10+
default_prefix: ex
11+
default_curi_maps:
12+
- semweb_context
13+
14+
slots:
15+
id:
16+
identifier: true
17+
range: uriorcurie
18+
job:
19+
range: JobEnum
20+
annotations:
21+
owl: ObjectPropertyAssertion
22+
23+
job_str:
24+
range: JobEnum
25+
annotations:
26+
owl: DataPropertyAssertion
27+
28+
classes:
29+
30+
Person:
31+
slots:
32+
- id
33+
- job
34+
- job_str
35+
36+
enums:
37+
JobEnum:
38+
permissible_values:
39+
Bricklayer:
40+
Chimney Sweep:
41+
Welder:
42+
meaning: ex:Welder

tests/inputs/monsters_and_magic.expected.ofn

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,23 @@ Ontology( <https://w3id.org/cmungall/monsters-and-magic>
1919
SubClassOf( mnm:Humanoid mnm:Creature )
2020
Declaration( Class( mnm:Orc ) )
2121
AnnotationAssertion( schema:description mnm:Orc "An orc is a humanoid creature from Middle-earth." )
22+
DataPropertyAssertion( mnm:armor_class mnm:Orc "13"^^xsd:integer )
23+
DataPropertyAssertion( mnm:strength mnm:Orc "16"^^xsd:integer )
24+
DataPropertyAssertion( mnm:dexterity mnm:Orc "11"^^xsd:integer )
25+
DataPropertyAssertion( mnm:constitution mnm:Orc "12"^^xsd:integer )
26+
DataPropertyAssertion( mnm:intelligence mnm:Orc "10"^^xsd:integer )
27+
DataPropertyAssertion( mnm:wisdom mnm:Orc "8"^^xsd:integer )
28+
DataPropertyAssertion( mnm:charisma mnm:Orc "8"^^xsd:integer )
2229
SubClassOf( mnm:Orc mnm:Humanoid )
2330
Declaration( Class( mnm:Goblin ) )
2431
AnnotationAssertion( schema:description mnm:Goblin "A goblin is a humanoid creature from Middle-earth." )
32+
DataPropertyAssertion( mnm:armor_class mnm:Goblin "15"^^xsd:integer )
33+
DataPropertyAssertion( mnm:strength mnm:Goblin "8"^^xsd:integer )
34+
DataPropertyAssertion( mnm:dexterity mnm:Goblin "14"^^xsd:integer )
35+
DataPropertyAssertion( mnm:constitution mnm:Goblin "10"^^xsd:integer )
36+
DataPropertyAssertion( mnm:intelligence mnm:Goblin "10"^^xsd:integer )
37+
DataPropertyAssertion( mnm:wisdom mnm:Goblin "8"^^xsd:integer )
38+
DataPropertyAssertion( mnm:charisma mnm:Goblin "8"^^xsd:integer )
2539
SubClassOf( mnm:Goblin mnm:Humanoid )
2640
Declaration( Class( mnm:SerpentineCreature ) )
2741
AnnotationAssertion( schema:description mnm:SerpentineCreature "A serpentine creature is a creature that has a snake-like body." )
@@ -67,24 +81,66 @@ Ontology( <https://w3id.org/cmungall/monsters-and-magic>
6781
SubClassOf( mnm:MagicallyCreatedCreature mnm:Creature )
6882
Declaration( Class( mnm:RugOfSmothering ) )
6983
AnnotationAssertion( schema:description mnm:RugOfSmothering "A rug of smothering is a rug that can be used to suffocate a creature." )
84+
DataPropertyAssertion( mnm:armor_class mnm:RugOfSmothering "13"^^xsd:integer )
85+
DataPropertyAssertion( mnm:strength mnm:RugOfSmothering "16"^^xsd:integer )
86+
DataPropertyAssertion( mnm:dexterity mnm:RugOfSmothering "11"^^xsd:integer )
87+
DataPropertyAssertion( mnm:constitution mnm:RugOfSmothering "12"^^xsd:integer )
88+
DataPropertyAssertion( mnm:intelligence mnm:RugOfSmothering "10"^^xsd:integer )
89+
DataPropertyAssertion( mnm:wisdom mnm:RugOfSmothering "8"^^xsd:integer )
90+
DataPropertyAssertion( mnm:charisma mnm:RugOfSmothering "8"^^xsd:integer )
7091
SubClassOf( mnm:RugOfSmothering mnm:MagicallyCreatedCreature )
7192
Declaration( Class( mnm:Basilisk ) )
7293
AnnotationAssertion( schema:description mnm:Basilisk "A basilisk is a legendary serpent-like creature with the body of a snake and the head of a king cobra." )
94+
DataPropertyAssertion( mnm:armor_class mnm:Basilisk "13"^^xsd:integer )
95+
DataPropertyAssertion( mnm:strength mnm:Basilisk "16"^^xsd:integer )
96+
DataPropertyAssertion( mnm:dexterity mnm:Basilisk "11"^^xsd:integer )
97+
DataPropertyAssertion( mnm:constitution mnm:Basilisk "12"^^xsd:integer )
98+
DataPropertyAssertion( mnm:intelligence mnm:Basilisk "10"^^xsd:integer )
99+
DataPropertyAssertion( mnm:wisdom mnm:Basilisk "8"^^xsd:integer )
100+
DataPropertyAssertion( mnm:charisma mnm:Basilisk "8"^^xsd:integer )
73101
SubClassOf( mnm:Basilisk mnm:SerpentineCreature )
74102
Declaration( Class( mnm:UndeadCreature ) )
75103
AnnotationAssertion( schema:description mnm:UndeadCreature "An undead creature is a creature that is dead, but has been brought back to life by magic." )
76104
SubClassOf( mnm:UndeadCreature mnm:Humanoid )
77105
Declaration( Class( mnm:WhiteWalker ) )
78106
AnnotationAssertion( schema:description mnm:WhiteWalker "A white walker is an undead creature from the Game of Thrones universe." )
107+
DataPropertyAssertion( mnm:armor_class mnm:WhiteWalker "13"^^xsd:integer )
108+
DataPropertyAssertion( mnm:strength mnm:WhiteWalker "16"^^xsd:integer )
109+
DataPropertyAssertion( mnm:dexterity mnm:WhiteWalker "11"^^xsd:integer )
110+
DataPropertyAssertion( mnm:constitution mnm:WhiteWalker "12"^^xsd:integer )
111+
DataPropertyAssertion( mnm:intelligence mnm:WhiteWalker "10"^^xsd:integer )
112+
DataPropertyAssertion( mnm:wisdom mnm:WhiteWalker "8"^^xsd:integer )
113+
DataPropertyAssertion( mnm:charisma mnm:WhiteWalker "8"^^xsd:integer )
79114
SubClassOf( mnm:WhiteWalker mnm:UndeadCreature )
80115
Declaration( Class( mnm:Lich ) )
81116
AnnotationAssertion( schema:description mnm:Lich "A lich is a fictional undead creature in the Dungeons & Dragons fantasy role-playing game." )
117+
DataPropertyAssertion( mnm:armor_class mnm:Lich "13"^^xsd:integer )
118+
DataPropertyAssertion( mnm:strength mnm:Lich "16"^^xsd:integer )
119+
DataPropertyAssertion( mnm:dexterity mnm:Lich "11"^^xsd:integer )
120+
DataPropertyAssertion( mnm:constitution mnm:Lich "12"^^xsd:integer )
121+
DataPropertyAssertion( mnm:intelligence mnm:Lich "10"^^xsd:integer )
122+
DataPropertyAssertion( mnm:wisdom mnm:Lich "8"^^xsd:integer )
123+
DataPropertyAssertion( mnm:charisma mnm:Lich "8"^^xsd:integer )
82124
SubClassOf( mnm:Lich mnm:UndeadCreature )
83125
Declaration( Class( mnm:Vampire ) )
84126
AnnotationAssertion( schema:description mnm:Vampire "A vampire is a fictional undead creature in the Dungeons & Dragons fantasy role-playing game." )
127+
DataPropertyAssertion( mnm:armor_class mnm:Vampire "13"^^xsd:integer )
128+
DataPropertyAssertion( mnm:strength mnm:Vampire "16"^^xsd:integer )
129+
DataPropertyAssertion( mnm:dexterity mnm:Vampire "11"^^xsd:integer )
130+
DataPropertyAssertion( mnm:constitution mnm:Vampire "12"^^xsd:integer )
131+
DataPropertyAssertion( mnm:intelligence mnm:Vampire "10"^^xsd:integer )
132+
DataPropertyAssertion( mnm:wisdom mnm:Vampire "8"^^xsd:integer )
133+
DataPropertyAssertion( mnm:charisma mnm:Vampire "8"^^xsd:integer )
85134
SubClassOf( mnm:Vampire mnm:UndeadCreature )
86135
Declaration( Class( mnm:Zombie ) )
87136
AnnotationAssertion( schema:description mnm:Zombie "A zombie is a fictional undead creature in the Dungeons & Dragons fantasy role-playing game." )
137+
DataPropertyAssertion( mnm:armor_class mnm:Zombie "13"^^xsd:integer )
138+
DataPropertyAssertion( mnm:strength mnm:Zombie "16"^^xsd:integer )
139+
DataPropertyAssertion( mnm:dexterity mnm:Zombie "11"^^xsd:integer )
140+
DataPropertyAssertion( mnm:constitution mnm:Zombie "12"^^xsd:integer )
141+
DataPropertyAssertion( mnm:intelligence mnm:Zombie "10"^^xsd:integer )
142+
DataPropertyAssertion( mnm:wisdom mnm:Zombie "8"^^xsd:integer )
143+
DataPropertyAssertion( mnm:charisma mnm:Zombie "8"^^xsd:integer )
88144
SubClassOf( mnm:Zombie mnm:UndeadCreature )
89145
Declaration( NamedIndividual( mnm:Smaug ) )
90146
Declaration( Class( mnm:Smaug ) )
@@ -98,6 +154,7 @@ Ontology( <https://w3id.org/cmungall/monsters-and-magic>
98154
ClassAssertion( mnm:WhiteWalker mnm:TheNightKing )
99155
Declaration( Class( mnm:Paladin ) )
100156
AnnotationAssertion( schema:description mnm:Paladin "A paladin is a holy warrior who fights evil using divine magic." )
157+
DataPropertyAssertion( mnm:hit_dice mnm:Paladin "D10" )
101158
Declaration( Class( mnm:Wizard ) )
102159
AnnotationAssertion( schema:description mnm:Wizard "A wizard is a person who practices magic." )
103160
Declaration( Class( mnm:Rogue ) )

0 commit comments

Comments
 (0)