Skip to content

Support for RDF 1.2 triple terms (without asserted triple) #379

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
bergos opened this issue May 12, 2025 · 2 comments
Open

Support for RDF 1.2 triple terms (without asserted triple) #379

bergos opened this issue May 12, 2025 · 2 comments
Labels
Core For SHACL 1.2 Core spec

Comments

@bergos
Copy link
Contributor

bergos commented May 12, 2025

PR #368 covers the use case with asserted triples. But we haven't decided yet how to deal with targets for reifiers that don't have an asserted triple. SPARQL and Node Expressions could be used, but we may want to support these use cases in the core specification out-of-the-box. Examples and use cases should be collected for further discussions.

Example data without asserted triple:

# asserted triple is not present in the graph!
# ex:Bob ex:age 23 .

# reified triples expanded to triple term
_:id rdf:reifies <<( ex:Bob ex:age 23 )>> .
_:id ex:date "2019-12-05"^^xsd:date .
_:id ex:author ex:Claire .
@bergos bergos added the Core For SHACL 1.2 Core spec label Jun 2, 2025
@recalcitrantsupplant
Copy link

Here's a potential extension:

Example 1:

_:id rdf:reifies <<( ex:Bob ex:age 23 )>> .
_:id ex:date "2019-12-05"^^xsd:date .
_:id ex:author ex:Claire .
ex:TripleTermValidationShape sh:targetObjectsOf rdf:reifies ;
    sh:reifiedSubject [
        sh:nodeKind sh:IRI ;
    ] ;
    sh:reifiedPredicate [
        sh:in ( ex:age ex:height ) ;
    ] ;
    sh:reifiedObject [
        sh:datatype xsd:integer ;
        sh:minInclusive 0 ;
    ] .

Example 2 with nested triple terms:

<< ex:Bob ex:age 23 >> ex:confidence 0.9 .
_:s rdf:reifies << << ex:Bob ex:age 23 >> ex:confidence 0.9 >> .
ex:ConfidenceShape sh:targetObjectsOf rdf:reifies ;
    sh:reifiedSubject ex:InnerTripleShape ;
    sh:reifiedPredicate [
        sh:hasValue ex:confidence ;
    ] ;
    sh:reifiedObject [
        sh:datatype xsd:decimal ;
        sh:minInclusive 0.0 ;
        sh:maxInclusive 1.0 ;
    ] .

ex:InnerTripleShape sh:reifiedSubject [
        sh:nodeKind sh:IRI ;
    ] ;
    sh:reifiedPredicate [
        sh:hasValue ex:age ;
    ] ;
    sh:reifiedObject [
        sh:datatype xsd:integer ;
    ] .

So sh:reifiedSubject, sh:reifiedPredicate, sh:reifiedObject would be functionally similar to sh:property (I think not sub properties though). The shapes would be similar to property shapes, without the need for sh:path, with the value node being explicit from the property used. I don't believe the triple term would need to be materialised or put into the data graph (or any other new triple term related graph).

Targeting via sh:targetObjectsOf rdf:reifies could potentially be quite broad.

@bergos
Copy link
Contributor Author

bergos commented Jun 5, 2025

Here is a list of possible use cases for reification in SHACL with proposals on how SHACL could be extended to cover it.

The following example data graph is used for all use cases:

ex:age a rdf:Property ;
  ex:version 1 .

_:id rdf:reifies <<( ex:Bob ex:age 23 )>> .
_:id ex:date "2019-12-05"^^xsd:date .
_:id ex:author ex:Claire .

# reifier refering to a reifier
# << << ex:Bob ex:age 23 >> ex:author ex:Claire >> .
_:id2 rdf:reifies <<( _:id ex:author ex:Claire )>> .
_:id2 ex:login "Claire321" .

Targets

Triple term

One may want to define a target for a triple term to reach the reifier based on a pattern for the triple term. A new target sh:targetTripleTerm would be introduced with a blank node object value that can be used to define a triple pattern with the properties sh:subject, sh:predicate, and sh:object. The following example would match all triple terms with the predicate ex:age like <<( ex:Bob ex:age 23 )>> in our example data.

ex:shape a sh:NodeShape ;
  sh:targetTripleTerm [
    # sh:subject ex:Bob
    sh:predicate ex:age
    # sh:object 23
  ];
  sh:property [
    sh:path ( [sh:inversePath rdf:reifies] ex:date );
  ].

Is reifier

Selecting only subjects that are/aren't reifiers could be another requirement. The target filter would be extended with an additional property sh:targetReifier. If it's true, only reifiers will be selected, reifiers would be excluded if it's false. The following example would match the _:id target as it's a reifier.

ex:shape a sh:NodeShape ;
  sh:targetSubjectsOf ex:author ;
  sh:targetReifier true;
  sh:property [
    sh:path ex:date ;
  ].

Traverse

All parts of a triple term could be useful for further traversing a path. This is not possible with the existing property path tools.

Traverse out of a triple term

The sh:triplePartOut path would allow traversing out of any triple part if the focus node is a triple term. The object must be one of the triple parts (sh:Subject, sh:Predicate, or sh:Object). The following example would start at the <<( ex:Bob ex:age 23 )>> triple term and traverse into ex:age, and next to the value of ex:version.

ex:shape a sh:NodeShape ;
  sh:targetTripleTerm [
    sh:subject ex:Bob
  ];
  sh:property [
    sh:path ([sh:triplePartOut sh:Predicate] ex:version) ;
    sh:in (1 2)
  ].

Traverse into a triple term

The sh:triplePartInpath would allow traversing into a triple term. The object must be one of the triple parts (sh:Subject, sh:Predicate, or sh:Object). Additional parts of the triple term can be matched with sh:subject, sh:predicate, or sh:object. The following example would start at ex:Claire, traverse into the triple term <<( _:id ex:author ex:Claire )>>, to the reifier _:id2, and last to the value of ex:login.

ex:shape a sh:NodeShape ;
  sh:targetObjectsOf ex:author ;
  sh:property [
    sh:path ([sh:triplePartIn sh:Object; sh:predicate ex:author] [sh:inverse rdf:reifies] ex:login) ;
    sh:in ("Claire321")
  ].

Is reifier constraint

The count of rdf:reifies triples can be used to check if a focus node is a reifier. A short hand constraint sh:isReifier could be defined. The object must be a boolean.

ex:shape a sh:NodeShape ;
  sh:targetSubjectsOf ex:author ;
  sh:isReifier true.

@recalcitrantsupplant My proposal for traversing covers your use case. I favor the sh:path solution because that would keep sh:path the main tool for traversing and it could be used in a sequence to without the shape overhead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Core For SHACL 1.2 Core spec
Projects
None yet
Development

No branches or pull requests

2 participants