Skip to content

feat(contextgen): add @type: @vocab coercion for eligible enums#8

Open
jdsika wants to merge 17 commits intomainfrom
feat/contextgen-enum-vocab-coercion
Open

feat(contextgen): add @type: @vocab coercion for eligible enums#8
jdsika wants to merge 17 commits intomainfrom
feat/contextgen-enum-vocab-coercion

Conversation

@jdsika
Copy link
Copy Markdown

@jdsika jdsika commented Apr 24, 2026

Summary

Adds JSON-LD 1.1 @type: @vocab coercion for enum-ranged slots whose permissible values are eligible (all have meanings, single namespace, text matches local name).

Problem

LinkML's visit_enum is a no-op — enum permissible values are not emitted in the generated JSON-LD context. Slots with enum ranges only get a structural ENUM_CONTEXT mapping ({text: skos:notation, description: skos:prefLabel, meaning: @id}), which requires structured object values.

In practice, JSON data files use bare string enum values (e.g., "DrivableAreaType": "RoadTypeMotorway"). Without context support, these remain plain strings and don't expand to IRIs.

Upstream issue: linkml#2497

Approach

Uses JSON-LD 1.1 §4.2.3 (type coercion via @vocab) combined with §4.1.8 (scoped contexts):

"DrivableAreaType": {
  "@id": "openlabel_v2:DrivableAreaType",
  "@type": "@vocab",
  "@context": {
    "@vocab": "https://w3id.org/ascs-ev/envited-x/openlabel/v2/",
    "text": "skos:notation",
    "description": "skos:prefLabel",
    "meaning": "@id"
  }
}

This supports both value forms simultaneously:

  • Bare string: "RoadTypeMotorway" → expands to IRI via scoped @vocab
  • Structured object: {text, meaning} → SKOS mappings still work

Eligibility Criteria

An enum qualifies only when ALL conditions are met:

  1. Every permissible value has a meaning IRI
  2. All meaning IRIs share the same namespace prefix
  3. Each value's text matches the local part of its meaning CURIE

Ineligible enums fall back to the existing ENUM_CONTEXT behavior.

Changes

  • jsonldcontextgen.py: Added _vocab_eligible_enum() method + modified visit_slot enum branch
  • test_jsonldcontextgen.py: 7 new tests covering eligible/ineligible cases, pyld expansion verification, kitchen_sink fallback

Testing

  • All 38 context generator tests pass (35 passed + 3 xfailed)
  • All 77 OWL generator tests pass
  • pyld expansion tests verify correct IRI expansion for bare strings and structured objects
  • Kitchen sink schema correctly falls back (EmploymentEventType has text≠local)

References

@jdsika jdsika force-pushed the feat/contextgen-enum-vocab-coercion branch 3 times, most recently from 63c5dd9 to 5edfd2c Compare April 25, 2026 10:12
@jdsika jdsika force-pushed the feat/contextgen-enum-vocab-coercion branch from 35af2a2 to b33f469 Compare May 7, 2026 13:56
cmungall and others added 3 commits May 7, 2026 10:52
Co-authored-by: Kevin Schaper <kevinschaper@gmail.com>
Co-authored-by: Corey Cox <69321580+amc-corey-cox@users.noreply.github.com>
@jdsika jdsika force-pushed the feat/contextgen-enum-vocab-coercion branch 2 times, most recently from 51cfa72 to 4e309f8 Compare May 7, 2026 17:12
@jdsika jdsika force-pushed the feat/contextgen-enum-vocab-coercion branch from 4e309f8 to 44515d5 Compare May 7, 2026 20:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants