Symptom
Editing an RID:Synonym value in Protégé Desktop's annotation editor throws IllegalStateException: Attempt to mutate in notification and crashes the edit. This matches a previously-filed upstream Protégé bug (protegeproject/protege#1111 — still open/unfixed there).
Root cause
RadLex.owl declares several annotation properties with AnnotationPropertyRange(... xsd:string) (or, in one case, xsd:dateTime), but many of their actual asserted values are language-tagged literals (e.g. "inferior lingular artery"@en). Per OWL 2, the correct datatype for language-tagged annotation values is rdf:PlainLiteral, not xsd:string (and not rdf:langString, which isn't part of the OWL 2 datatype map). This mismatch is what triggers the Protégé crash: Protégé sets an "overriding datatype" from the declared range and then chokes when the actual value carries a language tag.
This class of error is not detectable by a DL reasoner (ELK or otherwise) — OWL 2 Direct Semantics explicitly excludes annotations ("annotations are treated as not being present"). Only a SPARQL-based check (e.g. robot report/robot query) can catch it.
Affected properties
Verified via robot query against RadLex.owl directly:
| Property |
Total literal values |
Language-tagged |
RID:Synonym |
24,013 |
23,763 |
RID:Acronym |
139 |
107 |
RID:Unsanctioned_Term |
93 |
87 |
RID:Misspelling_of_term |
36 |
35 |
RID:Created |
989 |
16 |
RID:Radlex_version_of_class_change |
2,435 |
8 (all "4.1"@en) |
RID:Source |
3,116 |
7 |
RID:Definition |
3,840 |
4 |
RID:Created's case is worth flagging separately: its range is xsd:dateTime, not xsd:string, so a language tag there isn't a range-design gap, it's a straightforward tagging mistake (dates aren't language-dependent).
Same declared xsd:string range, but no language-tagged values found: RID:Comment (1,931 total), RID:Preferred_Name_for_Obsolete (940 total).
Related but distinct finding: RID:Replaced_by
RID:Replaced_by is declared with range xsd:string, but of its ~442 assertions, only 4 are actual string literals — the other ~438 are IRI references to other RID terms, e.g.:
AnnotationAssertion(RID:Replaced_by RID:RID10009 RID:RID9510)
This is a different (arguably more severe) range violation: most values aren't literals at all. Worth tracking, but should be fixed independently of the language-tag issue above.
Proposed fix
- Add a ROBOT SPARQL check (
tests/sparql/robot/, registered in tests/robot-report-profile.txt, following the existing ?entity ?property ?value convention — see docs/TESTING.md) that flags any annotation property whose declared range disallows language tags but which has language-tagged assertion values, so this can't silently regress.
- Fix the existing data, either by:
- broadening the affected
AnnotationPropertyRange declarations to rdf:PlainLiteral, or
- stripping the language tags from the offending values (e.g.
RID:Created, where the tag is simply wrong).
- Separately, investigate and fix
RID:Replaced_by's range/value-type mismatch (IRI values vs. declared xsd:string range).
Symptom
Editing an
RID:Synonymvalue in Protégé Desktop's annotation editor throwsIllegalStateException: Attempt to mutate in notificationand crashes the edit. This matches a previously-filed upstream Protégé bug (protegeproject/protege#1111 — still open/unfixed there).Root cause
RadLex.owldeclares several annotation properties withAnnotationPropertyRange(... xsd:string)(or, in one case,xsd:dateTime), but many of their actual asserted values are language-tagged literals (e.g."inferior lingular artery"@en). Per OWL 2, the correct datatype for language-tagged annotation values isrdf:PlainLiteral, notxsd:string(and notrdf:langString, which isn't part of the OWL 2 datatype map). This mismatch is what triggers the Protégé crash: Protégé sets an "overriding datatype" from the declared range and then chokes when the actual value carries a language tag.This class of error is not detectable by a DL reasoner (ELK or otherwise) — OWL 2 Direct Semantics explicitly excludes annotations ("annotations are treated as not being present"). Only a SPARQL-based check (e.g.
robot report/robot query) can catch it.Affected properties
Verified via
robot queryagainstRadLex.owldirectly:RID:SynonymRID:AcronymRID:Unsanctioned_TermRID:Misspelling_of_termRID:CreatedRID:Radlex_version_of_class_change"4.1"@en)RID:SourceRID:DefinitionRID:Created's case is worth flagging separately: its range isxsd:dateTime, notxsd:string, so a language tag there isn't a range-design gap, it's a straightforward tagging mistake (dates aren't language-dependent).Same declared
xsd:stringrange, but no language-tagged values found:RID:Comment(1,931 total),RID:Preferred_Name_for_Obsolete(940 total).Related but distinct finding:
RID:Replaced_byRID:Replaced_byis declared with rangexsd:string, but of its ~442 assertions, only 4 are actual string literals — the other ~438 are IRI references to other RID terms, e.g.:This is a different (arguably more severe) range violation: most values aren't literals at all. Worth tracking, but should be fixed independently of the language-tag issue above.
Proposed fix
tests/sparql/robot/, registered intests/robot-report-profile.txt, following the existing?entity ?property ?valueconvention — seedocs/TESTING.md) that flags any annotation property whose declared range disallows language tags but which has language-tagged assertion values, so this can't silently regress.AnnotationPropertyRangedeclarations tordf:PlainLiteral, orRID:Created, where the tag is simply wrong).RID:Replaced_by's range/value-type mismatch (IRI values vs. declaredxsd:stringrange).