SHACL 1.2 ルール

W3C 作業草案

この文書の詳細
このバージョン:
https://www.w3.org/TR/2026/WD-shacl12-rules-20260703/
最新公開バージョン:
https://www.w3.org/TR/shacl12-rules/
最新の編集者草案:
https://w3c.github.io/data-shapes/shacl12-rules/
履歴:
https://www.w3.org/standards/history/shacl12-rules/
コミット履歴
編集者:
Robert David (Ontotext)
(KurrawongAI)
Andy Seaborne (Apache Software Foundation)
Simon Steyskal (Siemens AG)
フィードバック:
GitHub w3c/data-shapes (プルリクエスト, 新しい課題, 未解決の課題)

概要

本文書はSHACLルールを定義する。

SHACL、すなわちShapes Constraint Languageは、RDFグラフの構造を記述するための 言語である。 SHACLは、検証、推論、ドメインのモデリング、他のエージェントに情報を与える オントロジーの生成、ユーザーインターフェイスの構築、コードの生成、データの統合など、 さまざまな目的に使用できる。

SHACLルールは、規則の集合と基礎となるデータグラフの組み合わせから 新しいRDFデータを生成することで推論を提供する。規則はRDFとして、 またはShape Rules Language(SRL)で表現できる。

この仕様は、 Data Shapes Working Groupによって公開されている。

この文書のステータス

この節は、公開時点におけるこの 文書のステータスを説明する。現在のW3C 公開物と、この技術報告の最新改訂版の一覧は、 W3C標準および草案 インデックスで確認できる。

本文書は、Data Shapes Working Groupによって、 勧告 トラックを用いる 作業草案として公開された。

作業草案としての公開は、 W3Cおよびその会員による 支持を意味するものではない。

これは草案文書であり、いつでも他の文書によって更新、置換、または廃止される 可能性がある。この文書を進行中の作業以外のものとして引用することは 適切ではない。 この今後の勧告に対する将来の更新では、 新機能が取り込まれる可能性がある。

本文書は、 W3C 特許 ポリシーの下で運営される グループによって作成された。 W3Cは、そのグループの成果物に関連して行われた 特許開示の公開リスト を維持している。そのページには、 特許を開示するための手順も含まれている。ある個人が、 自身が 必須クレームを含むと考える特許について 実際の知識を有している場合、その個人は W3C特許ポリシー第6節に従って その情報を開示しなければならない。

本文書は、 2025年8月18日版W3Cプロセス文書に準拠する。

SHACL仕様

この仕様は、SHACL 1.2仕様群の一部である。より詳しい それらの導入については、SHACL 1.2概要を参照されたい。

仕様は次のとおりである:

作業草案:

SHACL 1.2 Core
SHACLのコアを定義する
SHACL 1.2 SPARQL Extensions
SHACLのSPARQL関連拡張を定義する
SHACL 1.2 Node Expressions
SHACLでフォーカスノードを決定するために用いられるグラフ式を定義する
SHACL 1.2 Rules
SHACLの規則ベース推論の方法を定義する
SHACL 1.2 UI
ユーザーインターフェイス生成のためのSHACLの使用を定義する
SHACL 1.2 Profiling
SHACLデータを含むデータのプロファイリングのためのSHACLの使用を定義する

作業グループノート草案:

SHACL 1.2 Overview
SHACL仕様一式を概観する
SHACL 1.2 Compact Syntax
SHACLの概念を表現するためのRDF構文を定義する
注記

実装者は、上記仕様への適合レベルを部分的に確認するために、 SHACL 1.2テストスイートのテストケースに 正常に合格できる。 ただし、テストスイートのすべてのテストに合格しても、 仕様への完全な適合を意味するものではないことに注意されたい。 それは、実装がテストスイートでテストされた側面に適合していることのみを意味する。

1. 導入

本文書は、宣言的な規則を通じて既存のRDFデータから 新しいRDFトリプルを導出するための機構である、SHACL 1.2の推論規則を導入する。 本文書は、規則ベース推論の構文と意味論を定義する。

SHACLルールの実装は2つの操作を提供する。 infer操作は、与えられた 基底グラフに規則を適用し、規則の実行によって導出された RDFトリプルを含む推論グラフを生成する。 推論グラフを基底グラフと結合することは任意であり、 ユーザーに委ねられる。query操作は、 与えられたゴールパターンが規則を用いて基底グラフから導出できるかどうかを判定する。

SHACLルールでは、規則のヘッドにあるトリプルテンプレートで使用できる 空白ノードを含む新しいRDF用語を使用できる。

SHACLルールはまた、失敗としての否定など、規則が実行される順序によって 異なる推論グラフにつながり得る構成要素もサポートする。 これを避けるため、規則は層化という技法を用いて評価される。 これは、規則間に単一の暗黙の順序を確立し、常に同じ推論グラフが 生成されることを保証する。

1.1 用語

次の他の仕様は、本文書で使用される 基本的な用語を提供する:

1.2 文書の規約

本文書の一部の例では、RDF 1.2 Turtle [RDF12-TURTLE]を使用する。

本文書では、次の名前空間接頭辞束縛が使用される:

接頭辞 名前空間
rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns#
rdfs: http://www.w3.org/2000/01/rdf-schema#
srl: http://www.w3.org/ns/shacl-rules#
xsd: http://www.w3.org/2001/XMLSchema#
sparql: http://www.w3.org/ns/sparql#
ex: http://example.com/

文書全体を通じて、Turtle内のRDFグラフを含む 色分けされたボックスが現れる。これらのTurtle文書の断片は、 上記の接頭辞束縛を使用する。

編集者注

リセット。適切な箇所ではreSpecの既定の外観を使用する。

# This box represents rules
# This box represents input data
# This box represents inferred data

2. 適合性

非規範的として印が付けられた節に加えて、この仕様におけるすべての作成ガイドライン、図、例、注記は 非規範的である。それ以外のすべては規範的である。

本文書におけるキーワードMUST NOTおよびSHOULDは、 ここに示すようにすべて大文字で現れる場合に限り、 BCP 14 [RFC2119] [RFC8174] に記述されているように解釈される。

この仕様は、次に対する適合基準を定義する:

適合する Shape Rules Language文書は、 RDF 文字列であり、 RuleSet 生成規則から始まる文法に適合し、かつ 7. Shape Rules Language 文法で定義される追加の制約に適合するものである

注記

この仕様は、SHACLルール 処理系が適合しない規則集合をどのように扱うかを定義しない。

2.1 バージョンラベル

バージョンラベルとは、Shape Rules Languageの構文および意味論の 適合性を識別する文字列である。

バージョンラベル
バージョンラベル
"1.2"

バージョン宣言は、文書の早い段階で行うSHOULD

1つのShape Rules Language文書には、複数のバージョン指令が現れることがある。 各指令は、その指令に続く文書の部分に適用され、 別の指令に遭遇するか、文書の終わりに達するまで有効である。

バージョンラベルは、 メディアタイプversionパラメータによっても与えられる。現在有効な バージョン指令がない場合、メディアタイプの一部として指定されたバージョンが 考慮される。

3. SHACLルール

この節は非規範的である。

SHACLルールは、基底グラフ規則集合が与えられると、新しいトリプルを推論する。 評価の出力は、基底グラフには現れない導出された トリプルを含む推論グラフである。

規則は、ボディと呼ばれるパターンと、 ヘッドと呼ばれる結果テンプレートをもつ。 規則は、ボディが結合された基底グラフおよび その時点までの実行から得られた任意の推論済みトリプルに一致するように、 ボディ内の変数の値を見つけることで実行される。 これらの値は、その後、規則ヘッド内のトリプルテンプレートを具体化して 新しい推論済みトリプルを生成するために使用される。

規則は、これ以上トリプルが推論されなくなるまで実行され、 新しい推論済みトリプルが利用可能になるにつれて、規則は複数回 実行されることがある。

SHACLルールの実行は、新しい空白ノードを含む新しいRDF用語を作成する場合にも、 パターンの不在をテストする場合にも、規則の実行順序が異なる結果に つながらないように定義されている。言い換えれば、規則の実行順序にかかわらず、 同じ推論グラフが生成される。

SHACLルールには、RDF構文と、 SPARQL 1.2 Query Languageに着想を得た 人間にとって扱いやすい構文の両方がある。 規則集合の評価にはSPARQLに類似する要素が含まれるが、 規則の実行順序にかかわらず同じ推論グラフが生成されることを 保証するため、細部に違いがある。

3.1 基本パターン

この最初の例では、次のデータグラフと規則集合がある:

上記の規則をデータに適用すると、 :X:Aおよび:B:childOfであると結論する:

次に、他の規則によって生成された:childOfトリプルに依存する 規則を追加することで、:descendedFrom関係を導出できる:

3.2 再帰

:descendedFromトリプルに依存する規則を追加して、 :X:C:descendedFromであると推論できる:

これにより、トリプル:X :descendedFrom :Cが追加される。

この最後の規則は再帰的な規則であり、規則のボディが 規則のヘッドに依存している。

3.3 フィルタリング

規則のボディ内で式を使用して、ボディの照合における変数の値を 制限できる。 たとえば、町とその人口に関するデータが与えられた場合、 人口が1500を超える町のクラスを推論できる:

FILTERは式を評価し、その式がtrueに評価された場合は現在の 変数束縛の集合を保持し、その式がfalseに評価された場合は現在の 変数束縛の集合を破棄する。 これは SPARQLのFILTER操作 と同じであり、SHACLルールはSPARQLと同じ関数や演算子の多くを提供する。

3.4 否定

否定により、一致してはならないパターンを指定できる。 これは「失敗としての否定」と呼ばれる。

否定要素を評価するために、規則評価アルゴリズムは、 否定要素内のパターンに一致するトリプルを生成し得るすべての規則が 完了していることを保証する。これは 層化と呼ばれ、否定が、 データ由来か、他の規則によって推論された推論済みトリプル由来かを問わず、 関連するすべての可能なトリプルに基づくことを保証する。

3.5 代入とRDF 用語の作成

代入により、式の結果を規則のボディ内の変数に代入できる。 これは、データに基づいて新しいRDF用語を作成するために使用できる。

空白ノードは規則ヘッド内で使用でき、規則評価がトリプルを生成するたびに それぞれ新しい空白ノードを生成する。

代入を含む規則、および 規則ヘッドで空白ノードを作成する規則は、 一度だけ実行される規則である。 そのような規則は、それらが依存し得るデータを生成するすべての規則の後に、 かつ、それらが生成するデータに依存する規則の前に実行される。 規則ヘッド内に空白ノードを含む規則も、 新しいRDF用語を作成し、一度だけ実行される規則である。

この条件は、RDF用語を作成する規則が、潜在的に異なる結果を伴って 新しい用語を複数回生成しないこと、また、そのような規則が自身へ戻るループを形成して 無限個のRDF用語を生じさせないことを保証する。

代入内の式を評価する際にエラーが発生した場合、 現在の解写像はその代入によって拒否される。

3.6 規則のインポート

SHACLの規則集合は、その規則集合の 規則インポートにそれらのURLを含めることで、 他の規則集合を取り込むことができる。 これにより、規則を規則集合間で共有されるライブラリとして構造化できる。

規則集合のIMPORTS文は、規則集合内の任意の規則が評価される前に処理される。 インポートのステップ中に、インポートされた規則集合が独自のインポートを持つ場合、 それらも再帰的に処理される。 規則集合の処理中にIMPORTS文をたどると、 循環インポートにつながることがある。規則集合は一度だけインポートされる。 インポート文のグラフにおける循環は、無限ループを引き起こさない。

3.7 データブロック

データブロックにより、RDFトリプルを規則集合評価に直接、簡潔に提供できる。 データブロック内のトリプルは推論グラフに追加され、 規則のボディ内での照合に利用できる。

@@例を更新する

3.8 規則集合の評価

規則は規則集合へと組織化される。 規則集合とデータグラフ(基底グラフ)が評価への入力である。 出力は推論グラフと呼ばれるグラフであり、 そこでは推論されたトリプルはデータグラフに現れない。

評価中、ある規則に基づいて推論されたトリプルは、 他の規則における照合に利用できる。 規則集合の評価は、推論グラフが、 規則集合およびデータグラフの入力から可能なすべてのトリプルを含むまで進む。

評価は、規則自体が評価される前に、 規則集合を準備するための2つのステップから始まる:

  1. 入力規則集合のインポートが解決され、すべての インポートされた規則集合のすべての規則を含む 規則集合が形成される。 (6.2.1 インポートの 処理)。
  2. 層化が計算される(4.4.2 層化 アルゴリズム)。 これにより、否定要素および 代入要素が一貫した、 予測可能な結果を生み出す。層化には、 規則間の依存関係を調べることが含まれる (4.3.1 依存 グラフ)。

規則集合が準備されると、評価は 層化から各層を順番に取り、その層内の規則を完了するまで評価し、 次の層へ進むことで進行する。

3.9 SHACLルールと SPARQLの関係

この節は非規範的である。

SHACLルールとSPARQLには密接な関係がある。SHACLルールはSPARQLと互換性があるように 設計されており、SHACLルールの構成要素の多くはSPARQLから着想を得ている。 しかし、いくつかの違いがある:

3.10 規則タプル

Issue 752: 規則タプル - 規則評価中の作業領域 Rules

リスクあり:

規則タプルはトリプルと互いに素である。 それらはRDF用語のタプル(変数なし)であり、規則集合の評価中にのみ存在する。 規則評価中の中間結果を記録し、規則間でデータを渡すために使用できる。

タプルパターン、テンプレート、およびタプルの構文:

  • TUPLE(termOrVar , ...)
  • 略記: $(termOrVar , ...)

多くの場合、最初の引数は固定名になる。

評価の存続期間中タプルを保持するタプルストアがある。 タプルストアは重複するデータタプルを保持する(集合である RDFグラフとは異なる)。

4. Shape Rules抽象構文

Shape Rules抽象構文は、SHACLルールの論理構造である。 これは、SHACLルールの実行アルゴリズムを定義するために使用される。 SHACLルールの2つの具象構文形式であるShape Rules Language(SRL)と RDF構文(SRL/RDF)は、それぞれ抽象構文を表現する方法を提供する。

4.1 抽象構文の 要素

変数
変数は、トリプルパターン内のあり得る RDF 用語を表す。 変数はでも使用される。
とは、関数または関数形式であり、 引数はRDF用語である。 式は解写像に関して評価され、 結果としてRDF用語を与える。 は、 SHACLリストパラメータ関数 およびSPARQL式と互換性がある。
データブロック
データブロックとは、トリプルの集合である。 これらのトリプルは追加の事実として推論グラフに追加され、 推論過程に含められる。
トリプルテンプレート
トリプルテンプレートとは、各要素が 変数またはRDF 用語トリプル用語である可能性がある)のいずれかである3タプルである。 タプルの2番目の要素は、IRIまたは 変数でなければならない。 トリプルテンプレートは、規則ヘッドに現れる。
トリプル パターン
トリプルパターンとは、各要素が 変数またはRDF 用語(トリプル用語である可能性がある)のいずれかである3タプルである。 タプルの2番目の要素は、IRIまたは 変数でなければならない。
フィルター要素
フィルター要素とは、であり、 規則要素として現れる。 これは、パターン照合における変数の値を制限するために使用される。
トリプルパターン要素
トリプルパターン要素とは、 トリプルパターンであり、 規則要素として現れる。
否定要素
否定要素とは、 規則要素である。 それは、トリプルパターン要素および フィルター要素の列から構成される 否定要素ボディをもつ。
代入要素
代入要素とは、 規則要素であり、 代入変数と呼ばれる 変数と、 代入式と呼ばれる からなる対である。
規則要素
規則要素とは、 トリプルパターン要素フィルター要素否定要素、または 代入要素のいずれかである。
規則ヘッド
規則ヘッドとは、トリプル テンプレートの列である。
規則ボディ
規則ボディとは、規則要素の列である。 すなわち、各列要素は トリプルパターン要素フィルター要素否定要素、 または代入要素のいずれかである。
規則インポート
規則インポート(しばしば単に「imports」)とは、 評価中に含められる他の規則集合のURLの集合である。
規則
規則とは、規則ヘッド(しばしば単に 「head」)と 規則ボディ(しばしば単に「body」)の対である。 規則には、それを識別しやすくするためにURIを与えることができる。
一度だけ実行される規則
一度だけ実行される規則とは、規則集合の評価の特定の時点で 正確に一度だけ実行される規則である。
一般規則
一般規則とは、 一度だけ実行される規則ではない規則である。 一般規則は、規則集合の評価中に複数回実行されることがある。
規則集合
規則集合とは、0個以上の規則の集合、 0個以上のデータブロックの集合、 および0個以上の規則インポートの集合である。 解決済み 規則集合とは、インポートを持たない 規則集合である。 解決済み規則集合は、別の 規則集合から、 インポート処理を適用することで作成される。
基底グラフ
基底グラフとは、 評価過程への入力として与えられるRDFグラフである。
推論 グラフ
推論グラフとは、 規則集合を評価することで生成される RDFグラフである。 それは、規則集合基底グラフに適用することによって推論される、 基底グラフに存在しないすべてのトリプルを含む。
Infer
Inferとは、規則集合を与えられた 基底グラフに適用し、推論された トリプルを含む推論 グラフを生成する操作である。
Query
Queryとは、与えられたゴールパターンが 基底グラフから、 規則集合を用いて導出できるかどうかを判定する操作である。

トリプルパターンまたはトリプル テンプレートにおいて、 タプルの位置1は非公式には主語と呼ばれ、 位置2は非公式には述語と呼ばれ、 位置3は非公式には目的語と呼ばれる。

注記

規則要素の列の要素は、 1から始まる番号でラベル付けされる。

4.2 整形式性条件

整形式性とは、規則集合の抽象構文に課される条件の集合である。 これらの条件は合わせて、規則の 変数が 規則のヘッドにある場合、その値が規則の ボディ内で定義されること、 フィルター要素 または代入式内の各変数が 評価時点で値をもつこと、 そして規則内の各代入が、規則ボディ内で以前に使用されていない 新しい変数を導入することを保証する。

初期変数集合が与えられた 規則要素列について、 整形式性を定義する。

eltiを、規則要素列の i番目の要素とする。

varsiを、 eltiによって定義される変数の集合とし、次のように定める:

V0を、列の初期変数とする。

Viを、 V0と、jiより小さい すべてのvarsjとの和集合とする。

Vallを、Nが列の長さであるときの VNとする。

整形式 列とは、変数集合V0が与えられた 規則要素の列であり、 次の条件を満たすものである:

規則は、規則ボディの列が、 V0を空集合として与えられた 整形式列であり、 かつ、規則ヘッドトリプルテンプレート内の各変数が Vallの要素である場合、 整形式 規則である。

規則集合は、その規則集合のすべての規則が 整形式規則である場合に限り、 整形式規則集合である。

4.3 規則依存関係

規則R1は、2番目の規則の出力が最初の規則のボディの評価に 影響する場合、規則R2に依存する。すなわち、R2のヘッドに、 R1のボディ内の トリプルパターンに一致するトリプルを生成し得る トリプルテンプレートがあり、 それがトリプルパターン要素として、または 否定要素内に現れる場合である。

依存関係には2種類ある: 閉じた依存関係開いた 依存関係である。 閉じた依存関係は、規則R1が実行される前に、 規則R2がその可能なすべての出力を生成していることを保証する。 規則依存関係が閉じていない場合、それは開いた依存関係であり、 最初の規則R1を、規則R2がさらにトリプルを生成するために 再度実行される可能性がある間に実行することを許し、 その後R2からの新しいトリプルによってR1が再評価され得る。

この最初の例では、最初の規則は2番目の規則に対して 開いた依存関係をもつ。

この2番目の例では、最初の規則は2番目の規則に対して 閉じた依存関係をもつ。

トリプル パターン照合

トリプルパターンは、 トリプルテンプレートがそのトリプルパターンに一致するトリプルを生成できる場合、 トリプルテンプレートに一致する。

トリプルパターン依存関係

トリプルパターンは、 そのトリプルパターントリプルテンプレートに一致する可能性がある場合、 トリプルテンプレートに依存する

トリプルパターンは、その トリプルパターンが 規則のヘッド内の トリプルテンプレートのいずれかに依存する場合、 規則に依存する

規則依存関係

規則R1は、R1のボディ内の任意の トリプルパターンが、 トリプルパターン要素としてであれ 否定要素内であれ、 R2のヘッド内の トリプルテンプレート依存する 場合、規則R2依存する

閉じた依存関係

規則R1の規則R2に対する 規則依存関係は、 次の条件のいずれかが成り立つ場合、 閉じた依存関係である:

開いた依存関係

規則R1の規則R2に対する 規則依存関係は、 その依存関係が 閉じた依存関係でない場合、 開いた依存関係である。 すなわち、R2に依存するR1の任意の トリプルパターンは、 トリプルパターン要素としてのみ現れる。

注記

構成要素tSubjtPredtObjをもつ トリプルテンプレートは、 次のすべてが真である場合、構成要素RDF用語 spoをもつトリプルを 生成する可能性がある:

さらに、tSubjtPred、およびtObjの任意の組が 同じ変数である場合、 対応するsp、およびoの組も 同じでなければならない。

4.3.1 依存グラフ

規則間の依存関係は、 依存グラフと呼ばれる有向グラフとして表される。 グラフの頂点は規則集合の規則であり、辺は、その依存関係が 開いた依存関係であるか 閉じた依存関係であるかに応じて、 openまたはclosedのいずれかのラベルをもつ。

依存グラフ
依存グラフとは、 規則集合の有向グラフであり、各頂点は規則集合内の 規則であり、規則 R1が規則R2に依存する場合、規則 R1から規則R2への辺が存在する。 その辺は、依存関係が 開いた依存関係であるか 閉じた依存関係であるかに応じて、 openまたはclosedのいずれかのラベルをもつ。
推移的規則依存関係
規則R1は、 依存グラフ内に R1からR2への経路が存在する場合、規則 R2に対して 推移的依存関係をもつ。
再帰的規則依存関係

規則Rは、依存グラフ内に Rを含む循環経路が存在する場合、 再帰的依存関係をもつ。

注記

依存グラフはデータグラフの影響を受けない。

4.3.2 依存グラフアルゴリズム

次のアルゴリズムは、 規則集合から 依存 グラフを構築する1つの可能な方法を与える。適合性は、 依存グラフの定義を満たす依存グラフを生成することに依存し、 この手順の使用には依存しない。

define mergeLabel(oldLabel, newLabel):
    ## Closed dependency overrides open dependency.
    if oldLabel == "open" and newLabel == "open":
        return "open"
    else:
        return "closed"
    endif
enddefine

## output -- Dependency graph with rule vertices and labeled edges.
define buildDependencyGraph(ruleSet):
    ## edgeLabelMap maps (R1, R2) to "open" or "closed"
    let edgeLabelMap be a map from pair (rule, rule) to label

    foreach rule R1 in ruleSet:
        ## Classify each triple pattern TP in the rule as requiring "open" or "closed"
        ## depending on whether it is in a negation element or not.
        let bodyDependencies = {}
        foreach rule element RBE in the body of R1:
            if RBE is a negation element:
                foreach triple pattern TP in RBE:
                    let item be a pair (TP, "closed")
                    add item to bodyDependencies
                endfor
            else if RBE is a triple pattern element of triple pattern TP:
                let item be a pair (TP, "open")
                add item to bodyDependencies
            else if RBE is a condition element:
                ## Do nothing
            else if RBE is an assignment element:
                ## Do nothing
            endif
        endfor

        foreach pair (triple pattern TP, depLabel) in bodyDependencies:
            if R1 has an assignment element:
              set depLabel to "closed"
            endif
            if R1 has a triple template with a blank node:
              set depLabel to "closed"
            endif
            ## Find depenencies for this triple pattern element or negation element.
            foreach rule R2 in ruleSet:
                foreach triple template TT in head of R2:
                    ## "possibly generate" / matching is defined in
                    ## section 3.3 
                    if TT can possibly match triple pattern TP:
                        let key = (R1, R2)
                        if edgeLabelMap contains key:
                            let oldLabel = edgeLabelMap.get(key)
                            let merged = mergeLabel(oldLabel, depLabel)
                            edgeLabelMap.set(key, merged)
                        else:
                            edgeLabelMap.set(key, depLabel)
                        endif
                    endif
                endfor
            endfor
        endfor
    endfor

    let DP = { }
    foreach entry ((R1, R2), label) in edgeLabelMap:
        add edge (R1 -> R2) labeled label to DP
    endfor

    the result is DP
    enddefine

例:

4.4 層化

層化とは、規則集合を、 層化層の順序付き列 ("strata"、単数形は"stratum"としても知られる)に分割する過程である。 低いの規則は、 高いの規則よりも前に評価される。

層化は、規則間の依存関係に制約を課し、 否定要素代入 要素、および 規則ヘッド内に作成される空白ノードが、 より前の(より低い)基底グラフを用いて計算された結果にのみ依存することを保証する。 これは、与えられた基底グラフ上での 規則集合の評価から、 単一の明確に定義された有限の結果が得られることを保証する。

注記

層化過程は、他の評価上の決定を行うためにも使用できる。 本文書は、一貫した評価に必要な条件を記述し、 層化を形成する1つの可能な方法を与える。 実装は、互換性のある振る舞いを得るために、ここで記述される条件を 満たす必要があるが、提示されたアルゴリズムを実装することは 要求されない。

層化層

層化層SLは、互いに素な規則集合 (SL.onceSL.general)の対である。 SL.onceは、 一度だけ実行される規則を含む。 これは、代入要素を使用する規則、または 規則ヘッド内で空白ノードを生成する規則であり、 これらの規則はそれぞれ、層化層の評価の開始時に 正確に一度だけ評価される。 SL.generalは残りの規則を含み、それらは 新しいトリプルが推論されなくなるまで繰り返し評価される。

層化
層化とは、 規則集合層化層の列である。 規則集合内の各規則は、 層化層のいずれかの集合の1つに 正確に一度現れる。

4.4.1 層化条件

層化は、次の条件が満たされる場合にのみ 定義される。規則集合がこの条件を満たさない場合、 この仕様は、そのような規則集合の評価結果を定義しない。

層化条件
層化条件は、 規則集合依存グラフにおいて、 閉じた依存関係を含む 再帰的依存関係が 存在しないことを要求する。

言い換えれば、依存グラフのいかなる推移的依存循環にも、 NOTまたは一度だけ実行される規則(代入、または空白ノードを含む規則の トリプルテンプレート)は存在しない。

4.4.2 層化アルゴリズム

次のアルゴリズムは、規則集合のみに基づく1つの可能な層化を与える。

## output -- Map: Integer -> Set of rules.

define stratification(ruleSet):

    let DP = Dependency graph for the rule set.
    let stratumMap be a map from rule to integer

    ## The dependency graph should satisfy the stratification condition.
    ## The check for unbounded stratification is a guard 
    ## due to a violation of the stratification condition.
    let limit = num rules + 1
    let maxStratum = 0

    ## initialize stratumMap
    foreach rule in ruleSet:
        stratumMap.set(rule, 0)
        endfor

    boolean changed = true;
    while changed:
        changed = false;
        foreach edge E in DP:
            ## Edge from pRule to qRule with a label
            let pRule = source of edge
            let qRule = destination of the edge
            let label = edge label

            if label == "open" :
                if stratumMap.get(pRule) < stratumMap.get(qRule) :
                    stratumMap.set(pRule, stratumMap.get(qRule))
                    changed = true;
                endif
            endif
            if label == "closed" :
                if stratumMap.get(pRule) <= stratumMap.get(qRule) :
                    let xStratum = 1 + stratumMap.get(qRule)
                    if ( xStratum > limit )
                        ## Stratification requirement violated
                        error "Stratification error"
                        endif
                    stratumMap.set(pRule, xStratum)
                    maxStratum = max(maxStratum, xStratum)
                    changed = true;
                endif
            endif
        endfor
    endwhile

    ## Initialize the result map.
    let stratumRules be a map from integer to rules.
    for i = 0 to maxStratum
        stratumRules.set(i, {})
    endfor

    ## Gather rules in stratumMap with the same level number
    for rule R in map stratumMap:
        let stratumNum = stratumMap.get(R)
        add R to stratumRules.get(stratumNum)
    endfor

    ## Partition each level into once and general
    let stratumLevels be a sequence of pairs of sets of rules.
    for i = 0 to maxStratum:
        let rules = stratumRules.get(i)
        let once = { R in rules | R is a run-once rule }
        let general = rules \ once
        stratumLevels.set(i, pair(once, general))
    endfor

    the result is stratumLevels
enddefine
注記

層化条件の帰結として、 一度だけ実行される規則評価されると、その規則の結果を決定するために使用されたデータは、 以後の評価中に変化しない。

5. Shape Rules Languageの 具象構文形式

2つの具象構文がある。

注記

Shape Rules Language:

RDF規則構文:

5.1 Shape Rules Language構文

文法は以下に示す。

編集者注

ASTから抽象構文への写像。

5.1.1 Shape Rules Languageの略記法

追加のヘルパー(略記):

注記

これらはよく知られた規則パターンを可能にし、また基本的なエンジンにおける 特殊化された実装も可能にする。

  • TRANSITIVE(uri)
  • SYMMETRIC(uri)
  • INVERSE(uri, uri)
Issue 779: 略記法 : `TRANSITIVE`、`SYMMETRIC`、および `INVERSE` Rules

リスクあり:

TRANSITIVEには、実装上の利点と簡潔な表現上の利点の両方がある。 SYMMETRICおよびINVERSEの実装上の利点は明確ではない。

5.2 RDF規則構文

語彙: rdf-syntax-vocab.ttl
SHACLシェイプ: rdf-syntax-shapes.ttl

編集者注

整形式性:

  • すべてのRDFリストは整形式である
  • ボディまたはヘッド要素ごとに、subject - predicate - objectのうち正確に1つ
  • 整形式で、単一値の、リスト引数ノード式
  • 整形式の抽象構文
編集者注

抽象モデルがトリプルへどのように写像されるかを記述する。

編集者注

処理: アキュムレータ、ボトムアップ/構造の走査。

  • データトリプルを収集する
  • 式を写像する
  • トリプルパターンを写像する
  • トリプルテンプレートを写像する
  • 代入を写像する
  • 規則へ写像する
  • 規則集合

構文に含まれないすべてのトリプルは無視される。 他の"srl:"述語は許可されない(??)。

@@ 図解: テキスト構文およびRDF構文におけるSHACL規則集合: すべての機能:

PREFIX :        <http://example/>

DATA { :s :p :o }
RULE { ?x :q :o } WHERE { ?x :p :o }
RULE { ?x :q :o } WHERE { ?x :p :o1 ; :p :o2 }
RULE { ?x :q :o } WHERE { ?x :p ?o . FILTER (?o < 18) }
RULE { ?x :q ?o } WHERE { ?x :p :o . SET (?o := 18) }
RULE { ?x :q ?o } WHERE { ?x :p :o . NOT { ?s :p ?o . FILTER(?o < 18) } }
PREFIX :       <http://example/>
PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX sh:     <http://www.w3.org/ns/shacl#>
PREFIX sparql: <http://www.w3.org/ns/sparql#>
PREFIX srl:    <http://www.w3.org/ns/shacl-rules#>

:ruleSet-1
  rdf:type srl:RuleSet;
  srl:data (
    [ srl:subject :s ; srl:predicate :p; srl:object :o ; ]
  );
  srl:rules (
    [
      rdf:type srl:Rule;
      srl:body (
        [ srl:subject [ srl:varName "x" ] ; srl:predicate :p ; srl:object :o ; ]
      ) ;
      srl:head (
        [ srl:subject [ srl:varName "x" ] ; srl:predicate :q ; srl:object :o ; ]
      )
    ]
    [
      rdf:type srl:Rule ;
      srl:body (
        [ srl:subject [ srl:varName "x" ] ; srl:predicate :p ; srl:object :o1 ; ]
        [ srl:subject [ srl:varName "x" ] ; srl:predicate :p ; srl:object :o2 ; ]
      ) ;
      srl:head (
        [ srl:subject [ srl:varName "x" ] ; srl:predicate :q ; srl:object :o ; ]
      )
    ]
    [
      rdf:type srl:Rule ;
      srl:body (
        [ srl:subject [ srl:varName "x" ] ; srl:predicate :p ; srl:object [ srl:varName "o" ] ; ]
        [
          srl:filter [
            sparql:less-than (
              [ srl:varName "o" ]
              18
            )
          ]
        ]
      ) ;
      srl:head (
        [ srl:subject [ srl:varName "x" ] ; srl:predicate :q ; srl:object :o ; ]
      )
    ]
    [
      rdf:type srl:Rule ;
      srl:body (
        [ srl:subject [ srl:varName "x" ] ; srl:predicate :p ; srl:object :o ; ]
        [
          srl:assign [
            srl:assignValue 18 ;
            srl:assignVar [ srl:varName "o" ]
          ]
        ]
      ) ;
      srl:head (
        [ srl:subject [ srl:varName "x" ] ; srl:predicate :q ; srl:object [ srl:varName "o" ] ; ]
      )
    ]
    [
      rdf:type srl:Rule ;
      srl:body (
        [ srl:subject [ srl:varName "x" ] ; srl:predicate :p ; srl:object :o ; ]
        [
          srl:not (
            [ srl:subject [ srl:varName "s" ] ;     srl:predicate :p ;     srl:object [ srl:varName "o" ] ; ]
            [
              srl:filter [
                sparql:less-than (
                  [ srl:varName "o" ]
                  18
                )
              ]
            ]
          )
        ]
      ) ;
      srl:head (
        [ srl:subject [ srl:varName "x" ] ; srl:predicate :q ; srl:object [ srl:varName "o" ] ; ]
      )
    ]
  ) .

6. 规则集求值

本节定义在给定数据上对规则集求值的结果。 它并不规定该算法作为实现方法。 实现可以使用任何能生成相同结果的算法。

输入数据图 G,称为基础图,以及规则集 RS。
输出由推理三元组组成的 RDF 图 GI

推理出的三元组不包括 基础图的三元组集合中已有的三元组。

6.1 求值定义

解映射
一个解映射 μ 是一个偏函数 μ : VT, 其中 V 是所有变量的集合, T 是所有 RDF 术语的集合。 μ 的定义域记作 dom(μ),它是 Vμ 有定义的子集。在明确表示 解映射时,我们使用术语 。 将 μ0 写作这样的解映射: dom(μ0) 是空集合。
替换函数
替换函数,或简称为替换, 是一个函数 subst(μ, 三元组模式), 它返回一个三元组模式, 其中三元组模式中每个属于 dom(μ) 的变量出现处,都被该 var解映射给出的 RDF 术语替换。 如果所得三元组模式没有变量,那么它就是一个 RDF 三元组
求值 图
求值图是一个 RDF 图,它组合了 基础图 以及规则集求值期间产生的所有三元组。
图匹配
图匹配查找将三元组模式映射到 RDF 图中三元组的方式。

G 为一个 RDF 图TP 为一个 三元组模式。 函数 graphMatch(G, TP) 返回所有可能 的集合; 这些解应用于该三元组模式时,会产生一个存在于 求值图中的三元组

G 为一个 RDF 图TP 为一个 三元组模式

graphMatch(G, TP) = { μ | subst(μ, TP) is a triple in G }
解兼容
如果两个解 S1 和 S2 在共有变量上取值一致,则它们是 兼容的

令 S1 和 S2 为解。

compatible1, μ2) = true
                      if forall v in dom1) intersection dom2)
                          μ1(v) = μ2(v)
compatible1, μ2) = false otherwise
解 序列
解序列是解的多重集合。 该序列没有定义顺序。 它等价于无序列表,并且可以包含重复项。
解合并
如果两个解兼容,则两个解的合并是这样一个解: 它将每个解中的变量映射到 其中一个解给出的 RDF 术语
μ1μ2 为解映射,S1 和 S2 为解序列。
merge(μ1, μ2) = { μ |
                    μ(v) = μ1(v) if v in dom(μ1)
                    μ(v) = μ2(v) otherwise }
merge(S1, S2) = { μ |
                    μ1 in S1, μ2 in S2
                    and compatible(μ1, μ2)
                    μ(v) = merge(μ1, μ2) }
编辑者注

说明定义域是 dom(S1) ∪︀ dom(S2)

说明两个没有共有变量的解是兼容的。

6.2 求值准备

规则集求值的第一步,是准备一个单一的、 有效的规则集。这包括收集所有被导入的规则集, 构建一个单一的组合规则集,然后为该组合规则集计算 分层。

6.2.1 处理导入

已解析规则集通过递归读取另一个 规则集的导入项中提到的所有规则集, 从该规则集生成。

一个规则集有三个组件:R.rulesR.dataR.imports。 两个规则集 RS1RS2规则 集合并 是一个规则集 MR,定义如下:

MR.rules = RS1.rules ∪︀ RS2.rules
MR.data = merge(RS1.data, RS2.data)
MR.imports = {}

其中 mergeRDF 合并 操作。

define imports(rule set RS, set of URLs V), returning rule set
    let I = the set of import URLs declared for the rule set RS
    let RS2 be a rule set formed from RS.rules and RS.data
    foreach URL x in I:
        if x ∉ V:
            V = V ∪︀ { x }
            read rule set RS3 from URL x
            RS2 = rulesetMerge(RS2, imports(RS3, V))
        endif
    endfor
    result is RS2
enddefine

let RS be a rule set
let V = {}
if RS has a location, V = { location of RS }
result is imports(RS, V)

6.2.2 计算分层

创建已解析规则集后,计算 依赖图 (参见 4.3.2 依赖图算法), 然后计算一个 [=stratification] (参见 4.4.2 分层算法)。

6.3 表达式的求值

表达式无论是用于过滤元素还是 赋值元素,都会相对于一个 解映射求值;该解映射为表达式中的每个变量提供一个 RDF 术语值。 4.2 良构性条件 中的良构性要求确保表达式中的所有变量 都出现在解映射中。

define evalFunction(F, μ):
    ## F is an expression: an RDF term, a variable, or op(expr1, ..., exprN)
    ## where op is a function or a functional form.
    if F is an RDF term:
        return F
    if F is a variable:
        ## By well-formedness, F ∈ dom(μ).
        return μ(F)
    ## F is of the form F= op(expr1, ..., exprN)
    if op is a functional form (e.g. IF, logical-or):
        ## Evaluated specifically for op; op may evaluate only some arguments.
        ## For example, IF(c, t, f) evaluates c, then exactly one of t or f.
        return the value defined for op over expr1, ..., exprN under μ
    ## op is an ordinary function: evaluate all arguments first.
    return F(evalFunction(expr1, row), ..., evalFunction(exprN, row))
enddefine

函数 EBV(x) 返回一个 RDF 术语的 有效布尔值

6.4 规则的求值

规则求值,是通过从规则主体计算一个解 序列, 然后使用该解序列中的每个 解映射, 用规则头部生成三元组。

let R be a well-formed rule.

let rule R = (H, B) where
             H is the sequence of triple templates in the head
             B is the sequence of triple pattern elements,
                condition elements, negation elements,
                and assignment elements in the body

# Solution sequence of one solution that does not map any variables.
let SEQ0: Solution sequence = { μ0 }

let G = evaluation graph

# Evaluate rule body
# This function returns a sequence of solutions
define evalRuleElements(B, SEQ, G):

    for each rule element rElt in B:

        if rElt is a triple pattern TP:
            X = graphMatch(G, TP)
            SEQ1 = {}
            for each μ1 in X:
                for each μ2 in SEQ:
                    if compatible(μ1, μ2)
                      μ3 = merge(μ1, μ2)
                      add μ3 to SEQ1
                    endif
                endfor
            endfor
        endif

        if rElt is a condition element with expression F:
            SEQ1 = {}
            for each solution μ in SEQ:
                let x = evalFunction(F, μ)
                if EBV(x) is true:
                    add μ to SEQ1
                endif
            endfor
        endif

        if rElt is a negation expression with body elements N:
            SEQ1 = {}
            for each solution μ in SEQ:
                S = sequence{ μ }
                NEG = evalRuleElements(N, S, G)
                if NEG is empty
                    add μ to SEQ1
                endif
            endfor
        endif

        if rElt is an assignment with variable V and expression expr
            SEQ1 = {}
            for each solution μ in SEQ:
                let x = evalFunction(expr, μ)
                if x is not an error:
                    ## Add mapping V -> x to solution μ
                    let μ2 be a solution mapping μ ∪︀ { (V, x) }
                    add μ2 to SEQ1
                else
                    # Error: drop solution μ
                endif
            endfor
        endif

        if SEQ1 is empty
            SEQ = {}
            return SEQ
        endif

        SEQ = SEQ1
    endfor

    return SEQ
enddefine

let SEQ = evalRuleElements(B, SEQ0, G)

# Evaluate rule head
let OUT = empty set
for each μ in SEQ:
    let S = {}
    for each triple template TT in H:
        let triple = subst(μ, TT)
        Add triple to S
    endfor
    OUT = OUT union S
endfor

result eval(R, G) is OUT

注意,OUT 可能包含数据图中已有的三元组。

6.5 规则集的求值

规则集的求值被定义为执行该规则集 分层中的每个 分层; 其中每个分层都会先按顺序完整执行, 然后再进入下一个分层。 对一个分层求值时,首先对该分层中的每个 只运行一次规则求值,然后反复求值该分层中的 一般规则,直到不再产生新的三元组。

let G0 be the input base graph
let RS be the rule set
let D be the graph of all DATA triples in RS

Apply stratification to RS

let LS be the sequence of layers after stratification

# Inference graph
let GI = { t  D | t  G0 }

# Evaluation graph.
let GE = G0 ∪︀ D

for each stratum ST in LS:
    for each rule R in ST.once:
        let X = eval(R, GE)
        let Y = { t  X | t  GE }
        GI = Y ∪︀ GI
        GE = Y ∪︀ GE
    endfor

    let finished = false
    while !finished:
        finished = true
        for each rule R in ST.general:
            let X = eval(R, GE)
            let Y = { t  X | t  GE }
            if Y is not empty:
                finished = false
                GI = Y ∪︀ GI
                GE = Y ∪︀ GE
            endif
        endfor
    endwhile
endfor
the result is GI

7. 形状规则语言语法

形状规则语言文档是一个以 UTF-8 编码的 RDF 字符串 [RFC3629]。 仅允许使用 Unicode 标量值, 范围为 U+0000U+D7FF 以及 U+E000U+10FFFF。 这排除了 代理码点, 即 U+D800U+DFFF 范围。

7.1 空白

空白 (产生式 WS)用于 分隔两个否则会被(错误地)识别为一个终结符的终结符。 下方以大写表示的规则名指示空白具有重要意义的位置; 这些规则构成了用于构造形状规则语言解析器的一种可能终结符选择。

空白在产生式 String 中具有重要意义。

7.2 注释

注释以位于 IRIREFSTRING_LITERAL1STRING_LITERAL2STRING_LITERAL_LONG1STRING_LITERAL_LONG2 之外的 # 开始, 并持续到行尾(由 LFCR 标记), 如果注释标记之后没有行尾,则持续到文件结尾。 注释被视为空白。

7.3 IRI 引用

相对 IRI 引用按照 统一资源标识符(URI):通用 语法 [RFC3986], 使用第 5.2 节中的基本算法,通过基准 IRI 进行解析。 不执行基于语法的规范化或基于方案的规范化 (RFC3986 第 6.2.2 和 6.2.3 节中所述)。 IRI 引用中额外允许的字符,按 国际化资源标识符 (IRI) [RFC3987] 第 6.5 节所述,以与 URI 引用中未保留字符相同的方式处理。

BASE 指令定义用于解析 相对 IRI 引用的基准 IRI,依据 [RFC3986] 第 5.1.1 节,“内容中嵌入的基准 URI”第 5.1.2 节,“来自封装实体的基准 URI” 定义作用域内基准 IRI 如何来自封装文档, 例如带有 xml:base 指令的 SOAP 信封,或带有 Content-Location 标头的 MIME multipart 文档。 5.1.3,来自检索 URI 的基准 URI中标识的“检索 URI”, 是特定形状规则语言文档 被检索自的 URL。 如果以上均未指定基准 URI,则使用默认 基准 URI(第 5.1.4 节,“默认基准 URI”)。 每个 BASE 指令都会相对于前一个基准 URI 设置新的作用域内基准 URI。

7.4 转义序列

形状规则文档中使用三种形式的转义:

可使用每种转义序列的上下文
数字
转义
字符串
转义
保留字符
转义
IRI, 用作 RDF 术语PREFIX, 或 BASE 声明
局部名称
字符串

%-编码序列位于 IRI 的字符范围中, 并且在局部名称中被显式允许。 它们表现为一个 % 后跟两个十六进制字符,并表示这 同一组三个字符。这些序列在处理过程中不会 被解码。 写作 <http://a.example/%66oo-bar> 的术语 指示 IRI http://a.example/%66oo-bar, 而不是 IRI http://a.example/foo-bar。 带有前缀 PREFIX ex: <http://a.example/> 的术语 ex:%66oo-bar 也指示 IRI http://a.example/%66oo-bar

7.5 语法

此处使用的 EBNF 在 XML 1.0 [EBNF-NOTATION] 中定义。

说明:

  1. 语法的入口点是 RuleSet
  2. 关键词不区分大小写,除了 'a' 区分大小写。
  3. 转义序列 UCHARECHAR 区分大小写。
  4. DATA 块中不允许出现变量。
  5. 在对输入进行词法分析并选择语法规则时,选择最长匹配。
  6. 当使用名称为大写的规则作为终结符时,形状规则语言语法是 LL(1) 和 LALR(1)。
[1]   RuleSet   ::=   RuleOrDataBlock
[2]   RuleOrDataBlock   ::=   Prologue ( RuleOrData+ ( Prologue1 RuleOrData? )* )?
[3]   RuleOrData   ::=   Rule | Data
[4]   Prologue   ::=   Prologue1*
[5]   Prologue1   ::=   BaseDecl | PrefixDecl | VersionDecl | ImportsDecl
[6]   BaseDecl   ::=   'BASE' IRIREF
[7]   PrefixDecl   ::=   'PREFIX' PNAME_NS IRIREF
[8]   VersionDecl   ::=   'VERSION' VersionSpecifier
[9]   VersionSpecifier   ::=   STRING_LITERAL1 | STRING_LITERAL2
[10]   ImportsDecl   ::=   'IMPORTS' iri
[11]   Rule   ::=   Rule1 | Rule2 | Declaration
[12]   Rule1   ::=   'RULE' iri? HeadTemplate 'WHERE' BodyPattern
[13]   Rule2   ::=   'IF' BodyPattern 'THEN' HeadTemplate
[14]   Declaration   ::=   ( 'TRANSITIVE' '(' iri ')' | 'SYMMETRIC' '(' iri ')' | 'INVERSE' '(' iri ',' iri ')' )
[15]   Data   ::=   'DATA' '{' TriplesDataBlock? '}'
[16]   TriplesDataBlock   ::=   TriplesSameSubject ( '.' TriplesDataBlock? )?
[17]   HeadTemplate   ::=   '{' HeadTemplateBlock? '}'
[18]   BodyPattern   ::=   '{' BodyTriplesBlock? ( BodyNotTriples '.'? BodyTriplesBlock? )* '}'
[19]   BodyNotTriples   ::=   Filter | Negation | Assignment
[20]   BodyTriplesBlock   ::=   TriplesBlock
[21]   Negation   ::=   'NOT' '{' BodyBasic '}'
[22]   BodyBasic   ::=   BodyTriplesBlock? ( BodyBasicNotTriples '.'? BodyTriplesBlock? )*
[23]   BodyBasicNotTriples   ::=   Filter
[24]   HeadTemplateBlock   ::=   TriplesBlock
[25]   TriplesBlock   ::=   TriplesSameSubjectPath ( '.' TriplesBlock? )?
[26]   ReifiedTripleBlock   ::=   ReifiedTriple PropertyList
[27]   ReifiedTripleBlockPath   ::=   ReifiedTriple PropertyListPath
[28]   Assignment   ::=   'SET' '(' Var ':=' Expression ')'
[29]   Reifier   ::=   '~' VarOrReifierId?
[30]   VarOrReifierId   ::=   Var | iri | BlankNode
[31]   Filter   ::=   'FILTER' Constraint
[32]   Constraint   ::=   BrackettedExpression | BuiltInCall | FunctionCall
[33]   FunctionCall   ::=   iri ArgList
[34]   ArgList   ::=   NIL | '(' Expression ( ',' Expression )* ')'
[35]   ExpressionList   ::=   NIL | '(' Expression ( ',' Expression )* ')'
[36]   TriplesSameSubject   ::=   VarOrTerm PropertyListNotEmpty | TriplesNode PropertyList | ReifiedTripleBlock
[37]   PropertyList   ::=   PropertyListNotEmpty?
[38]   PropertyListNotEmpty   ::=   Verb ObjectList ( ';' ( Verb ObjectList )? )*
[39]   Verb   ::=   VarOrIri | 'a'
[40]   ObjectList   ::=   Object ( ',' Object )*
[41]   Object   ::=   GraphNode Annotation
[42]   TriplesSameSubjectPath   ::=   VarOrTerm PropertyListPathNotEmpty | TriplesNodePath PropertyListPath | ReifiedTripleBlockPath
[43]   PropertyListPath   ::=   PropertyListPathNotEmpty?
[44]   PropertyListPathNotEmpty   ::=   ( VerbPath | VerbSimple ) ObjectListPath ( ';' ( ( VerbPath | VerbSimple ) ObjectListPath )? )*
[45]   VerbPath   ::=   Path
[46]   VerbSimple   ::=   Var
[47]   ObjectListPath   ::=   ObjectPath ( ',' ObjectPath )*
[48]   ObjectPath   ::=   GraphNodePath AnnotationPath
[49]   Path   ::=   PathSequence
[50]   PathSequence   ::=   PathEltOrInverse ( '/' PathEltOrInverse )*
[51]   PathEltOrInverse   ::=   PathElt | '^' PathElt
[52]   PathElt   ::=   PathPrimary
[53]   PathPrimary   ::=   iri | 'a' | '(' Path ')'
[54]   TriplesNode   ::=   Collection | BlankNodePropertyList
[55]   BlankNodePropertyList   ::=   '[' PropertyListNotEmpty ']'
[56]   TriplesNodePath   ::=   CollectionPath | BlankNodePropertyListPath
[57]   BlankNodePropertyListPath   ::=   '[' PropertyListPathNotEmpty ']'
[58]   Collection   ::=   '(' GraphNode+ ')'
[59]   CollectionPath   ::=   '(' GraphNodePath+ ')'
[60]   AnnotationPath   ::=   ( Reifier | AnnotationBlockPath )*
[61]   AnnotationBlockPath   ::=   '{|' PropertyListPathNotEmpty '|}'
[62]   Annotation   ::=   ( Reifier | AnnotationBlock )*
[63]   AnnotationBlock   ::=   '{|' PropertyListNotEmpty '|}'
[64]   GraphNode   ::=   VarOrTerm | TriplesNode | ReifiedTriple
[65]   GraphNodePath   ::=   VarOrTerm | TriplesNodePath | ReifiedTriple
[66]   VarOrTerm   ::=   Var | RDFTerm
[67]   RDFTerm   ::=   iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | NIL | TripleTerm
[68]   ReifiedTriple   ::=   '<<' ReifiedTripleSubject Verb ReifiedTripleObject Reifier? '>>'
[69]   ReifiedTripleSubject   ::=   Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple | TripleTerm
[70]   ReifiedTripleObject   ::=   Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple | TripleTerm
[71]   TripleTerm   ::=   '<<(' TripleTermSubject Verb TripleTermObject ')>>'
[72]   TripleTermSubject   ::=   Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTerm
[73]   TripleTermObject   ::=   Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTerm
[74]   TripleTermData   ::=   '<<(' TripleTermDataSubject ( iri | 'a' ) TripleTermDataObject ')>>'
[75]   TripleTermDataSubject   ::=   iri | RDFLiteral | NumericLiteral | BooleanLiteral
[76]   TripleTermDataObject   ::=   iri | RDFLiteral | NumericLiteral | BooleanLiteral | TripleTermData
[77]   VarOrIri   ::=   Var | iri
[78]   Var   ::=   VAR1 | VAR2
[79]   Expression   ::=   ConditionalOrExpression
[80]   ConditionalOrExpression   ::=   ConditionalAndExpression ( '||' ConditionalAndExpression )*
[81]   ConditionalAndExpression   ::=   ValueLogical ( '&&' ValueLogical )*
[82]   ValueLogical   ::=   RelationalExpression
[83]   RelationalExpression   ::=   NumericExpression ( '=' NumericExpression | '!=' NumericExpression | '<' NumericExpression | '>' NumericExpression | '<=' NumericExpression | '>=' NumericExpression | 'IN' ExpressionList | 'NOT' 'IN' ExpressionList )?
[84]   NumericExpression   ::=   AdditiveExpression
[85]   AdditiveExpression   ::=   MultiplicativeExpression ( '+' MultiplicativeExpression | '-' MultiplicativeExpression | ( NumericLiteralPositive | NumericLiteralNegative ) ( ( '*' UnaryExpression ) | ( '/' UnaryExpression ) )* )*
[86]   MultiplicativeExpression   ::=   UnaryExpression ( '*' UnaryExpression | '/' UnaryExpression )*
[87]   UnaryExpression   ::=     '!' PrimaryExpression
| '+' PrimaryExpression
| '-' PrimaryExpression
| PrimaryExpression
[88]   PrimaryExpression   ::=   BrackettedExpression | BuiltInCall | iriOrFunction | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprTripleTerm
[89]   ExprTripleTerm   ::=   '<<(' ExprTripleTermSubject Verb ExprTripleTermObject ')>>'
[90]   ExprTripleTermSubject   ::=   iri | RDFLiteral | NumericLiteral | BooleanLiteral | Var
[91]   ExprTripleTermObject   ::=   iri | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprTripleTerm
[92]   BrackettedExpression   ::=   '(' Expression ')'
[93]   BuiltInCall   ::=     'STR' '(' Expression ')'
| 'LANG' '(' Expression ')'
| 'LANGMATCHES' '(' Expression ',' Expression ')'
| 'LANGDIR' '(' Expression ')'
| 'DATATYPE' '(' Expression ')'
| 'IRI' '(' Expression ')'
| 'URI' '(' Expression ')'
| 'BNODE' ( '(' Expression ')' | NIL )
| 'ABS' '(' Expression ')'
| 'CEIL' '(' Expression ')'
| 'FLOOR' '(' Expression ')'
| 'ROUND' '(' Expression ')'
| 'CONCAT' ExpressionList
| 'SUBSTR' '(' Expression ',' Expression ( ',' Expression )? ')'
| 'STRLEN' '(' Expression ')'
| 'REPLACE' '(' Expression ',' Expression ',' Expression ( ',' Expression )? ')'
| 'UCASE' '(' Expression ')'
| 'LCASE' '(' Expression ')'
| 'ENCODE_FOR_URI' '(' Expression ')'
| 'CONTAINS' '(' Expression ',' Expression ')'
| 'STRSTARTS' '(' Expression ',' Expression ')'
| 'STRENDS' '(' Expression ',' Expression ')'
| 'STRBEFORE' '(' Expression ',' Expression ')'
| 'STRAFTER' '(' Expression ',' Expression ')'
| 'YEAR' '(' Expression ')'
| 'MONTH' '(' Expression ')'
| 'DAY' '(' Expression ')'
| 'HOURS' '(' Expression ')'
| 'MINUTES' '(' Expression ')'
| 'SECONDS' '(' Expression ')'
| 'TIMEZONE' '(' Expression ')'
| 'TZ' '(' Expression ')'
| 'NOW' NIL
| 'UUID' NIL
| 'STRUUID' NIL
| 'IF' '(' Expression ',' Expression ',' Expression ')'
| 'STRLANG' '(' Expression ',' Expression ')'
| 'STRLANGDIR' '(' Expression ',' Expression ',' Expression ')'
| 'STRDT' '(' Expression ',' Expression ')'
| 'sameTerm' '(' Expression ',' Expression ')'
| 'isIRI' '(' Expression ')'
| 'isURI' '(' Expression ')'
| 'isBLANK' '(' Expression ')'
| 'isLITERAL' '(' Expression ')'
| 'isNUMERIC' '(' Expression ')'
| 'hasLANG' '(' Expression ')'
| 'hasLANGDIR' '(' Expression ')'
| 'REGEX' '(' Expression ',' Expression ( ',' Expression )? ')'
| 'isTRIPLE' '(' Expression ')'
| 'TRIPLE' '(' Expression ',' Expression ',' Expression ')'
| 'SUBJECT' '(' Expression ')'
| 'PREDICATE' '(' Expression ')'
| 'OBJECT' '(' Expression ')'
[94]   iriOrFunction   ::=   iri ArgList?
[95]   RDFLiteral   ::=   String ( LANG_DIR | '^^' iri )?
[96]   NumericLiteral   ::=   NumericLiteralUnsigned | NumericLiteralPositive | NumericLiteralNegative
[97]   NumericLiteralUnsigned   ::=   INTEGER | DECIMAL | DOUBLE
[98]   NumericLiteralPositive   ::=   INTEGER_POSITIVE | DECIMAL_POSITIVE | DOUBLE_POSITIVE
[99]   NumericLiteralNegative   ::=   INTEGER_NEGATIVE | DECIMAL_NEGATIVE | DOUBLE_NEGATIVE
[100]   BooleanLiteral   ::=   'true' | 'false'
[101]   String   ::=   STRING_LITERAL1 | STRING_LITERAL2 | STRING_LITERAL_LONG1 | STRING_LITERAL_LONG2
[102]   iri   ::=   IRIREF | PrefixedName
[103]   PrefixedName   ::=   PNAME_LN | PNAME_NS
[104]   BlankNode   ::=   BLANK_NODE_LABEL | ANON

终结符产生式:

[105]   IRIREF   ::=   '<' ([^<>"{}|^`\]-[#x00-#x20] | UCHAR )* '>'
[106]   PNAME_NS   ::=   PN_PREFIX? ':'
[107]   PNAME_LN   ::=   PNAME_NS PN_LOCAL
[108]   BLANK_NODE_LABEL   ::=   '_:' ( PN_CHARS_U | [0-9] ) ((PN_CHARS|'.')* PN_CHARS)?
[109]   VAR1   ::=   '?' VARNAME
[110]   VAR2   ::=   '$' VARNAME
[111]   LANG_DIR   ::=   '@' [a-zA-Z]+ ('-' [a-zA-Z0-9]+)* ('--' [a-zA-Z]+)?
[112]   INTEGER   ::=   [0-9]+
[113]   DECIMAL   ::=   [0-9]* '.' [0-9]+
[114]   DOUBLE   ::=   ( ([0-9]+ ('.'[0-9]*)? ) | ( '.' ([0-9])+ ) ) [eE][+-]?[0-9]+
[115]   INTEGER_POSITIVE   ::=   '+' INTEGER
[116]   DECIMAL_POSITIVE   ::=   '+' DECIMAL
[117]   DOUBLE_POSITIVE   ::=   '+' DOUBLE
[118]   INTEGER_NEGATIVE   ::=   '-' INTEGER
[119]   DECIMAL_NEGATIVE   ::=   '-' DECIMAL
[120]   DOUBLE_NEGATIVE   ::=   '-' DOUBLE
[121]   STRING_LITERAL1   ::=   "'" ( ([^#x27#x5C#xA#xD]) | ECHAR | UCHAR )* "'"
[122]   STRING_LITERAL2   ::=   '"' ( ([^#x22#x5C#xA#xD]) | ECHAR | UCHAR )* '"'
[123]   STRING_LITERAL_LONG1   ::=   "'''" ( ( "'" | "''" )? ( [^'\] | ECHAR | UCHAR ) )* "'''"
[124]   STRING_LITERAL_LONG2   ::=   '"""' ( ( '"' | '""' )? ( [^"\] | ECHAR | UCHAR ) )* '"""'
[125]   ECHAR   ::=   '\' [tbnrf\"']
[126]   UCHAR   ::=   ('\u' HEX HEX HEX HEX) | ('\U' HEX HEX HEX HEX HEX HEX HEX HEX)
[127]   NIL   ::=   '(' WS* ')'
[128]   WS   ::=   #x20 | #x9 | #xD | #xA
[129]   ANON   ::=   '[' WS* ']'
[130]   PN_CHARS_BASE   ::=   [A-Z] | [a-z] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | [#x00F8-#x02FF] | [#x0370-#x037D] | [#x037F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
[131]   PN_CHARS_U   ::=   PN_CHARS_BASE | '_'
[132]   VARNAME   ::=   ( PN_CHARS_U | [0-9] ) ( PN_CHARS_U | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] )*
[133]   PN_CHARS   ::=   PN_CHARS_U | '-' | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040]
[134]   PN_PREFIX   ::=   PN_CHARS_BASE ((PN_CHARS|'.')* PN_CHARS)?
[135]   PN_LOCAL   ::=   (PN_CHARS_U | ':' | [0-9] | PLX ) ((PN_CHARS | '.' | ':' | PLX)* (PN_CHARS | ':' | PLX) )?
[136]   PLX   ::=   PERCENT | PN_LOCAL_ESC
[137]   PERCENT   ::=   '%' HEX HEX
[138]   HEX   ::=   [0-9] | [A-F] | [a-f]
[139]   PN_LOCAL_ESC   ::=   '\' ( '_' | '~' | '.' | '-' | '!' | '$' | '&' | "'" | '(' | ')' | '*' | '+' | ',' | ';' | '=' | '/' | '?' | '#' | '@' | '%' )

该语法的文本版本可在 此处获取。

7.6 选定的终结符字面 字符串

本文档使用一些特定的终结符字面字符串 [EBNF-NOTATION]。为阐明这些 终结符字面字符串所使用的 Unicode 码点, 下表描述了本节中使用的特定字符。

编码 字形 描述
U+000A LF 换行
U+000D CR 回车
U+0023 # 数字符号
U+0025 % 百分号
U+005C \ 反斜杠

A. インターネットメディアタイプと ファイル拡張子

Shape Rules Languageのインターネットメディアタイプ (以前はMIMEタイプとして知られていた)は "application/shape-rules"である。

以下の情報は、レビュー、承認、およびIANAへの登録のため、 Internet Engineering Steering Group(IESG)に提出されている。

型名:
application
サブタイプ名:
shape-rules
必須パラメータ:
なし
任意パラメータ:
version
このパラメータは任意である。 存在する場合、versionの許容値は バージョンラベルで定義される。
profile
このパラメータは任意であり、追加情報を含めるために使用される。 プロファイルの知識なしに処理される場合、リソース表現の意味論を 変更しない。profileパラメータの値は、 空でない、空白区切りURIのリストである。 詳細および背景については、[RFC6906]を参照されたい。
符号化上の考慮事項:
Shape Rules Languageの構文は、Unicode [UNICODE]のコードポイント上で表現される。 符号化は常にUTF-8 [RFC3629]である。
Unicodeコードポイントは、\uXXXX(U+0からU+FFFF)または \UXXXXXXXX構文(U+10000以降)を用いて表現してもよく、 ここでXは16進数字[0-9A-F]である
セキュリティ上の考慮事項:
附録C、セキュリティ上の考慮事項、および UTF-8, a transformation format of ISO 10646 [RFC3629]第7節、Security Considerationsを参照。
相互運用性上の考慮事項:
既知の相互運用性の問題はない。
公開仕様:
この仕様。
追加情報:
マジックナンバー:
SHACL規則ファイルは、文書の冒頭付近に文字列'PREFIX' (大文字小文字を区別しない)を持つ場合がある。
ファイル拡張子:
".srl"
基底URI:
SHACL Rulesの'BASE <IRIref>'項は、 文書内で後続して使用されるクエリ言語内の相対IRIrefに対して、 現在の基底URIを変更できる。
詳細情報の連絡先となる人およびメールアドレス:
Data Shapes Working Group <public-shacl@w3.org;
想定される用途:
COMMON
使用上の制限:
なし
著者/変更管理者:
SHACL 1.2 Rules仕様は、World Wide Web ConsortiumのData Shapes Working Groupの成果物である。W3Cは、これらの仕様に対する 変更管理を有する。

B. セキュリティ上の考慮事項

この節は非規範的である。

TODO

C. プライバシー上の考慮事項

この節は非規範的である。

TODO

D. 国際化上の 考慮事項

この節は非規範的である。

TODO

E. 謝辞

この節は非規範的である。

TODO

F. 索引

F.1 この 仕様で定義される用語

F.2 参照によって定義される用語

G. Issue概要

H. 参考文献

H.1 規範的参考文献

[EBNF-NOTATION]
EBNF Notation. Tim Bray; Jean Paoli; Michael Sperberg-McQueen; Eve Maler; François Yergeau et al. W3C. W3C勧告. URL: https://www.w3.org/TR/xml/#sec-notation
[I18N-GLOSSARY]
Internationalization Glossary. Richard Ishida; Addison Phillips. W3C. 2024年10月17日. W3C作業グループノート. URL: https://www.w3.org/TR/i18n-glossary/
[RDF12-CONCEPTS]
RDF 1.2 Concepts and Abstract Data Model. Andy Seaborne; Gregg Kellogg; Olaf Hartig; Pierre-Antoine Champin. W3C. 2026年4月7日. W3C勧告候補. URL: https://www.w3.org/TR/rdf12-concepts/
[RDF12-SEMANTICS]
RDF 1.2 Semantics. Peter Patel-Schneider; Enrico Franconi; Dörthe Arndt. W3C. 2026年4月7日. W3C勧告候補. URL: https://www.w3.org/TR/rdf12-semantics/
[RDF12-TURTLE]
RDF 1.2 Turtle. Gregg Kellogg; Andy Seaborne; Dominik Tomaszuk. W3C. 2026年6月12日. W3C作業草案. URL: https://www.w3.org/TR/rdf12-turtle/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. 1997年3月. Best Current Practice. URL: https://www.rfc-editor.org/info/rfc2119/
[RFC3629]
UTF-8, a transformation format of ISO 10646. F. Yergeau. IETF. 2003年11月. インターネット標準. URL: https://www.rfc-editor.org/info/rfc3629/
[RFC3986]
Uniform Resource Identifier (URI): Generic Syntax. T. Berners-Lee; R. Fielding; L. Masinter. IETF. 2005年1月. インターネット 標準. URL: https://www.rfc-editor.org/info/rfc3986/
[RFC3987]
Internationalized Resource Identifiers (IRIs). M. Duerst; M. Suignard. IETF. 2005年1月. Proposed Standard. URL: https://www.rfc-editor.org/info/rfc3987/
[RFC6906]
The 'profile' Link Relation Type. E. Wilde. IETF. 2013年3月. Informational. URL: https://www.rfc-editor.org/info/rfc6906/
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. 2017年5月. Best Current Practice. URL: https://www.rfc-editor.org/info/rfc8174/
[shacl12-node-expr]
SHACL 1.2 Node Expressions. Holger Knublauch; Simon Steyskal; Robert David; David Habgood. W3C. 2026年1月8日. FPWD. URL: https://www.w3.org/TR/shacl12-node-expr/
[SPARQL12-QUERY]
SPARQL 1.2 Query Language. Olaf Hartig; Andy Seaborne; Ruben Taelman; Gregory Williams; Thomas Pellissier Tanon. W3C. 2026年6月25日. W3C作業草案. URL: https://www.w3.org/TR/sparql12-query/
[UNICODE]
The Unicode Standard. Unicode Consortium. URL: https://www.unicode.org/versions/latest/