feat: Add migration guide and patterns for transitioning from SHACL-AF to SHACL 1.2#879
feat: Add migration guide and patterns for transitioning from SHACL-AF to SHACL 1.2#879simonstey wants to merge 2 commits into
Conversation
simonstey
commented
May 6, 2026
- Introduced a comprehensive migration guide detailing architectural differences, vocabulary mapping, syntax migration, and new capabilities in SHACL 1.2.
- Created a migration patterns cookbook with specific examples for rewriting SHACL-AF rules into SHACL 1.2, covering various common patterns and their transformations.
- See this document rendered online here
81fdcfd to
24d523b
Compare
|
Just checking - this PR has two MD files : and does not itself change index.html? |
|
Something else that has been suggested is adding sh:rule [
rdf:type sh:SHACLRule ;
srl:rule "...."
] |
| These features have no SHACL-AF equivalent. Migrated rules can leverage them | ||
| for improved expressiveness. | ||
|
|
||
| ### 5.1 Negation as Failure (`NOT`) |
|
Relates to issue #776 |
3cf9406 to
c047619
Compare
| |------|--------|-----------| | ||
| | SHACL-AF | `sh:` | `http://www.w3.org/ns/shacl#` | | ||
| | SHACL 1.2 Rules | `srl:` | `http://www.w3.org/ns/shacl-rules#` | | ||
| | SHACL 1.2 (expressions) | `sparql:` | `http://www.w3.org/ns/sparql#` | |
There was a problem hiding this comment.
This comment is unclear to me. I cannot say whether @simonstey understands it better.
| WHERE { | ||
| $this ex:width ?width . | ||
| $this ex:height ?height . | ||
| BIND (?width * ?height AS ?area) . |
There was a problem hiding this comment.
i.e.,
| BIND (?width * ?height AS ?area) . | |
| SET (?area := ?width * ?height ) . |
?
There was a problem hiding this comment.
yes, but not for the "old" SHACL-AF rules -->
have to change it here though:
**SHACL 1.2 SRL:**
```
PREFIX ex: <http://example.com/ns#>
RULE { ?this ex:area ?area }
WHERE {
?this a ex:Rectangle .
?this ex:width ?width .
?this ex:height ?height .
SET (?area := ?width * ?height ) .
}
```|
Excellent! Do you think this should be a WG NOTE, or https://github.com/w3c/shacl-resources, or some other place? |
|
|
||
| **After (in SRL):** | ||
| ``` | ||
| BIND(ex:multiply(?w, ?h) AS ?area) |
There was a problem hiding this comment.
Given all the BIND -> SET comments elsewhere, shouldn't the same be applied here?
There was a problem hiding this comment.
yes, you are totally right
|
@simonstey Would it be possible to update this PR so that it only has the markdown files? |
8bfb87f to
6e6f7a3
Compare
done fwiw, since I had to look up on how to do this without too much hassle myself, I might as well share it-> move branch base onto latest gh-pages -> pull the two files from the old tip -> commit and push -> |
|
|
| dependency cycle contains a closed dependency; if it does, the spec leaves the | ||
| outcome undefined. This guarantees a single well-defined, finite outcome. |
There was a problem hiding this comment.
| dependency cycle contains a closed dependency; if it does, the spec leaves the | |
| outcome undefined. This guarantees a single well-defined, finite outcome. | |
| dependency cycle contain a closed dependency; if any do, this specification | |
| leaves the outcome undefined. This guarantees a single, well-defined, finite | |
| outcome. |
| an assignment, or a blank-node-producing head is what introduces a hard stratum | ||
| boundary. |
There was a problem hiding this comment.
| an assignment, or a blank-node-producing head is what introduces a hard stratum | |
| boundary. | |
| an assignment, or a blank-node-producing head introduces a hard stratum boundary. |
| | — | `srl:filter` | New; `FILTER` equivalent | | ||
| | — | `srl:assign` | New; assignment element (`SET`) | | ||
| | — | `srl:assignVar` | New; the variable assigned by an `srl:assign` | | ||
| | — | `srl:assignValue` | New; the value/expression of an `srl:assign` | |
There was a problem hiding this comment.
| | — | `srl:assignValue` | New; the value/expression of an `srl:assign` | | |
| | — | `srl:assignValue` | New; the value or expression of an `srl:assign` | |
| are used both in `srl:head` (triple templates) and in `srl:body`/`srl:data` | ||
| (triple patterns and data triples), not only for the SHACL-AF `sh:subject`/etc. | ||
| mapping shown above. |
There was a problem hiding this comment.
| are used both in `srl:head` (triple templates) and in `srl:body`/`srl:data` | |
| (triple patterns and data triples), not only for the SHACL-AF `sh:subject`/etc. | |
| mapping shown above. | |
| are used in `srl:head` (triple templates) as well as `srl:body` and `srl:data` | |
| (triple patterns and data triples), not only for the SHACL-AF `sh:subject`, etc., | |
| mappings shown above. |
| - `CONSTRUCT { } WHERE { }` → `RULE { } WHERE { }` | ||
| - Declare prefixes via `PREFIX` keyword, not `sh:prefixes` indirection | ||
| - SPARQL `BIND(expr AS ?v)` → SRL `SET (?v := expr)`; SRL text has no `BIND` | ||
| - The assignment makes this rule a **run-once rule** (it has an `srl:assign`) |
There was a problem hiding this comment.
| - The assignment makes this rule a **run-once rule** (it has an `srl:assign`) | |
| - The assignment (`srl:assign`) makes this a **run-once rule** |
| definition mechanism is defined in SHACL 1.2 Node Expressions (separate spec), | ||
| not in the rules spec itself. |
There was a problem hiding this comment.
Shouldn't this (and similar) reference be made a live link to SHACL 1.2 Node Expressions, if not directly to the definition of the function definition mechanism therein?
| definition mechanism is defined in SHACL 1.2 Node Expressions (separate spec), | |
| not in the rules spec itself. | |
| definition mechanism is defined in SHACL 1.2 Node Expressions (a separate | |
| specification), not in the Rules specification itself. |
| - Within a stratum, evaluate **run-once rules** (those with assignments or | ||
| blank-node-producing heads) exactly once, then iterate the **general rules** | ||
| to a fixed point | ||
| - Evaluate each stratum completely and in order before proceeding to the next |
There was a problem hiding this comment.
Even in an unordered list, there is often a logic to their ordering and their wording. I believe these adjustments make this list more logical and more likely to be followed correctly.
| - Within a stratum, evaluate **run-once rules** (those with assignments or | |
| blank-node-producing heads) exactly once, then iterate the **general rules** | |
| to a fixed point | |
| - Evaluate each stratum completely and in order before proceeding to the next | |
| - Evaluate each stratum completely and in order before proceeding to the next | |
| - Within each stratum, evaluate all **run-once rules** (those with assignments | |
| or blank-node-producing heads) exactly once, then iterate the **general rules** | |
| to a fixed point |
| recursion through **open** dependencies within a stratum — rules iterate until no | ||
| new triples are produced. Recursion through a **closed** dependency (negation, | ||
| assignment, or blank-node-producing head) violates the stratification condition | ||
| and is undefined. Implementations need semi-naive evaluation or equivalent to |
There was a problem hiding this comment.
| and is undefined. Implementations need semi-naive evaluation or equivalent to | |
| and is undefined. Implementations need semi-naive evaluation or an equivalent to |
| - A *closed* dependency (negation, assignment, or a blank node in the head) is | ||
| what forces the depended-on rule into a strictly earlier stratum. Ordinary | ||
| positive chaining like this does not. |
There was a problem hiding this comment.
| - A *closed* dependency (negation, assignment, or a blank node in the head) is | |
| what forces the depended-on rule into a strictly earlier stratum. Ordinary | |
| positive chaining like this does not. | |
| - A *closed* dependency (negation, assignment, or a blank node in the head) | |
| forces a depended-on rule into a strictly earlier stratum. Ordinary positive | |
| chaining like this does not. |