Skip to content

gen-shacl rules: translate equals_string on IRI- and typed-literal-valued ranges (follow-up to linkml/linkml#3989) #37

Open

Description

@jdsika

What

Since linkml#3989, and in linkml#3990, gen-shacl translates equals_string / equals_string_in in rules only on slots that hold strings or xsd:boolean. Strings means an enum, a type with datatype xsd:string, or no range. On any other range the rule is skipped with a warning (ShaclGenerator._value_terms), while gen-json-schema enforces it with const.

Reproduction (linkml#3990 head c89faac)

# schema.yaml
id: https://example.org/r
name: r
prefixes:
  ex: https://example.org/r/
  linkml: https://w3id.org/linkml/
default_prefix: ex
imports: [linkml:types]
classes:
  Thing:
    attributes:
      guard: {range: string}
      target: {range: uriorcurie}
    rules:
      - preconditions: {slot_conditions: {guard: {value_presence: PRESENT}}}
        postconditions: {slot_conditions: {target: {equals_string: "ex:a"}}}
# data.yaml
guard: g
target: ex:b
# both.yaml
plugins:
  JsonschemaValidationPlugin: {closed: true}
  linkml.validator.plugins.shacl_validation_plugin.ShaclValidationPlugin: {}

linkml-validate --config both.yaml -s schema.yaml -C Thing data.yaml

[ERROR] [data.yaml/0] 'ex:a' was expected in /target
Rule 1 of class 'Thing': skipped, because equals_string(_in) on slot 'target', whose range 'uriorcurie' is neither an enum nor a type with datatype xsd:string or xsd:boolean.

Other ranges behave the same way. The RDF term column shows rdflib_dumper / JSON-LD context / context with --xsd-anyuri-as-iri.

Range RDF term JSON Schema
uri, uriorcurie IRI / "V"^^xsd:anyURI (CURIE unexpanded) / IRI const, enforced
typeof: string, uri: xsd:anyURI IRI / "V"^^xsd:anyURI / IRI enforced
typeof: string, uri: xsd:token "V"^^xsd:token enforced
class with identifier IRI const on the id, enforced
date, datetime, time typed literal (rdflib rewrites …Z to …+00:00) enforced
integer, float, decimal typed literal const: "3" next to type: integer/number: rejects every value

Contract (decide first)

Proposed approach (if in scope)

Acceptance criteria

  • For each newly supported range, SHACL and JSON Schema agree on the same instances. Extend _json_schema_and_shacl_verdicts (test_shaclgen.py) to load data through rdflib_dumper as well as through the JSON-LD context.
  • Ill-typed values fail at generation time, and a non-canonical lexical form in the data is tested.
  • Numeric ranges stay skipped unless the contract changes.

Activity

  1. changed the title [-]gen-shacl rules: translate equals_string on IRI- and typed-literal-valued ranges (follow-up to #3989)[/-] [+]gen-shacl rules: translate equals_string on IRI- and typed-literal-valued ranges (follow-up to linkml/linkml#3989)[/+] on Oct 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions