Skip to content

Annotation properties declared with xsd:string/xsd:dateTime range but asserted with language-tagged values — crashes Protégé editor, undetectable by ELK #8

Description

@jclerman

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

  1. 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.
  2. 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).
  3. Separately, investigate and fix RID:Replaced_by's range/value-type mismatch (IRI values vs. declared xsd:string range).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions