SPARQL 1.2 RL

W3C作業草案

この文書の詳細
このバージョン:
https://www.w3.org/TR/2026/WD-sparql12-rl-20260826/
最新の公開バージョン:
https://www.w3.org/TR/sparql12-rl/
最新の編集者草案:
https://w3c.github.io/data-shapes/sparql12-rl/
履歴:
https://www.w3.org/standards/history/sparql12-rl/
コミット履歴
テストスイート:
https://github.com/w3c/data-shapes/tree/gh-pages/shacl12-test-suite/tests/sparql-rl
編集者:
Robert David (Ontotext)
(KurrawongAI)
Andy Seaborne (Apacheソフトウェア 財団)
Simon Steyskal (Siemens AG)
フィードバック:
GitHub w3c/data-shapes (プルリクエスト, 新しいIssue, 未解決のIssue)

要約

この文書は、SPARQL-RL、すなわちRDF用のDatalog形式の規則言語を定義します。

SPARQL-RLは、ルールセットと基礎データとなるRDFグラフの 組み合わせから新しいRDFデータを生成することにより、推論機能を 提供します。また、SPARQLに似たテキスト構文を提供し、ルールセットが RDFグラフに対してどのように評価されるかを定義します。

文脈が明確な場合、SPARQL規則言語を単にSRLと 呼ぶことができます。

この仕様は、 Data Shapesワーキンググループによって公開されています。

この文書のステータス

この節では、この 文書の公開時点におけるステータスについて説明します。現在のW3C 出版物の一覧およびこの技術報告書の最新版は、 次の W3C標準および草案の 索引で確認できます。

この文書は、Data Shapesワーキング グループによって、 勧告 トラックを使用した作業草案として公開されました。

作業草案として公開されたことは、 次の主体によって承認されたことを意味するものではありません: W3Cおよびそのメンバー。

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

この文書は、 次の方針の下で活動するグループによって作成されました: W3C 特許 方針W3Cは、 特許 開示の公開リストを維持しています。 このリストには、グループの成果物に関連して行われた開示が掲載され、 そのページには特許を開示するための 手順も含まれています。ある特許について実際の 知識を有し、その特許に 必須クレーム が含まれていると考える個人は、次に従ってその情報を開示しなければなりません: W3C特許方針の第6節

この文書には、 2025年8月18日付W3Cプロセス文書が適用されます。

SHACL仕様

この仕様は、SHACL 1.2仕様ファミリーの一部です。これらの詳細な紹介については、SHACL 1.2の概要を 参照してください。

各仕様は次のとおりです:

作業草案:

SHACL 1.2コア
SHACLのコアを定義します
SHACL 1.2 SPARQL拡張
SHACLのSPARQL関連の拡張を定義します
SHACL 1.2ノード式
SHACLでフォーカスノードおよび値ノードを導出するために使用する式を定義します
SHACL 1.2ルール
SHACLのルールベースの推論方法を定義します
SHACL 1.2 UI
ユーザーインターフェイス生成におけるSHACLの使用方法を定義します
SHACL 1.2プロファイリング
SHACLデータを含むデータのプロファイリングにおけるSHACLの使用方法を定義します

ワーキンググループノート草案:

SHACL 1.2の概要
一連のSHACL仕様の概要を示します
SHACL 1.2コンパクト構文
SHACLの概念を表現するためのRDF構文を定義します
注記

実装者は、上記の仕様への適合度を部分的に確認できます。そのためには、 次の SHACL 1.2テストスイートのテストケースに合格する必要があります。 ただし、テストスイートのすべてのテストに合格しても、 仕様への完全な適合を意味するものではないことに注意してください。 これは、実装がテストスイートによってテストされた側面に適合していることのみを意味します。

1. はじめに

この文書では、SPARQL-RLを紹介します。これは、宣言的ルールを通じて 既存のRDFデータから新しいRDFトリプルを導出するための仕組みです。 この文書では、ルールベースの推論の構文および意味論を定義します。

SPARQL-RLの実装は、2つの操作を提供します。 infer操作は、指定された ベースグラフにルールを適用し、ルールの実行によって導出された RDFトリプルを含む推論グラフを生成します。 推論グラフとベースグラフの結合は任意であり、 ユーザーに委ねられます。query操作は、指定された 目標パターンをルールを使用してベースグラフから導出できるかどうかを判定します。

SPARQL-RLでは、空白ノードを含む新しいRDF項を ルールのヘッドにあるトリプルテンプレートで使用できます。

SPARQL-RLは失敗による否定もサポートしますが、これはルールが 実行される順序に応じて異なる推論グラフを生成する可能性があります。 これを回避するため、ルールは単一の暗黙的な 順序をルール間に確立する層別化という手法を使用して評価され、 常に同じ推論グラフが 生成されることを保証します。

1.1 用語

次の他の仕様では、この文書で使用される 基本的な用語を定めています:

1.2 文書の表記規則

この文書のRDFデータの例では、 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/sparql-rl#
xsd: http://www.w3.org/2001/XMLSchema#
sparql: http://www.w3.org/ns/sparql#
ex: http://example/

文書全体を通じて、Turtle形式のRDFグラフを含む色分けされた ボックスが表示されます。これらのTurtle文書の断片では、上記の接頭辞 バインディングを使用します。

# このボックスはルールを表します
# このボックスは入力データを表します
# このボックスは推論データを表します

2. 適合性

非規範的と明示された節に加え、この仕様に含まれるすべての作成ガイドライン、図、例、および注記は 非規範的です。この仕様のその他のすべての内容は規範的です。

この文書のキーワードMAYMUSTMUST NOT、およびSHOULDは、 ここに示すように、すべて 大文字で表記される場合に限り、 BCP 14 [RFC2119] [RFC8174] に記載されているとおりに 解釈されるものとします。

この仕様では、次の適合基準を定義します:

適合するSRL文書とは、 RDF 文字列であり、 RuleSet 生成規則から始まる 文法に適合するものとして、 7. SPARQL-RL文法で定義されています。

注記

この仕様では、SPARQL-RL プロセッサーが、非適合のルールセットをどのように処理するかを定義しない。

3. SPARQL-RL

この節は非規範的です。

SPARQL-RLは、ベースグラフルールセットを指定すると、新しいトリプルを推論します。 評価の出力は、ベースグラフには現れない導出された トリプルを含む推論グラフです。

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

ルールは、それ以上トリプルが推論されなくなるまで実行され、 新しい推論済みトリプルが利用可能になると、ルールが複数回 実行される場合があります。

SPARQL-RLの実行は、ルールの実行順序が、 新しい空白ノードを含む新しいRDF項の作成時にも、 パターンの不在をテストする場合にも、異なる結果を生じさせないように定義されています。 つまり、ルールの実行順序に 関係なく、同じ推論グラフが生成されます。

SPARQL-RLには、SPARQL 1.2クエリ言語に着想を得た、人間にとって扱いやすい構文があります。 ルールセットの評価にはSPARQLと類似する要素がありますが、 ルールの実行順序に関係なく同じ推論グラフが生成されることを 保証するため、細部が異なります。

3.1 基本パターン

この節の例では、ソフトウェアコンポーネントと その依存関係について説明します。フロントエンドがアプリケーションサーバーを呼び出し、 アプリケーションサーバーは既知の脆弱性を持つ データベースに問い合わせます。

この最初の例には、次のデータグラフとルールセットがあります:

上記のルールをデータに適用すると、依存関係の種類にかかわらず、 :frontend:appに依存し、:app:dbに依存すると結論付けられます。

次に、他のルールによって生成された:dependsOnトリプルに依存するルールを 追加することで、:exposedTo関係を導出できます(下記の4.3 ルールの依存関係も参照してください):

3.2 再帰

前節の:exposedToルールが到達するのは直接的な 依存関係のみです。:frontend:dbに直接依存していないため、 :frontendについて:exposedToトリプルは推論されません。 任意の長さの依存関係チェーンに沿って危険への露出を伝播させるため、そのルールを 2つのルールに置き換えます。コンポーネントは自身が持つ 脆弱性にさらされ、さらに直接の依存先がさらされている あらゆる脆弱性にもさらされます:

前の例と比較すると、ここでは :db :exposedTo :vuln1(データベースは自身の 脆弱性にさらされています)と、:frontend :exposedTo :vuln1が追加されます。 チェーンの長さにかかわらず、依存関係の チェーンを通じて危険への露出が:frontendまで到達します。

この最後のルールは再帰的ルールです。ルールのボディが そのルールのヘッドに依存しています。

3.3 フィルタリング

ルールのボディで式を使用して、ボディの照合時に 変数の値を制限できます。 たとえば、各脆弱性の重大度が指定されている場合、 重大な脆弱性にさらされているコンポーネントに ステータスを付与できます:

FILTERは式を評価し、その式がtrueと評価された場合は現在の 変数バインディングの集合を保持し、式がfalseと評価された場合は 現在の変数バインディングの集合を破棄します。 これは、 SPARQLのFILTER演算 と同じであり、SPARQL-RLはSPARQLと同じ関数および演算子の多くを提供します。

3.4 否定

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

否定要素を評価するため、ルール評価アルゴリズムは、 否定要素内のパターンに一致するトリプルを生成できるすべてのルールが 完了していることを保証します。これは 層別化と呼ばれ、否定が データに由来するか、否定要素内で完了したものかを問わず、 関連するすべての可能なトリプルに基づくことを保証します。否定を含むルールは、これらのトリプルを 生成するルールに_依存する_といいます(下記の4.3 ルールの依存関係を参照してください)。

3.5 代入およびRDF 項の作成

代入を使用すると、ルールのボディ内で式の結果を変数に 代入できます。これを使用して、データに基づく 新しいRDF項を作成できます。

空白ノードはルールヘッドで使用でき、ルール評価によってトリプルが生成される たびに、それぞれ新しい空白ノードが生成されます。

代入を含むルール、および ルールヘッド内に空白ノードを作成するルールは、1回実行ルールです。 このようなルールは、依存するデータを生成できるすべてのルールの後に実行され、 それらが生成するデータに依存するすべてのルールより前に実行されます。 ルールヘッド内に空白ノードを含むルールも、新しい RDF項を作成するため、1回実行ルールです。

この条件により、そのようなルールが自身にループバックして、無制限の数の RDF項を生成することを防ぎます。

代入内の式を評価した結果エラーが発生した場合、 現在の解マッピングは代入によって拒否されます。

3.6 ルールセットのインポート

SPARQL-QLのルールセットは、他のルールセットのURLを そのルールセットのルールセットインポートに含めることで、他のルールセットを組み込めます。 これにより、ルールセット間で共有されるライブラリとしてルールを構造化できます。

ルールセットのIMPORTS文は、そのルールセット内のルールが 評価される前に処理されます。インポート手順中に、インポートされたルールセットが 独自のインポートを持つ場合、それらも再帰的に処理されます。 ルールセットの処理中にIMPORTS文をたどると、 循環インポートが発生する可能性があります。ルールセットは1回だけインポートされます。 インポート文のグラフ内の循環によって無限ループが生じることはありません。

ルールセットのインポートのサポートは、SRLプロセッサーでは任意です。 詳細については、4.5 インポートの 処理を参照してください。

3.7 データブロック

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

たとえば、ルールセットには、データから導出する代わりに、 既知の事実を直接表明して含めることができます:

注記

データブロックは、空のボディを持つルールと同等です。 そのトリプルは、いかなるルールも 評価されることなく推論グラフの一部になります。

3.8 ルールセットの評価

ルールはルールセットにまとめられます。 ルールセットとデータグラフ(ベースグラフ)が評価への入力です。 出力は、推論グラフと呼ばれるグラフであり、 データグラフには現れないトリプルの集合です。

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

評価は、ルール自体を評価する前に ルールセットを準備するための 2つの手順から始まります:

  1. サポートされている場合、入力ルールセットのインポートを解決して、 インポートされたすべてのルールセットのすべてのルールを含む ルールセットを形成します。 いずれかのインポートがプロセッサーに受け入れられない場合、プロセッサーはエラーを通知しなければなりません4.5 インポートの処理)。
  2. 層別化が計算されます(4.4.2 層別化 アルゴリズム これにより、否定要素および代入要素は、一貫性があり 予測可能な結果を生成します。層別化には、ルール間の 依存関係を 調べることが含まれます (4.3.1 依存関係 グラフ)。

ルールセットの準備が完了すると、評価は 層別化の各層を順番に取得し、 その層内のルールを完了するまで評価してから、 次の層に移ることで進行します。

3.9 グラウンドデータの照合

グラウンドデータとは、ベースグラフ内のトリプルです。 ルールセットの評価中には、推論された トリプルではなく、元のトリプルのみに対してパターン照合を行う 必要がある場合があります。

この一例は、デフォルト値の設定です。 ルールは、ベースグラフに値がすでに含まれているかどうかをテストし、含まれていない場合は、 デフォルト値を計算できます。

NOT DATAを使用すると、ルールボディの他の部分が推論済みトリプルと照合できます。 また、すべてのルールボディの照合をベースグラフに対して行うこともできます。そのためには、 WHERE DATAを使用します。 このようなルールは、ベースグラフからの照合のみに依存します。

4. SPARQL-RL抽象構文

SPARQL-RL抽象構文は、SPARQL-RLの論理構造です。 これは、SPARQL-RLの実行アルゴリズムを定義するために使用されます。

4.1 抽象構文の 要素

変数
変数は、トリプルパターン内の可能なRDF 項を表します。 変数はでも使用されます。
は、関数または関数形式です。 引数はRDF項です。 式は解マッピングに関して評価され、その結果として RDF項を返します。 は、 SPARQL式 および SHACLリストパラメーター関数と互換性があります。
データブロック
データブロックは、トリプルの集合です。 これらのトリプルは追加の事実として推論グラフに追加され、 推論処理に含まれます。
トリプルテンプレート
トリプルテンプレートは、各要素が 変数またはRDF 項トリプル項の場合もあります)のいずれかである3タプルです。 タプルの第2要素は、IRIまたは変数でなければなりません。 トリプルテンプレートは、ルールヘッドに現れます。
トリプルパターン
トリプルパターンは、各要素が 変数またはRDF 項(トリプル項の場合もあります)のいずれかである3タプルです。 タプルの第2要素は、IRIまたは変数でなければなりません。
フィルター要素
フィルター要素は、であり、 ルール要素として現れます。 これは、パターン照合における 変数の値を制限するために使用されます。
トリプルパターン要素
トリプルパターン要素は、 トリプルパターンであり、 ルール要素として現れます。
否定要素
否定要素は、 ルール要素です。 これには、トリプルパターン要素および フィルター要素のシーケンスで構成される 否定要素ボディがあります。
代入要素
代入要素は、 ルール要素であり、 代入変数と呼ばれる 変数と、 代入式と呼ばれる からなるペアです。
ルール要素
ルール要素は、 トリプルパターン要素フィルター要素否定要素、または 代入要素のいずれかです。
ルールヘッド
ルールヘッドは、トリプル テンプレートのシーケンスです。
ルールボディ
ルールボディは、ルール要素のシーケンスです。 すなわち、各シーケンス要素は、 トリプルパターン要素フィルター要素否定要素、 または代入要素のいずれかです。
ルールセットインポート
ルールセットインポート(多くの場合、単に「インポート」)は、評価中に 組み込まれる他のルールセットの URLの集合です。
ルール
ルールは、ルールヘッド(多くの場合、単に 「ヘッド」)と ルールボディ(多くの場合、単に「ボディ」)のペアです。 ルールには、それを識別しやすくするためにURIを指定できます。
1回実行ルール
1回実行ルールは、ルールセットの評価中の 特定の時点で正確に1回実行されるルールです。
一般ルール
一般ルールは、1回実行ルールではないルールです。 一般ルールは、ルールセットの評価中に複数回実行される場合があります。
ルールセット
ルールセットは、0個以上のルールの集合、 0個以上のデータブロックの集合、 および0個以上のルールセットインポートの集合です。 解決済み ルールセットは、インポートを持たないルールセット です。 解決済みルールセットは、別のルールセットインポート処理を適用することで作成されます。
ベースグラフ
ベースグラフは、評価処理への入力として指定される RDF グラフです。
推論 グラフ
推論グラフは、 RDF グラフであり、 ルールセット評価によって生成されます。 これには、ルールセットベースグラフに適用することによって推論された、 ベースグラフには 存在しないすべての推論済みトリプルが含まれます。
ルールセット 評価
ルールセット評価は、 ルールセットベースグラフに適用して、 推論 グラフを生成する処理です。 ルール 評価は、ルールを1回評価する処理です。 ルールを評価すると、ルールボディの評価に基づいて、 ルールヘッドによって指定されるすべてのトリプルが生成されます。 これは、トリプルがベースグラフ内にあるか、 ルールセット評価中にすでに推論されているか、 または新しい推論済みトリプルであるかにかかわりません。 ルールセット評価中に、ルールが複数回評価される場合が あります。

SPARQL-RLは、inferおよびqueryという2つの操作を提供します。

推論
推論は、指定された ベースグラフルールセットを適用し、推論された トリプルを含む推論グラフを生成する操作である。これは完全なルールセット評価を適用する。
クエリ

クエリは、指定されたゴール パターンを、ベースグラフからルールセットを使用して導出できるかどうかを判定する操作である。 すべてのルールを評価するとは限らず、代わりに、クエリのゴールに回答するために 必要なルールのみを評価してもよい。

クエリは、推論操作を実行し、 続いて、ゴールパターンを結合された ベースグラフおよび推論 グラフに照合することと等価である。

SPARQL-RL プロセッサー
SPARQL-RL プロセッサーは、 SPARQL-RL 仕様を実装し、ルールセットを評価でき、推論およびクエリの操作の一方または両方を提供するシステムである。

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

注記

ルール要素のシーケンスの要素には、 1 から始まるラベルが付けられる。

ルールセットおよびルールの各種コンポーネントには、次の表記を使用する。

コンポーネント表記
コンポーネント 用途
ruleset.rules ルールセットのルール。
ruleset.data ルールセット内のデータブロックの和集合によって 形成されるRDF グラフ
ruleset.imports ルールセットインポートの集合。
rule.head ルールヘッドトリプルテンプレート
rule.body ルールルール要素
rule.data ブールフラグ。falseの場合、ルール本体ベースグラフに対して照合される。
rule.id ルールの識別子。これは空白ノードまたはIRIである。
filter.expr フィルター 要素
assign.var [代入要素]の代入変数
assign.expr 代入式
negation.inner 否定要素本体否定要素である。
negation.data ブールフラグ。falseの場合、negation.innerベースグラフに対して照合される。

4.2 整形式性条件

整形式性とは、 ルールセットの抽象構文に対する一連の条件です。これらの条件は総合的に、 ルールのヘッド内の 変数が、そのルールの ボディ内で定義された値を持つこと、 フィルター要素 または代入式内の各変数が、 評価時点で値を持つこと、 およびルール内の各 代入が、ルールボディ内でそれ以前に使用されていない 新しい変数を導入することを保証します。

初期変数集合が指定されたルール要素の シーケンスについて、整形式性を定義します。

eltiを、ルール要素のシーケンスのi番目の要素とします。

varsiを、 eltiによって定義される変数の集合とします。ここで:

V0を、シーケンスの初期変数とします。

Viを、 V0と、i未満のjについての すべてのvarsjとの和集合とします。

VallVNとします。 ここで、Nはシーケンスの長さです。

整形式 シーケンスとは、変数集合V0が指定された ルール要素のシーケンスであり、 次の条件を 満たすものです:

ルールは、 ルールボディのシーケンスが、空集合である V0を指定された 整形式シーケンスであり、 ルールヘッドトリプルテンプレート内の各変数が Vallの要素である場合、整形式 ルールです。

ルールセットは、そのルールセットのすべてのルールが 整形式ルールである場合に限り、 整形式ルールセットです。

4.3 ルールの依存関係

第2のルールの出力が第1のルールのボディの評価に影響する場合、 ルールR1はルールR2に依存します。すなわち、R2のヘッドには、 R1のボディ内のトリプルパターンと一致するトリプルを生成する可能性がある トリプルテンプレートがあります。 これは、トリプルパターン要素として、または 否定要素の内部にあります。

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

この最初の例では、第1のルールは 第2のルールに対して開放依存関係を持ちます。

この第2の例では、第1のルールは第2のルールに対して閉鎖依存関係を持ちます。 トリプルパターン?x :status :criticallyExposedは、 第1のルールの否定要素内に現れ、 第2のルールのヘッド内のトリプルテンプレートと一致します。 第1のルールは、第2のルールが可能なすべての出力を 生成するまで評価できません。

トリプル パターン照合

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

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

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

トリプルパターンルールに依存する のは、トリプルパターンが、ルールのトリプルテンプレートのいずれかに依存している 場合であり、それらのトリプルテンプレートはルールのヘッド内にある。

ルールの依存関係

R1のボディ内のいずれかの トリプルパターンが、 トリプルパターン要素として、または 否定要素の内部にあるかにかかわらず、 R2のヘッド内の トリプルテンプレート依存する場合、 ルールR1はルールR2依存します

閉鎖依存関係

ルールR1のルールR2に対する ルールの依存関係は、 次のいずれかの条件を満たす場合、 閉鎖依存関係です:

開放依存関係

ルールR1のルールR2に対する ルールの依存関係は、その依存関係が 閉鎖依存関係でない場合、 開放依存関係です。 すなわち、R2に依存するR1トリプルパターンは、すべて トリプルパターン要素としてのみ現れます。

トリプルテンプレートは、テンプレート内の変数を値で置き換えることで、 T2T1等しくなるようなトリプル T2 が得られる、 トリプルテンプレートの変数の値が存在する場合に、 RDFトリプル T1生成できる

同様に、トリプルパターンは、パターン内の変数を値で置き換えることで、 T2T1等しくなるようなトリプル T2 が得られる、 トリプルパターンの変数の値が存在する場合に、トリプル T1一致するトリプルパターンの場合、これには 対称トリプルが含まれる。

変数がトリプル テンプレート またはトリプルパターンで複数回使用されている場合、置換には同じRDF項 が使用される。

変数をRDF項で置き換える際には、 トリプル項内の変数も対象に含まれる。

4.3.1 依存関係グラフ

ルール間の依存関係は、有向グラフとして表され、 依存関係グラフと呼ばれます。 グラフの頂点はルールセットのルールであり、辺には、 依存関係が開放依存関係であるか 閉鎖依存関係であるかに応じて、 openまたはclosedのラベルが付けられます。

依存関係グラフ
ルールセット依存関係グラフは、 各頂点がルールセット内のルールである有向グラフです。 R1R2に依存する場合、ルールR1から ルールR2への辺が存在します。 その依存関係が開放依存関係であるか 閉鎖依存関係であるかに応じて、 辺にはopenまたはclosedのラベルが付けられます。
推移的ルール依存関係
依存関係グラフ内に R1からR2への経路が存在する場合、 ルールR1はルールR2に対して 推移的依存関係を持ちます。
再帰的ルール依存関係

依存関係グラフ内に Rを含む循環経路が存在する場合、ルールR再帰的依存関係を持ちます。

注記

依存関係グラフは、データグラフの影響を受けません。

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

次のアルゴリズムは、 ルールセットから 依存関係 グラフを構築するために使用できる 1つの方法を示します。適合性は、依存関係グラフの定義を 満たす依存関係グラフを生成することに依存し、 この手順を使用することには依存しません。

define mergeLabel(oldLabel, newLabel):
    ## 閉鎖依存関係は開放依存関係を上書きします。
    if oldLabel == "open" and newLabel == "open":
        return "open"
    else:
        return "closed"
    endif
enddefine

## 出力 -- ルールの頂点およびラベル付き辺を持つ依存関係グラフ。
define buildDependencyGraph(ruleSet):
    ## edgeLabelMapは(R1, R2)を"open"または"closed"に対応付けます
    let edgeLabelMap be a map from pair (rule, rule) to label

    foreach rule R1 in ruleSet.rules:
        ## ルール内の各トリプルパターンTPを、"open"または"closed"を必要とするものとして分類します
        ## 否定要素内にあるかどうかによって分類します。
        let bodyDependencies = {}
        foreach rule element RBE in R1.body:
            if RBE is a negation element:
                foreach triple pattern TP in RBE.inner
                    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:
                ## 何もしません
            else if RBE is an assignment element:
                ## 何もしません
            endif
        endfor

        foreach pair (triple pattern TP, depLabel) in bodyDependencies:
            if R1.body has an assignment element:
              set depLabel to "closed"
            endif
            if R1.head has a triple template with a blank node:
              set depLabel to "closed"
            endif
            ## このトリプルパターン要素または否定要素の依存関係を検索します。
            foreach rule R2 in ruleSet.rules:
                foreach triple template TT in R2.head:
                    if triple pattern TP matches triple template TT:
                        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 an edge (R1 -> R2) labeled with label to DP
    endfor

    the result is DP
    enddefine

4.4 層別化

層別化は、 ルールセットを、 層別化レイヤー(「strata」、単数形は 「stratum」とも呼ばれます)の順序付きシーケンスに分割する処理です。より低い のルールは、 より高いのルールより前に評価されます。

層別化は、 否定要素代入 要素、および ルールヘッド内で作成される空白ノードが、 より前の(低い)および ベースグラフを使用して計算された結果のみに依存することを保証するため、 ルール間の依存関係に制約を課します。 これにより、指定されたベースグラフに対する ルールセットの評価から、 単一で明確に定義された有限の結果が得られることを保証します。

注記

層別化処理は、他の評価上の判断を行うためにも 使用できます。この文書では、一貫した評価に必要な 条件を説明し、層別化を形成するために使用できる 1つの方法を示します。互換性のある動作を得るため、実装は ここで説明する条件を満たす必要がありますが、提示された アルゴリズムを実装する必要はありません。

層別化レイヤー

層別化レイヤーSLは、 互いに素な2つのルール集合 (SL.onceSL.general)のペアです。 SL.onceには、 1回実行ルールが含まれます。これは、 代入要素を使用するか、 ルールヘッド内に空白ノードを 生成するルールです。これらのルールはそれぞれ、 層別化レイヤーの評価開始時に正確に1回 評価されます。 SL.generalには残りのルールが含まれ、それらは 新しいトリプルが推論されなくなるまで繰り返し評価されます。

層別化
ルールセット層別化は、 層別化レイヤーのシーケンスです。 ルールセット内の各ルールは、 いずれかの層別化レイヤーのいずれか1つの集合に正確に1回現れます。

4.4.1 層別化条件

層別化は、次の 条件が 満たされる場合にのみ定義されます。ルールセットがこの条件を満たさない場合、この 仕様では、そのようなルールセットの 評価結果を定義しません。

層別化条件
層別化条件では、 ルールセット依存関係グラフ内に、 閉鎖依存関係を含む 再帰的依存関係が 存在しないことが 要求されます。

言い換えると、依存関係グラフの推移的依存関係の循環には、 NOTまたは1回実行ルール(代入、あるいは空白ノードを含むルールの トリプルテンプレート)が 存在しません。

4.4.2 層別化アルゴリズム

次のアルゴリズムは、ルールセットのみに基づく 層別化の1つの方法を示します。

## 出力 -- マップ:整数 -> ルールの集合。

define stratification(ruleSet):

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

    ## 依存関係グラフは層別化条件を満たす必要があります。
    ## 無制限の層別化の検査は、層別化条件への違反による 
    ## 問題を防ぐための保護手段です。
    let limit = num rules + 1
    let maxStratum = 0

    ## stratumMapを初期化します
    foreach rule in ruleSet.rules:
        stratumMap.set(rule, 0)
        endfor

    boolean changed = true;
    while changed:
        changed = false;
        foreach edge E in DP:
            ## ラベルを持つpRuleからqRuleへの辺
            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 )
                        ## 層別化要件への違反
                        error "Stratification error"
                        endif
                    stratumMap.set(pRule, xStratum)
                    maxStratum = max(maxStratum, xStratum)
                    changed = true;
                endif
            endif
        endfor
    endwhile

    ## 結果マップを初期化します。
    let stratumRules be a map from integer to rules.
    for i = 0 to maxStratum
        stratumRules.set(i, {})
    endfor

    ## stratumMap内の同じレベル番号を持つルールを収集します
    for rule R in map stratumMap:
        let stratumNum = stratumMap.get(R)
        add R to stratumRules.get(stratumNum)
    endfor

    ## 各レベルをonceと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
注記

層別化条件の結果として、 1回実行ルールが一度 評価されると、 ルールの結果を決定するために使用されたデータは、その後の 評価中に変更されません。

完全なルールセットに対する依存関係分析および 層別化の段階的な適用から評価に至るまでの手順については、 6.6 具体 例に示します。

4.5 インポートの処理

Webから文書を読み取ることには、セキュリティ上の影響があります。 ルールセットのインポートのサポートは、SRLプロセッサーでは任意です。 さらに、実装は、一部のルールセットのインポートのみをサポートし、 その他をサポートしないなど、部分的なサポートを提供してもよく、 検証済みのコピーからインポートする場合もあります。

インポート処理には、次の条件が適用されます:

解決済みルールセットは、別のルールセットの インポートで言及されたすべてのルールセットを 再帰的に読み取ることによって、その別のルールセットから生成されます。

アルゴリズムの例については、A. インポートアルゴリズムの例を参照してください。

5. SPARQL-RLと SPARQLの関係

この節は非規範的です。

SRLとSPARQLには密接な関係があります。SRLはSPARQLと互換性を持つように設計されており、 SRLの構文要素の多くはSPARQLのパターン照合から取り入れられたか、 それに着想を得ています。ただし、いくつかの相違点があります。

SRLでは、RULE変数は、FILTERおよびSETの 式で使用される場合も、 ルールヘッドトリプルテンプレートで使用される場合も、 使用前に常にバインドされます。SPARQLのCONSTRUCTクエリおよび INSERT更新では、変数がCONSTRUCTまたは INSERTテンプレート内に現れても、WHERE節で値を与えられていない場合、 部分的な結果が生成されます。

その他の相違点には、次のものがあります:

6. ルールセット評価

この節では、指定されたデータに対してルールセットを評価した結果を定義します。 実装方法としてこのアルゴリズムを規定するものではありません。 実装は、同じ結果を生成する任意のアルゴリズムを使用できます。

Inputs: data graph G, called the base graph, and a rule set RS.
Output: an RDF graph GI of inferred triples

推論済みトリプルには、 ベースグラフのトリプル集合に存在するトリプルは含まれません。

6.1 評価の定義

解マッピング
解マッピングμは、部分 関数 μ : VTです。 ここで、Vはすべての変数の集合であり、 TはすべてのRDF 項の集合です。 μの定義域は dom(μ)で表され、これは μが定義されているVの部分集合です。 解マッピングを意味することが明らかな場合は、 という用語を使用します。 dom(μ0)が空集合となる 解マッピングをμ0と表します。
置換関数
置換関数、または単に置換とは、 関数 subst(μ, トリプルパターン) であり、トリプルパターンを返します。 返されるトリプルパターンでは、 dom(μ)内にある変数の トリプルパターン内の各出現箇所が、 varに対する 解マッピングによって指定された RDF項に置き換えられます。 結果のトリプルパターンに変数がない場合、それは RDFトリプルです。
評価 グラフ
評価グラフは、RDF グラフであり、ベースグラフ と、ルールセットの評価中に生成されたすべてのトリプルを結合したものである。
グラフ照合
グラフ照合は、トリプルパターンを RDF グラフ内のトリプルに対応付ける方法を見つけます。

GRDFグラフTPトリプルパターンとします。 関数graphMatch(G, TP)は、トリプルパターンに 適用すると、評価グラフ内にあるトリプルを生成する、 可能なすべてのの集合を返します。

GRDFグラフTPトリプルパターンVTP内に現れる変数の集合とします。

graphMatch(G, TP) = { μ | dom(μ) = V and subst(μ, TP) is a triple in G }
解の互換性
2つの解S1およびS2は、共通する変数について一致する場合、 互換性があります

S1およびS2を解とします。

compatible1, μ2) = true
                      if forall v in dom1) intersection dom2)
                          μ1(v) = μ2(v)
compatible1, μ2) = false otherwise
解 シーケンス
解シーケンスは、解の多重集合です。 シーケンスには定義された順序がありません。 これは順序なしリストと同等であり、重複を含めることができます。
解のマージ
2つの解に互換性がある場合、それらの解のマージとは、 各解の変数を、いずれかの解から得られた 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) }
注記

merge(S1, S2)の定義域はdomain(S1) ∪︀ domain(S2)です。

2つの解に共通する変数がない場合、それらには互換性があり、 2つの解のマージはS1S2の和集合です。

実効ブール値
関数EBV(x)は、 RDF項の実効ブール値を返します。

6.2 評価の準備

ルールセットの評価では、インポートされたすべてのルールセットを収集し、 4.5 インポートの 処理で説明されているように、単一の結合されたルールセットを構築する。

次に、以下の手順によって、結合されたルールセットを 評価用に準備する。

  1. 4.2 適格性 条件で説明されているように、各ルールが適格なルールであることを確認する。
  2. 4.3.2 依存関係グラフアルゴリズムで説明されているように、 依存関係グラフを計算する。
  3. 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

6.4 規則の評価

ルールは、ルール本体から 解 シーケンスを計算し、その後、解シーケンスの各 解マッピングを使用して、 ルールヘッドを使用してトリプルを生成することによって評価されます。

トリプルパターン内の空白ノードは、変数のように動作します。 これは、 SPARQL グラフパターンマッチングと互換性があります。

# Evaluate rule body
# This function returns a sequence of solutions

define evalRuleElements(B, SEQ, G, GD):
    where 
        B is a sequence of rule elements
        SEQ is a solution sequence 
        G and GD are RDF graphs

    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 F:
            SEQ1 = {}
            for each solution μ in SEQ:
                let x = evalFunction(F.expr, μ)
                if EBV(x) is true:
                    add μ to SEQ1
                endif
            endfor
        endif

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

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

        SEQ = SEQ1
    endfor

    return SEQ
enddefine

define evalRule(R, G, GD):
    where 
        R is a well-formed rule
        G and GD are RDF graphs
    let B be R.body 
        where each blank node in a triple pattern in R.body
        is replaced by a variable which is not used in the rule. 
        The same variable is used for each occurrence of the
        same blank node, and a different variable is used for 
       each different blank node.

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

    if R.data:
        let SEQ = evalRuleElements(B, SEQ0, GD, GD)
    else
        let SEQ = evalRuleElements(B, SEQ0, G, GD)
    
    # Evaluate rule head
    let OUT = empty set
    for each μ in SEQ:
        let S = {}
        for each triple template TT in R.head:
            let triple = subst(μ, TT)
            Add triple to S
        endfor
        OUT = OUT union S
    endfor
    return OUT
enddefine
注記

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 }

let GD = G0 ∪︀ D

# Evaluation graph.
let GE = GD

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

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

6.6 実例

このセクションは非規範的です。

このセクションでは、完全な ルールセットの評価を順を追って説明する。すなわち、ルールの依存関係を決定し (4.3 ルールの 依存関係)、 階層化を計算し (4.4 階層化)、 各階層を順番に評価して 推論グラフを生成する (6.5 ルールセットの 評価)。

この例では、ソフトウェアコンポーネントとその依存関係について説明する。 フロントエンドはアプリケーションサーバーに依存し、そのアプリケーションサーバーは データベースとロギングライブラリに依存する。データベースには既知の 脆弱性がある。ルールは、依存関係の連鎖に沿って脆弱性への 露出を伝播させ、深刻な脆弱性に露出しているコンポーネントに :criticallyExposedというステータスを付与し、重大ではないコンポーネントに :safeToDeployというステータスを付与し、重大な脆弱性に露出している 各コンポーネントに対する通知を作成する。 (実際には、脆弱性がコンポーネントに影響するかどうかは 配備されたバージョンに依存するが、この例ではバージョンを省略し、 脆弱性を直接記述している。) 簡潔にするため、基底グラフでは、より具体的な関係から導出するのではなく、 :dependsOnトリプルを直接記述している。これは、 3.1 基本パターンとは異なる。

ルールには、コメント内でR1からR5までのラベルが付けられており、 このセクションの残りの部分では、これらのラベルを使用して参照する。 これらは、 3.2 再帰から 3.5 代入 とRDF用語の作成までで導入されたルールである。 このルールセットにはIMPORTSがないため、インポート処理を行っても 変更されず、DATAブロックもないため、評価は 基底グラフのみから開始される。

6.6.1 依存関係の 特定

各規則本体内の各トリプルパターンを、 すべての規則ヘッド内のトリプルテンプレートと比較して、どの規則が どの規則に依存するかを特定します (4.3 規則の 依存関係)。

  • R1 の本体は、単一のトリプルパターン ?x :hasVulnerability ?v です。述語 :hasVulnerability を持つ トリプルを生成できるトリプルテンプレートを持つ規則ヘッドはないため、 このパターンはデータとのみ一致できます。 R1 には依存関係がありません。
  • R2 の本体には2つのトリプルパターンがあります。 ?x :dependsOn ?y はどの規則ヘッドとも一致できないため、 データとのみ一致します。?y :exposedTo ?vR1 のヘッドテンプレート ?x :exposedTo ?v と一致し、R2 自身のヘッドとも一致します。 どちらの出現箇所もトリプルパターン要素です (これらは否定要素内には現れず、 R2 の 本体には代入要素がなく、ヘッドにも空白ノードが ありません)。したがって、 R2R1 に対してオープン依存関係を持ち、 自身に対してもオープン依存関係を持ちます。 R2 の自身に対する依存関係により、R2 は再帰的な規則になります。
  • R3 の本体では、パターン ?x :exposedTo ?vR1R2 のヘッドに一致するため、R3 はそれぞれに対してオープン 依存関係を持ちます。パターン ?v :severity ?s はどの 規則ヘッドとも一致しません。
  • R4 の本体では、パターン ?x rdf:type :Component は どの規則ヘッドとも一致しません。述語 rdf:type を持つ唯一のヘッドテンプレートは R5 にありますが、その目的語 :Notification:Component とは異なる RDF 用語であるため、生成された トリプルが一致することはありません。 パターン ?x :status :criticallyExposed は、 否定要素 NOT { ?x :status :criticallyExposed } 内に現れ、 R3 のヘッドテンプレートと一致します。このパターンは 否定要素内に現れるため、R4R3 に対してクローズド 依存関係を持ちます。
  • R5 の本体では、パターン ?x :status :criticallyExposedR3 のヘッドと一致します。R5 のヘッドには 空白ノードが含まれるため、パターンが通常の トリプルパターン要素であっても、R3 に対する依存関係はクローズド 依存関係になります。 どの規則本体内のパターンも R5 のヘッドテンプレートとは 一致しないため、R5 に依存する規則はありません。

したがって、依存関係グラフには5つの頂点と6つの 辺があります。

  • R2 → R1(オープン)
  • R2 → R2(オープン)
  • R3 → R1(オープン)
  • R3 → R2(オープン)
  • R4 → R3(クローズド)
  • R5 → R3(クローズド)

R4R5R1 または R2 に直接依存していませんが、それぞれが R3 を介して、両方に対する推移的依存関係を持ちます。

実例の規則セットの依存関係グラフ R1、R2、R3、R4、R5 とラベル付けされた5つの頂点。 破線の矢印はオープン依存関係を示します。R2 から R1、 R2 から自身、R3 から R1、および R3 から R2 への依存関係です。 実線の矢印はクローズド依存関係を示します。R4 から R3 および R5 から R3 への依存関係です。 R2 R1 R3 R4 R5 オープン依存関係 クローズド依存関係
1 実例の規則セットの依存関係グラフ。 オープン依存関係は破線の矢印で、クローズド 依存関係は実線の矢印で描画されます。各辺は、一致するトリプルパターンを 本体に含む規則から、一致するトリプルを生成できる ヘッドを持つ規則を指します。 規則は、階層 0 を上部に、より上位の 階層を下部に配置し、評価順序と一致させています。

グラフ内の唯一の循環は自己辺 R2 → R2 であり、 これはオープン依存関係です。クローズド 依存関係を含む循環はないため、階層化条件が 満たされ、 規則セットには明確に定義された結果があります。

6.6.2 階層化の 計算

階層化アルゴリズムに 従い、 すべての規則は階層 0 から開始します。その後、何も変化しなくなるまで 辺が繰り返し検査されます。

  • オープン辺では、始点側の規則が 終点側と同じ階層またはそれより上位の階層にある必要があります。4つのオープン辺はすべて、 すべての規則が階層 0 にある状態ですでにこの条件を満たしているため、 変更は発生しません。
  • クローズド辺では、始点側の規則が 終点側より厳密に上位の階層にある必要があります。これは、終点側を 先に完了まで実行する必要があるためです。辺 R4 → R3 (クローズド)では、R4R3 がどちらも階層 0 にあるため、R4 は 階層 1 に移動されます。同様に、辺 R5 → R3 (クローズド)により、R5 は階層 1 に移動されます。

さらに辺を1回走査しても変更はないため、階層は 確定します。次に、各階層は 一度だけ実行される規則一般規則に分割されます。 R5 のヘッドには空白 ノードがあるため、これは一度だけ実行される規則です。ほかの規則には、 代入要素も、ヘッド内の空白ノードもありません。 階層化は次のとおりです。

  • 階層 0:一般規則 R1R2R3。一度だけ実行される規則はなし
  • 階層 1:一度だけ実行される規則 R5。一般規則 R4

この順序付けは、上位 階層にある規則の意図を反映しています。コンポーネントを安全にデプロイできるかどうか、および どのコンポーネントに通知が必要かは、 すべての :status :criticallyExposed トリプルが導出された後にのみ判断できます — また、それらを導出する規則 R3 は、 その入力を生成する規則 R1 および R2 とともに、 下位の階層で完了します。

6.6.3 各階層の評価

評価は、 6.5 規則 セットの評価のアルゴリズムに従います。 評価グラフ GE は基本グラフとして開始し、 推論グラフ GI は空の状態で開始します。各階層は順番に 完了まで評価されます。階層内の規則は パス単位で評価され、パスが新しいトリプルを生成しなくなるまで繰り返されます。 このアルゴリズムは、1つのパス内で階層内の規則を 評価する順序を固定していません。この実行過程では、 R1R2R3 の順序を使用します。異なる順序では、同じ 推論が異なる回数のパスに分散される場合がありますが、 階層 0 は完了まで実行されるため、同じ最終グラフが生成されます。

この規則セットには DATA ブロックがないため、評価中のすべての時点で GEG0GI を合わせたものです。したがって、この実行過程では GI のみを追跡し、評価の進行に伴う状態を示すとともに、 各新規トリプルに、それを生成した規則を記します。

階層 0、1回目のパス。

  • R1:本体が :db :hasVulnerability :vuln1 と一致し、 ?x = :db および ?v = :vuln1 が束縛されます。 ヘッドは :db :exposedTo :vuln1 を生成します。 このトリプルは GE にないため、GEGI に追加されます。
  • R2:本体は ?x :dependsOn ?y?y :exposedTo ?v を結合します。GE には現在 :db :exposedTo :vuln1 が含まれるため、この結合から1つの解が得られます。 ?x = :app?y = :db、および ?v = :vuln1:app :dependsOn :db から)です。 ヘッドは新しい :app :exposedTo :vuln1 を生成し、 追加されます。:frontend に対する解はまだありません。これは、 R2 のこの評価が開始された時点では、 :app :exposedTo :vuln1GE に含まれていなかったためです。
  • R3?x :exposedTo ?v は現在、:db:app に対して一致します。 :vuln1 :severity 9.1 と結合し、 FILTER(?s >= 9.0) を適用すると、両方の解が保持されます。 ヘッドは :db :status :criticallyExposed:app :status :criticallyExposed を生成し、どちらも新規です。
# 階層 0 の1回目のパス後の GI
:db  :exposedTo :vuln1 .                    # 新規 (R1)
:app :exposedTo :vuln1 .                    # 新規 (R2)
:db  :status :criticallyExposed .           # 新規 (R3)
:app :status :criticallyExposed .           # 新規 (R3)

新しいトリプルが生成されたため、階層 0 の評価は 次のパスに続きます。

階層 0、2回目のパス。

  • R1:前と同様に一致します。:db :exposedTo :vuln1 はすでに GE にあるため、新しいものは生成されません。
  • R2:結合からさらに ?x = :frontend?y = :app、および ?v = :vuln1 が得られ、 新しいトリプル :frontend :exposedTo :vuln1 が生成されます。 露出が依存関係チェーンに沿って2段階伝播するには、 2回のパスが必要でした。
  • R3:新しいトリプル :frontend :status :criticallyExposed を生成します。
# 階層 0 の2回目のパス後の GI
:db       :exposedTo :vuln1 .
:app      :exposedTo :vuln1 .
:frontend :exposedTo :vuln1 .               # 新規 (R2)
:db       :status :criticallyExposed .
:app      :status :criticallyExposed .
:frontend :status :criticallyExposed .      # 新規 (R3)

階層 0、3回目のパス。 すべての規則のすべての解が、現在ではすでに GE 内にあるトリプルのみを生成します。GI は変更されません。 新しいトリプルがないため、階層 0 は完了です。今後 導出可能なすべての :exposedTo トリプルおよび :status :criticallyExposed トリプルが導出されました。

階層 1、一度だけ実行される規則。 階層内の一度だけ実行される規則が先に評価され、 それぞれが厳密に1回だけ実行されます。

  • R5:本体が3つの :status :criticallyExposed トリプルと一致し、解 ?x = :db?x = :app、および ?x = :frontend が得られます。各解についてヘッドをインスタンス化すると、 新しい空白ノードが作成され、解ごとに 2つのトリプル、すなわち各重大コンポーネントに対する 通知が生成されます。その後、階層内の一般規則が 繰り返し評価されますが、R5 が再び評価されることはありません。

階層 1、一般規則の1回目のパス。

  • R4:パターン ?x rdf:type :Component は、 :frontend:app:db、および :logger と一致します。 (R5 によって直前に作成された rdf:type :Notification トリプルとは一致しません。) 否定要素 NOT { ?x :status :criticallyExposed } は、 :frontend:app、および :db に対する解を棄却します。これは、 GE にそれぞれの :status :criticallyExposed トリプルが含まれるためです。 解 ?x = :logger のみが残り、新しい トリプル :logger :status :safeToDeploy を生成します。
# 階層 1 後の GI
:db       :exposedTo :vuln1 .
:app      :exposedTo :vuln1 .
:frontend :exposedTo :vuln1 .
:db       :status :criticallyExposed .
:app      :status :criticallyExposed .
:frontend :status :criticallyExposed .
_:n1      rdf:type :Notification .          # 新規 (R5)
_:n1      :concerns :db .                   # 新規 (R5)
_:n2      rdf:type :Notification .          # 新規 (R5)
_:n2      :concerns :app .                  # 新規 (R5)
_:n3      rdf:type :Notification .          # 新規 (R5)
_:n3      :concerns :frontend .             # 新規 (R5)
:logger   :status :safeToDeploy .           # 新規 (R4)

階層 1、一般規則の2回目のパス。 新しいトリプルはありません。評価は完了し、上に示した GI が 結果となる推論グラフです。

階層化によって、この結果の信頼性が確保されます。 階層 0 の1回目のパス中、まだ :frontend :status :criticallyExposed が導出される前に評価されていた場合、R4:frontend :status :safeToDeploy であると誤って結論付け、 R5:db:app に対する通知を作成しても、 :frontend に対する通知は作成しなかったはずです。 両方を階層 1 まで遅延させることで、完全な :status :criticallyExposed トリプルの集合を参照できるため、各階層内で 規則が評価される順序は 最終結果に影響しません。

7. SPARQL-RL文法

SPARQL-RL文書とは、 UTF-8 [RFC3629]で符号化された RDF文字列であり、 RuleSet 生成規則で始まり、 7.6 文法で定義される追加の制約に適合するものです。 U+0000からU+D7FFまで、および U+E000からU+10FFFFまでの範囲にある Unicodeスカラー値のみが 許可されます。これにより、U+D800から U+DFFFまでの範囲にある サロゲートコードポイントは除外されます。

7.1 バージョン宣言

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

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

バージョン宣言は文書の早い段階で行われるべきです

1つのSPARQL-RL文書内に、 複数のVERSIONディレクティブが 現れる場合があります。 各ディレクティブは、そのディレクティブより後の文書部分に適用され、 別のディレクティブが現れるか、文書の末尾に達するまで有効です。

バージョンラベルは、 メディアタイプversion パラメーターによって指定することもできます。現在有効な VERSIONディレクティブがない場合は、 メディアタイプの一部として指定されたバージョンが考慮されます。

7.2 空白

空白 (生成規則WS)は、 それ以外では1つの終端記号として(誤)認識される2つの終端記号を 分離するために使用されます。以下に大文字で示されるルール名は、 空白が重要となる箇所を示します。これらは、SPARQL-RLパーサーを構築するための 終端記号として使用可能な選択肢を構成します。

生成規則 Stringでは、空白が重要です。

7.3 コメント

コメントは、 IRIREFSTRING_LITERAL1STRING_LITERAL2STRING_LITERAL_LONG1、または STRING_LITERAL_LONG2の外部にある #で始まり、 行末(LFまたは CRによって示されます)まで続きます。 コメントマーカーより後に行末がない場合は、 ファイルの末尾まで続きます。 コメントは空白として扱われます。

7.4 IRI参照

相対IRI参照は、 統一資源識別子(URI):汎用 構文 [RFC3986]の 第5.2節にある基本アルゴリズムのみを使用し、ベースIRIによって解決されます。 RFC3986の第6.2.2節および第6.2.3節で説明されている 構文ベースの正規化もスキームベースの正規化も実行されません。 IRI参照で追加的に許可される文字は、国際化資源識別子 (IRI) [RFC3987]の第6.5節に従い、 URI参照内の非予約文字と同じ方法で扱われます。

BASE ディレクティブは、 [RFC3986]に従って 相対IRI 参照を解決するために使用するベースIRIを定義します。 第5.1.1節「コンテンツに 埋め込まれたベースURI」第5.1.2節「カプセル化 エンティティからのベースURI」では、 スコープ内ベースIRIを、xml:baseディレクティブを持つSOAPエンベロープや Content-Locationヘッダーを持つMIMEマルチパート文書などの カプセル化文書から取得する方法を定義しています。 第5.1.3節「取得URIからのベース URI」で識別される「取得URI」は、 特定のSPARQL-RL文書を取得したURLです。 上記のいずれによってもベースURIが指定されない場合は、 デフォルトのベースURI(第5.1.4節「デフォルトのベースURI」)が 使用されます。 各BASEディレクティブは、 直前のベースURIを基準として、新しいスコープ内ベースURIを設定します。

7.5 エスケープシーケンス

SRL文書では、 3つの形式のエスケープを使用します:

各種エスケープシーケンスを使用できるコンテキスト
数値
エスケープ
文字列
エスケープ
予約文字
エスケープ
PREFIXまたは BASE宣言で、 RDF項として使用される IRI はい いいえ いいえ
ローカル名 いいえ いいえ はい
文字列 はい はい いいえ
注記

%-エンコードされたシーケンスは、 IRIの文字範囲に含まれ、 ローカル名で明示的に許可されています。 これらは、%の後に 2つの16進文字が続く形で現れ、 同じ3文字のシーケンスを表します。これらのシーケンスは処理中に デコードされることはありません<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.6 文法

ここで使用するEBNFは、XML 1.0 [EBNF-NOTATION]で定義されています。

注記:

  1. 文法のエントリーポイントはRuleSetです。
  2. キーワードは、大文字と小文字が区別される 「a」を除き、 大文字と小文字が区別されません。
  3. エスケープシーケンスUCHARおよび ECHARは、 大文字と小文字が区別されます。
  4. DATAブロック内では、変数は許可されません。
  5. 入力をトークン化して文法規則を選択する際は、最長一致が選択されます。
  6. 大文字の名前を持つ規則を終端記号として 使用する場合、SPARQL-RL文法は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 ::= 'RULE' iri? HeadTemplate 'WHERE' 'DATA'? BodyPattern
[12] Data ::= 'DATA' '{' DataTriplesBlock? '}'
[13] HeadTemplate ::= '{' HeadTemplateBlock? '}'
[14] BodyPattern ::= '{' BodyTriplesBlock? ( BodyNotTriples '.'? BodyTriplesBlock? )* '}'
[15] BodyNotTriples ::= Filter | Negation | Assignment
[16] Filter ::= 'FILTER' Constraint
[17] Constraint ::= BrackettedExpression | BuiltInCall | FunctionCall
[18] FunctionCall ::= iri ArgList
[19] ArgList ::= NIL | '(' Expression ( ',' Expression )* ')'
[20] ExpressionList ::= NIL | '(' Expression ( ',' Expression )* ')'
[21] Negation ::= 'NOT' 'DATA'? '{' BodyBasic '}'
[22] BodyBasic ::= BodyTriplesBlock? ( BodyBasicNotTriples '.'? BodyTriplesBlock? )*
[23] BodyBasicNotTriples ::= Filter
[24] Assignment ::= 'SET' '(' Var ':=' Expression ')'
[25] DataTriplesBlock ::= TriplesSameSubjectData ( '.' DataTriplesBlock? )?
[26] TriplesSameSubjectData ::= RDFTermData PropertyListNotEmptyData | TriplesNodeData PropertyListData | ReifiedTripleBlockData
[27] PropertyListData ::= PropertyListNotEmptyData?
[28] PropertyListNotEmptyData ::= VerbData ObjectListData ( ';' ( VerbData ObjectListData )? )*
[29] VerbData ::= iri | 'a'
[30] ObjectListData ::= ObjectData ( ',' ObjectData )*
[31] ObjectData ::= GraphNodeData AnnotationData
[32] GraphNodeData ::= RDFTermData | TriplesNodeData | ReifiedTripleData
[33] TriplesNodeData ::= CollectionData | BlankNodePropertyListData
[34] BlankNodePropertyListData ::= '[' PropertyListNotEmptyData ']'
[35] CollectionData ::= '(' GraphNodeData+ ')'
[36] AnnotationData ::= ( ReifierData | AnnotationBlockData )*
[37] AnnotationBlockData ::= '{|' PropertyListNotEmptyData '|}'
[38] ReifierData ::= '~' ReifierIdData?
[39] ReifierIdData ::= iri | BlankNode
[40] ReifiedTripleBlockData ::= ReifiedTripleData PropertyListData
[41] ReifiedTripleData ::= '<<' ReifiedTripleSubjectData VerbData ReifiedTripleObjectData ReifierData? '>>'
[42] ReifiedTripleSubjectData ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTripleData | TripleTermData
[43] ReifiedTripleObjectData ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTripleData | TripleTermData
[44] TripleTermData ::= '<<(' TripleTermSubjectData VerbData TripleTermObjectData ')>>'
[45] TripleTermSubjectData ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTermData
[46] TripleTermObjectData ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTermData
[47] HeadTemplateBlock ::= TriplesBlockTemplate
[48] TriplesBlockTemplate ::= TriplesSameSubjectTemplate ( '.' TriplesBlockTemplate? )?
[49] TriplesSameSubjectTemplate ::= VarOrRDFTerm PropertyListNotEmptyTemplate | TriplesNodeTemplate PropertyListTemplate | ReifiedTripleBlockTemplate
[50] PropertyListTemplate ::= PropertyListNotEmptyTemplate?
[51] PropertyListNotEmptyTemplate ::= Verb ObjectListTemplate ( ';' ( Verb ObjectListTemplate )? )*
[52] ObjectListTemplate ::= ObjectTemplate ( ',' ObjectTemplate )*
[53] ObjectTemplate ::= GraphNodeTemplate AnnotationTemplate
[54] GraphNodeTemplate ::= VarOrRDFTerm | TriplesNodeTemplate | ReifiedTriple
[55] TriplesNodeTemplate ::= CollectionTemplate | BlankNodePropertyListTemplate
[56] BlankNodePropertyListTemplate ::= '[' PropertyListNotEmptyTemplate ']'
[57] CollectionTemplate ::= '(' GraphNodeTemplate+ ')'
[58] AnnotationTemplate ::= ( Reifier | AnnotationBlockTemplate )*
[59] AnnotationBlockTemplate ::= '{|' PropertyListNotEmptyTemplate '|}'
[60] ReifiedTripleBlockTemplate ::= ReifiedTriple PropertyListTemplate
[61] BodyTriplesBlock ::= TriplesBlockPattern
[62] TriplesBlockPattern ::= TriplesSameSubjectPattern ( '.' TriplesBlockPattern? )?
[63] ReifiedTripleBlockPattern ::= ReifiedTriple PropertyListPattern
[64] TriplesSameSubjectPattern ::= VarOrRDFTerm PropertyListNotEmptyPattern | TriplesNodePattern PropertyListPattern | ReifiedTripleBlockPattern
[65] PropertyListPattern ::= PropertyListNotEmptyPattern?
[66] PropertyListNotEmptyPattern ::= ( VerbPath | Var ) ObjectListPattern ( ';' ( ( VerbPath | Var ) ObjectListPattern )? )*
[67] ObjectListPattern ::= ObjectPattern ( ',' ObjectPattern )*
[68] ObjectPattern ::= GraphNodePattern AnnotationPattern
[69] TriplesNodePattern ::= CollectionPattern | BlankNodePropertyListPattern
[70] BlankNodePropertyListPattern ::= '[' PropertyListNotEmptyPattern ']'
[71] CollectionPattern ::= '(' GraphNodePattern+ ')'
[72] AnnotationPattern ::= ( Reifier | AnnotationBlockPattern )*
[73] AnnotationBlockPattern ::= '{|' PropertyListNotEmptyPattern '|}'
[74] GraphNodePattern ::= VarOrRDFTerm | TriplesNodePattern | ReifiedTriple
[75] Reifier ::= '~' ReifierId?
[76] ReifierId ::= Var | iri | BlankNode
[77] ReifiedTriple ::= '<<' ReifiedTripleSubject Verb ReifiedTripleObject Reifier? '>>'
[78] ReifiedTripleSubject ::= Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple | TripleTerm
[79] ReifiedTripleObject ::= Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple | TripleTerm
[80] TripleTerm ::= '<<(' TripleTermSubject Verb TripleTermObject ')>>'
[81] TripleTermSubject ::= Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTerm
[82] TripleTermObject ::= Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTerm
[83] Verb ::= VarOrIri | 'a'
[84] VerbPath ::= Path
[85] Path ::= PathSequence
[86] PathSequence ::= PathEltOrInverse ( '/' PathEltOrInverse )*
[87] PathEltOrInverse ::= PathElt | '^' PathElt
[88] PathElt ::= ( iri | 'a' | '(' Path ')' )
[89] RDFTermData ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | NIL | TripleTermData
[90] VarOrRDFTerm ::= Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | NIL | TripleTerm
[91] VarOrIri ::= Var | iri
[92] Var ::= VAR1 | VAR2
[93] RDFLiteral ::= String ( LANG_DIR | '^^' iri )?
[94] NumericLiteral ::= NumericLiteralUnsigned | NumericLiteralPositive | NumericLiteralNegative
[95] NumericLiteralUnsigned ::= INTEGER | DECIMAL | DOUBLE
[96] NumericLiteralPositive ::= INTEGER_POSITIVE | DECIMAL_POSITIVE | DOUBLE_POSITIVE
[97] NumericLiteralNegative ::= INTEGER_NEGATIVE | DECIMAL_NEGATIVE | DOUBLE_NEGATIVE
[98] BooleanLiteral ::= 'true' | 'false'
[99] String ::= STRING_LITERAL1 | STRING_LITERAL2 | STRING_LITERAL_LONG1 | STRING_LITERAL_LONG2
[100] iri ::= IRIREF | PrefixedName
[101] PrefixedName ::= PNAME_LN | PNAME_NS
[102] BlankNode ::= BLANK_NODE_LABEL | ANON
[103] Expression ::= ConditionalOrExpression
[104] ConditionalOrExpression ::= ConditionalAndExpression ( '||' ConditionalAndExpression )*
[105] ConditionalAndExpression ::= ValueLogical ( '&&' ValueLogical )*
[106] ValueLogical ::= RelationalExpression
[107] RelationalExpression ::= NumericExpression ( '=' NumericExpression | '!=' NumericExpression | '<' NumericExpression | '>' NumericExpression | '<=' NumericExpression | '>=' NumericExpression | 'IN' ExpressionList | 'NOT' 'IN' ExpressionList )?
[108] NumericExpression ::= AdditiveExpression
[109] AdditiveExpression ::= MultiplicativeExpression ( '+' MultiplicativeExpression | '-' MultiplicativeExpression | ( NumericLiteralPositive | NumericLiteralNegative ) ( ( '*' UnaryExpression ) | ( '/' UnaryExpression ) )* )*
[110] MultiplicativeExpression ::= UnaryExpression ( '*' UnaryExpression | '/' UnaryExpression )*
[111] UnaryExpression ::= '!' PrimaryExpression
| '+' PrimaryExpression
| '-' PrimaryExpression
| PrimaryExpression
[112] PrimaryExpression ::= BrackettedExpression | BuiltInCall | iriOrFunction | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprTripleTerm
[113] iriOrFunction ::= iri ArgList?
[114] ExprTripleTerm ::= '<<(' ExprTripleTermSubject Verb ExprTripleTermObject ')>>'
[115] ExprTripleTermSubject ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | Var
[116] ExprTripleTermObject ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprTripleTerm
[117] BrackettedExpression ::= '(' Expression ')'
[118] 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 ')'

終端記号の生成規則:

[119] IRIREF ::= '<' ([^<>"{}|^`\]-[#x00-#x20] | UCHAR )* '>'
[120] PNAME_NS ::= PN_PREFIX? ':'
[121] PNAME_LN ::= PNAME_NS PN_LOCAL
[122] BLANK_NODE_LABEL ::= '_:' ( PN_CHARS_U | [0-9] ) ((PN_CHARS|'.')* PN_CHARS)?
[123] VAR1 ::= '?' VARNAME
[124] VAR2 ::= '$' VARNAME
[125] LANG_DIR ::= '@' [a-zA-Z]+ ('-' [a-zA-Z0-9]+)* ('--' [a-zA-Z]+)?
[126] INTEGER ::= [0-9]+
[127] DECIMAL ::= [0-9]* '.' [0-9]+
[128] DOUBLE ::= ( ([0-9]+ ('.'[0-9]*)? ) | ( '.' ([0-9])+ ) ) [eE][+-]?[0-9]+
[129] INTEGER_POSITIVE ::= '+' INTEGER
[130] DECIMAL_POSITIVE ::= '+' DECIMAL
[131] DOUBLE_POSITIVE ::= '+' DOUBLE
[132] INTEGER_NEGATIVE ::= '-' INTEGER
[133] DECIMAL_NEGATIVE ::= '-' DECIMAL
[134] DOUBLE_NEGATIVE ::= '-' DOUBLE
[135] STRING_LITERAL1 ::= "'" ( ([^#x27#x5C#xA#xD]) | ECHAR | UCHAR )* "'"
[136] STRING_LITERAL2 ::= '"' ( ([^#x22#x5C#xA#xD]) | ECHAR | UCHAR )* '"'
[137] STRING_LITERAL_LONG1 ::= "'''" ( ( "'" | "''" )? ( [^'\] | ECHAR | UCHAR ) )* "'''"
[138] STRING_LITERAL_LONG2 ::= '"""' ( ( '"' | '""' )? ( [^"\] | ECHAR | UCHAR ) )* '"""'
[139] ECHAR ::= '\' [tbnrf\"']
[140] UCHAR ::= ('\u' HEX HEX HEX HEX) | ('\U' HEX HEX HEX HEX HEX HEX HEX HEX)
[141] NIL ::= '(' WS* ')'
[142] WS ::= #x20 | #x9 | #xD | #xA
[143] ANON ::= '[' WS* ']'
[144] 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]
[145] PN_CHARS_U ::= PN_CHARS_BASE | '_'
[146] VARNAME ::= ( PN_CHARS_U | [0-9] ) ( PN_CHARS_U | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] )*
[147] PN_CHARS ::= PN_CHARS_U | '-' | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040]
[148] PN_PREFIX ::= PN_CHARS_BASE ((PN_CHARS|'.')* PN_CHARS)?
[149] PN_LOCAL ::= (PN_CHARS_U | ':' | [0-9] | PLX ) ((PN_CHARS | '.' | ':' | PLX)* (PN_CHARS | ':' | PLX) )?
[150] PLX ::= PERCENT | PN_LOCAL_ESC
[151] PERCENT ::= '%' HEX HEX
[152] HEX ::= [0-9] | [A-F] | [a-f]
[153] PN_LOCAL_ESC ::= '\' ( '_' | '~' | '.' | '-' | '!' | '$' | '&' | "'" | '(' | ')' | '*' | '+' | ',' | ';' | '=' | '/' | '?' | '#' | '@' | '%' )

この文法のテキスト版は こちらから入手できます。

7.7 選択された終端リテラル 文字列

この文書では、いくつかの特定の終端リテラル文字列を使用します [EBNF-NOTATION]。これらの 終端リテラル文字列で使用される Unicode コードポイントを明確にするため、 次の表では、このセクションで使用される特定の 文字について説明します。

コード グリフ 説明
U+000A LF 改行
U+000D CR 復帰
U+0023 # 番号記号
U+0025 % パーセント記号
U+005C \ バックスラッシュ

A. インポートアルゴリズムの例

以下のアルゴリズムは、参照されているすべての文書を再帰的に 訪問することによってインポート文を解決する方法の 1 つを示します。

2 つのルールセット RS1RS2ルールセット マージとは、 次のように定義されるルールセット MR です。

define ruleSetMerge(rule set R1,rule Set RS2):
    MR.rules = RS1.rules ∪︀ RS2.rules
    MR.data = rdf_merge(RS1.data, RS2.data)
    MR.imports = {}
    the result is MR
enddefine

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
    the 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)

ここで、rdf_mergeRDF マージ 操作です。

B. インターネットメディアタイプおよびファイル 拡張子

SPARQL-RLのインターネットメディアタイプ(以前はMIMEタイプと呼ばれていました)は、 「application/sparql-rl」です。

以下の情報は、審査、承認、およびIANAへの登録のため、 Internet Engineering Steering Group(IESG)に提出されています。

タイプ名:
application
サブタイプ名:
sparql-rl
必須パラメーター:
なし
任意のパラメーター:
version
このパラメーターは任意です。 指定する場合、versionとして使用可能な値は、 バージョンラベルで定義されています。
profile
このパラメーターは任意であり、追加情報を含めるために使用されます。 プロファイルに関する知識なしで処理された場合でも、 リソース表現の意味論は変更されません。 profileパラメーターの値は、空白で区切られたURIの空でないリストです。 詳細および背景については、[RFC6906]を参照してください。
符号化に関する考慮事項:
SPARQL-RLの構文は、Unicode [UNICODE]のコードポイントを使用して表現されます。符号化は常にUTF-8 [RFC3629]です。
Unicodeコードポイントは、Xを16進数字[0-9A-F]とする\uXXXX(U+0からU+FFFF)または \UXXXXXXXX構文(U+10000以降)を使用して表現することもできます。
セキュリティに関する考慮事項:
C. セキュリティに関する考慮事項、および ISO 10646の 変換形式であるUTF-8 [RFC3629]の第7節「セキュリティに関する 考慮事項」を参照してください。
相互運用性に関する考慮事項:
既知の相互運用性の問題はありません。
公開済み仕様:
この仕様。
追加情報:
マジックナンバー:
SPARQL-RLファイルでは、文書の先頭付近に 文字列「PREFIX」(大文字と小文字を区別しない)が 含まれる場合があります。
ファイル拡張子:
".srl"
ベースURI:
SPARQL-RLの「BASE <IRIref>」項は、 文書内で後から順次使用されるクエリ言語の相対IRIrefに対する 現在のベースURIを変更できます。
詳細情報の問い合わせ先およびメールアドレス:
Data Shapesワーキンググループ <public-shacl@w3.org;
想定される用途:
COMMON
使用上の制限:
なし
作成者/変更管理者:
SPARQL-RL仕様は、World Wide Web ConsortiumのData Shapesワーキンググループによる成果物です。W3Cがこれらの仕様に対する変更 管理権を有します。

C. セキュリティに関する考慮事項

この節は非規範的です。

SPARQL-RL文書には、他の SPARQL-RL文書を参照し、その内容を現在の 文書にインポートするIMPORTS文が含まれる場合があります。 インポートされた文書自体に独自のIMPORTS文が含まれている場合は、 それらの文書もインポートされます。

ルールセットをモジュール化するうえでは有用ですが、 IMPORTS文を使用するとセキュリティ上のリスクが 生じる可能性があります。 リスクには、悪意によるか偶発的であるかを問わず、評価中に ルールセットが 過剰な計算を引き起こすことや、HTTPリクエストが傍受され、 古いコピーを含む別の文書が返されることなどがありますが、 これらに限定されません。

SPARQL-RLルールセットをデータグラフに適用すると、 大量の計算処理およびメモリ使用が発生する可能性があり、これを悪用して サービス拒否を引き起こすことができます。 アプリケーションは、SPARQL-RLルールセットの適用によって生じる 計算量およびメモリ使用量を制限するよう注意する必要があります。

SPARQL-RL構文はUTF-8 [RFC3629]で符号化され、 文字列データ内でエスケープされていない 制御文字を使用できます。 この仕様はこの内容をエンドユーザーに直接公開しませんが、 ユーザーエージェントを通じて提示される可能性があり、その場合、そのような文字の表示によって 提示されるテキストが不明瞭になる可能性があります。

SPARQL-RLを使用して、任意のアプリケーションデータを処理および作成できます。 セキュリティに関する考慮事項は、使用分野によって異なります。 テキストに適用可能なセキュリティツールおよびプロトコル (たとえば、PGP暗号化、チェックサム検証、パスワード保護された圧縮)も、 SPARQL-RL文書に使用できます。 SPARQL-RLルールセット評価の結果に含まれる情報の機密性を反映した セキュリティ/プライバシープロトコルを適用しなければなりません。

SPARQL-RLのセキュリティに関する考慮事項には、 RDFデータおよび RDF Turtleなどの 形式に関する考慮事項が含まれます。

D. プライバシーに関する考慮事項

この節は非規範的です。

SPARQL-RL文書には、個人を特定できる情報(PII)または 機密性が高いと見なされるその他の情報の表現を含む可能性がある、 追加のアプリケーションデータを含めることができます。 このような情報を含むルールセットを公開する作成者は、 そのような情報を公開する必要性および用途に加え、 データが利用され、場合によっては開示されることが想定される地域に 適用される規制(たとえば、 GDPRCCPAその他)を慎重に検討し、 特にデータへのアクセスに認可措置が必要かどうかを考慮することが推奨されます。

E. 謝辞

この節は非規範的です。

次の人々が、Data ShapesワーキンググループのルールタスクフォースにおけるSPARQL-RLの 開発に貢献しました: Robert David、David Habgood、Livio Robaldo、Ognjen Savkovic、Simon Steyskal、Ted Thibodeau Jr、およびAndy Seaborne。

Data Shapesワーキンググループのメンバーには@@が含まれていました。

F. 索引

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

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

G. 課題の概要

この仕様には課題が記載されていません。

H. 参考文献

H.1 規範的参考文献

[EBNF-NOTATION]
EBNF記法。Tim Bray、Jean Paoli、Michael Sperberg-McQueen、Eve Maler、François Yergeauほか。W3C。W3C勧告。URL:https://www.w3.org/TR/xml/#sec-notation
[I18N-GLOSSARY]
国際化用語集。 Richard Ishida、Addison Phillips。W3C。2024年10月17日。W3Cワーキンググループノート。URL:https://www.w3.org/TR/i18n-glossary/
[rdf-concepts]
リソース記述フレームワーク(RDF):概念 および抽象構文。Graham Klyne、Jeremy Carroll。W3C。2004年2月10日。W3C 勧告。URL:https://www.w3.org/TR/rdf-concepts/
[RDF12-CONCEPTS]
RDF 1.2の概念および抽象データ モデル。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意味論。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年8月12日。W3C作業草案。URL:https://www.w3.org/TR/rdf12-turtle/
[RFC2119]
要求レベルを示すためにRFCで使用する キーワード。S. Bradner。IETF。1997年3月。現行の最良慣行。URL:https://www.rfc-editor.org/info/rfc2119/
[RFC3629]
ISO 10646の変換形式であるUTF-8。F. Yergeau。IETF。2003年11月。インターネット標準。URL:https://www.rfc-editor.org/info/rfc3629/
[RFC3986]
統一資源識別子(URI):汎用 構文。T. Berners-Lee、R. Fielding、L. Masinter。IETF。2005年1月。インターネット 標準。URL:https://www.rfc-editor.org/info/rfc3986/
[RFC3987]
国際化資源識別子 (IRI)。M. Duerst、M. Suignard。IETF。2005年1月。標準化提案。URL:https://www.rfc-editor.org/info/rfc3987/
[RFC6906]
「profile」リンク関係 タイプ。E. Wilde。IETF。2013年3月。情報提供。URL:https://www.rfc-editor.org/info/rfc6906/
[RFC8174]
RFC 2119キーワードにおける大文字と小文字の曖昧さ。B. Leiba。IETF。2017年5月。現行の最良慣行。URL:https://www.rfc-editor.org/info/rfc8174/
[shacl12-node-expr]
SHACL 1.2ノード式。 Robert David、Holger Knublauch、Simon Steyskal。W3C。2026年7月21日。W3C作業草案。URL:https://www.w3.org/TR/shacl12-node-expr/
[SPARQL12-QUERY]
SPARQL 1.2クエリ言語。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]
Unicode標準。Unicode コンソーシアム。URL:https://www.unicode.org/versions/latest/