Copyright © 2025-2026 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
この文書は、RDF 向けの Datalog 形式のルール言語である SPARQL-RL を定義します。
SPARQL-RL は、入力 RDF グラフに対して宣言的な ルールの集合を評価することにより、新しい RDF データを生成します。ルールは SPARQL に似たテキスト構文で記述されます。
この仕様は、 W3C Data Shapes ワーキンググループによって公開されています。
この節では、この 文書の公開時点におけるステータスについて説明します。現在の W3C の公開文書一覧およびこの技術報告書の最新リビジョンは、 W3C 標準およびドラフト の索引で確認できます。
この文書は、Data Shapes ワーキング グループによって、 勧告 トラックを使用する ワーキングドラフトとして公開されました。
ワーキングドラフトとしての公開は、 W3C およびそのメンバーによる承認を意味するものではありません。
これはドラフト文書であり、いつでも他の 文書によって更新、置換、または廃止される可能性があります。この文書を進行中の作業以外のものとして 引用することは適切ではありません。 今後、この将来の勧告が更新される際には、 新しい機能が組み込まれる可能性があります。
この文書は、 W3C 特許 ポリシーの下で活動するグループによって作成されました。 W3C は、 グループの成果物に関連して行われた 特許開示の公開 一覧 を維持しています。そのページには、 特許を開示するための手順も記載されています。自身が 必須クレーム を含むと考える特許について実際に 知っている個人は、 W3C 特許ポリシー第 6 節に従って、その情報を開示しなければなりません。
この文書には、 2025 年 8 月 18 日付 W3C プロセス文書が適用されます。
この文書では SPARQL-RL を紹介します。これは、宣言的なルールを通じて 既存の RDF データから新しい RDF トリプルを導出するための仕組みです。 この文書では、ルールベース推論の構文と意味論を定義します。
SPARQL-RL の実装は、infer および query の 一方または両方の操作を提供します。 infer 操作は、指定された ベースグラフにルールを適用し、ベースグラフには現れない、 ルール評価によって導出された RDF トリプルを含む推論グラフを生成します。 推論グラフとベースグラフを結合するかどうかは任意であり、 ユーザーに委ねられます。 query 操作は、指定されたゴールパターンが、 ルールを使用してベースグラフから導出できるかどうか、およびどのように導出できるかを 判定します。
SPARQL-RL では、空白ノードを含む新しい RDF 項を作成でき、 それらをルールのヘッド内のトリプルテンプレートで使用できます。
SPARQL-RL は失敗による否定もサポートしており、ルールを 評価する順序によって異なる推論グラフが生じる可能性があります。 これを避けるため、ルールは層別化という手法を使用して評価されます。 これはルール間に順序を確立し、 常に同じ推論グラフが生成されることを保証します。
文脈が明確な場合、SPARQL-RL は SRL と呼ぶことができます。
次の仕様は、この文書で使用される 基本的な用語を提供します。
この文書における RDF データの例では、 RDF 1.2 Turtle [RDF12-TURTLE] を使用します。
この文書では、次の名前空間接頭辞バインディングを使用します。
| 接頭辞 | 名前空間 |
|---|---|
rdf: |
http://www.w3.org/1999/02/22-rdf-syntax-ns# |
xsd: |
http://www.w3.org/2001/XMLSchema# |
: |
http://example/ |
文書全体を通して、色分けされたボックスには SPARQL-RL 構文のルール または Turtle 構文の RDF グラフが含まれます。
# このボックスはルールを表します
# このボックスは入力データを表します
# このボックスは推論されたデータを表します
非規範的と明示された節に加え、この仕様内のすべての作成ガイドライン、図、例、および注記は 非規範的です。この仕様内のそれ以外のすべては規範的です。
この文書におけるキーワード MAY、MUST、MUST NOT、および SHOULD は、 ここに示すようにすべて 大文字で記述されている場合に限り、 BCP 14 [RFC2119] [RFC8174] に記述されているとおりに解釈されるものとします。
この仕様では、次の適合基準を定義します。
適合するSPARQL-RL 文書とは、
RDF 文字列であり、
7. SPARQL-RL 文法で
定義されている
RuleSet
生成規則から始まる文法に
適合するものです。
この仕様では、SPARQL-RL プロセッサが 非適合のSPARQL-RL 文書をどのように 処理するかは定義しません。
この節は非規範的です。
SPARQL-RL は、ベースグラフとルールセットを与えると、新しいトリプルを推論します。 評価の出力は、ベースグラフには現れない導出された トリプルを含む推論グラフです。
各ルールには、ボディと呼ばれるパターンと、 ヘッドと呼ばれる結果テンプレートがあります。 ルールは、ボディが結合されたベースグラフおよび その時点までの実行によって推論されたトリプルに一致するように、 ボディ内の変数の値を見つけることで実行されます。 次に、これらの値を使用してルールヘッド内のトリプルテンプレートを インスタンス化し、新しい推論トリプルを生成します。
それ以上トリプルが推論されなくなるまでルールが実行され、 新しい推論トリプルが利用可能になるにつれて、ルールは複数回 実行されることがあります。
SPARQL-RL の実行は、新しい空白ノードを含む 新しい RDF 項を作成する場合や、パターンが存在しないことを テストする場合に、ルールの実行順序によって異なる結果が 生じないように定義されています。言い換えると、ルールの実行順序に 関係なく同じ推論グラフが生成されます。
SPARQL-RL には、SPARQL 1.2 クエリ言語から着想を得た、 人間に扱いやすい構文があります。 ルールセットの評価には SPARQL と類似した要素が含まれますが、 ルールの実行順序に関係なく同じ推論グラフが生成されることを 保証するため、細部には相違があります。
この節の例では、ソフトウェアコンポーネントと その依存関係について説明します。フロントエンドがアプリケーションサーバーを呼び出し、 アプリケーションサーバーは既知の脆弱性を持つ データベースにクエリを行います。
トリプルパターンはトリプルデータと照合され、 変数に値を与えます。パターンには 3つの要素があり、それぞれはRDF用語、変数、 または変数を含むトリプル用語のパターンです。
この最初の例では、基本グラフと規則集合に次のデータがあります。
上記の規則をデータに適用すると、次のように結論付けられます。
:frontendは:appに依存し、:appは
:dbに依存します。依存関係の種類は問いません。
次に、依存する規則を追加することで、:exposedTo関係を導出できます。
その依存先は、他の規則によって生成される:dependsOnトリプルです
(後述の4.3 規則の
依存関係も参照)。
前節の:exposedTo規則が到達するのは直接の
依存先のみです。:frontendは:dbに直接依存しないため、
:frontendについて:exposedToトリプルは推論されません。
任意の長さの依存関係の連鎖に沿って曝露を伝播させるため、
その規則を2つの規則に置き換えます。コンポーネントは、自身が持つ
脆弱性にさらされ、また、コンポーネントは、
その直接の依存先がさらされているあらゆる脆弱性にさらされます。
前の例と比較すると、ここでは次のものが追加されます。
:db :exposedTo :vuln1 — データベースは自身の
脆弱性にさらされます — および:frontend :exposedTo :vuln1です。
曝露は、依存関係の連鎖を通じて:frontendに到達します。
その連鎖の長さは問いません。
この最後の規則は再帰的な規則です。規則の本体が 規則の頭部に依存しています。
規則の本体で式を使用することで、変数の値を制限できます。 この制限は、本体の照合時に適用されます。 たとえば、各脆弱性の深刻度が与えられた場合、 深刻な脆弱性にさらされているコンポーネントに 状態を付与できます。
FILTERは式を評価し、現在の
変数束縛の集合を、式の評価結果が真であれば保持し、
式の評価結果が偽であれば、現在の変数束縛の集合を破棄します。
これは、次のものと同じです。
SPARQLのFILTER演算
また、SPARQL-RLはSPARQLと同じ関数および演算子を多数提供します。
否定は、一致してはならないパターンを指定するために使用されます。 これは「失敗による否定」と呼ばれます。
否定要素を評価するため、規則集合の評価アルゴリズムは、 否定要素内のパターンに一致するトリプルを生成し得るすべての規則が 完了していることを保証します。これは、 階層化と呼ばれ、否定が、 データ由来であるか他の規則由来であるかを問わず、関連するすべての可能なトリプルに 基づくことを保証します。否定を含む規則は、 これらのトリプルを生成する規則に依存するといいます (後述の4.3 規則の 依存関係を参照)。
代入により、規則は式の結果を変数に代入できます。 これは規則の本体で行われます。これを使用すると、新しいRDF用語を データに基づいて作成できます。
規則の頭部では空白ノードを使用でき、それぞれが新しい空白ノードを生成します。 この生成は、規則の評価がトリプルを生成するたびに行われます。
代入を含む規則、空白ノードを作成する規則で、 その作成が規則の頭部の評価によるもの、およびテンプレートを持つ規則で、 そのテンプレートにトリプル用語が含まれ、その用語が変数を含むものは、 単一実行規則です。 このような規則は、依存するデータを生成し得るすべての規則の後に実行され、 自身が生成するデータに依存するすべての規則より前に実行されます。
この条件は、このような規則が自身へと循環し、 無制限の数のRDF用語を作成することがないよう保証します。
GROUP BYと集約関数を提供します。
これには少なくとも、
COUNT、COUNT DISTINCT、MIN、MAX、および
SUMが含まれます。
集約要素を持つ規則は、単一実行規則です。 このような規則は、自身が依存するデータを生成し得るすべての規則の 後に、自身が生成するデータに依存するすべての規則より前に実行されます。 集約要素は、完全なコレクションを消費します。その対象は、 解列であり、先行する規則要素のものです。 これらは規則の本体内にあり、次のものに基づいてグループにまとめられます。 グループキー。その後、評価します
SPARQL-RLの規則集合は、他の規則集合を組み込むことができます。 そのためには、それらのURLを、その規則集合の規則集合のインポートに含めます。 これにより、規則集合間で共有されるライブラリとして規則を構成できます。
規則集合のIMPORTS文は、その規則集合内のいずれの規則が
評価されるよりも前に処理されます。インポートのステップでは、インポートされた規則集合に
独自のインポートがある場合、それらも再帰的に処理されます。
規則集合の処理中にIMPORTS文をたどると、
循環するインポートに遭遇することがあります。規則集合は一度だけインポートされます。
インポート文のグラフに循環があっても、無限ループにはなりません。
規則集合のインポートのサポートは、SPARQL-RL 処理系にとって任意です。 詳細については、4.5 処理対象の インポートを参照してください。
データブロックは、規則集合の評価にRDFトリプルを直接提供します。 データブロック内のトリプルは推論グラフに追加され、 規則の本体での照合に利用できます。
たとえば、規則集合には、既知の事実を直接表明して 含めることができます。データから導出する必要はありません。
データブロックは、本体が空の規則と同等です。 そのトリプルは、いずれの規則も 評価されることなく、推論グラフの一部となります。
規則集合の評価中には、 元の基本グラフのみを対象としてパターン照合を行い、 推論されたトリプルを対象としないことが必要な場合があります。
この例として、既定値の設定があります。 規則は、基本グラフにすでに値が含まれているかを検査しなければならず、含まれていない場合、 その規則は既定値を計算できます。
NOT DATAを使用すると、規則の本体の他の部分では推論されたトリプルを照合できます。
また、すべての規則の本体の照合を、基本グラフに対して行うこともできます。
これにはWHERE DATAを使用します。
このような規則は、基本グラフからの照合のみに依存します。
この節での照合対象は、基本グラフです。
次によって追加されるトリプルは含まれません。
規則集合の評価
その追加元は、規則集合のDATAブロックです
(3.8 データブロック)。
規則は、規則集合にまとめられます。 規則集合とデータグラフ(基本グラフ)が評価への入力です。 出力は、推論グラフと呼ばれるグラフであり、 評価プロセスによって生成されるトリプルの集合で、 次の基本グラフに現れないものです。
評価中に、ある規則に基づいて推論されたトリプルは、 他の規則での照合に利用できます。 規則集合の評価は、 それ以上のトリプルを推論できなくなるまで進行します。 その入力は、規則集合と基本グラフです。
評価は、次のステップから始まります。 規則集合の準備 これらは、規則自体が評価される前に行われます。
規則集合の準備が完了すると、評価は次のように進行します。 階層化から各層を順に取り出し、 その層の規則を完了するまで評価し、 その後、次の層に進みます。 規則の実行によってトリプルが推論されると、それらは直ちに、 他の規則が実行される際に利用可能になります。
SPARQL-RL 抽象構文は、SPARQL-RL の論理構造です。 これは SPARQL-RL の実行アルゴリズムを定義するために使用されます。
トリプルテンプレートは、各要素が 変数、RDF用語、または トリプル用語のテンプレートで、変数を含むものである3つ組です。 この組の第2要素は、IRI または変数でなければなりません。 トリプルテンプレートが現れるのは、頭部、すなわち規則の頭部であり、 RDFトリプルの生成に使用されます。
.evaldataを持ち、
照合にどのグラフを使用するかを示します。
その照合対象は、否定要素の本体です。
IMPORTS文に由来し、
評価中に組み込まれる他の規則集合を対象とします。
.evaldataを含みます。
このフラグは、どの
グラフを照合に使用するかを示し、本体内のトリプルパターンを対象とします。
規則には、識別を助けるためにURIまたは空白ノードを付与できます。
単一実行規則は、ちょうど一度だけ実行される規則であり、 規則集合の評価における特定の時点で実行されます。 規則は、単一実行 規則です。ただし、次のいずれかが成り立つ場合です。
SPARQL-RLは、2つの操作、推論と問合せを提供します。
問合せは、与えられたパターンについて、 その導出が基本グラフから、規則集合を使用して可能かどうかを判定し、 解列を返す操作であり、その各解写像は、 変数に対するRDF用語を与えます。
問合せは、推論操作を実行し、 続いて目標パターンを、結合された 基本グラフと推論 グラフに照合する効果を持ちます。
問合せ操作は、すべての規則を評価しない場合があります。代わりに、 問合せの目標に答えるために必要な規則のみを 評価してもかまいません。
トリプルパターンまたはトリプル テンプレートでは、 組の位置1を、非形式的に主語と呼び、 位置2を、非形式的に述語と呼び、 位置3を、非形式的に目的語と呼びます。
規則要素の列の要素には、1から始まる番号を付けます。
規則集合と規則のさまざまな構成要素には、次の表記を使用します。
| 構成要素 | 用途 |
|---|---|
ruleset.rules |
規則集合の規則。 |
ruleset.data |
RDFグラフで、 規則集合内のデータブロックの和集合によって形成されるもの。 |
ruleset.imports |
インポートの集合で、規則集合に属するもの。 |
rule.head |
トリプルテンプレートで、規則の頭部に属するもの。 |
rule.body |
規則要素で、規則に属するもの。 |
rule.evaldata |
真偽値フラグ。falseの場合、規則の本体は、 照合されます。 その対象は、基本グラフです。 |
rule.id |
規則の識別子であり、空白ノードまたはIRIです。 |
filter.expr |
式で、フィルター 要素に属するもの。 |
assign.var |
代入変数で、代入要素に属するもの。 |
assign.expr |
代入式。 |
negation.inner |
否定要素の本体で、 否定要素に属するもの。 |
negation.evaldata |
真偽値フラグ。falseの場合、negation.innerが照合されます。
その対象は、基本グラフです。 |
aggregation.grouping |
@@ |
aggregation.pattern |
@@ |
aggregation.assignments |
@@ |
aggregation.variables |
@@ |
aggregation.functions |
@@ |
整形式性は、抽象構文に対する条件の集合であり、 規則集合を対象とします。これらの条件は、全体として次のことを保証します。 変数で、 頭部にあるものは、その規則の本体で定義された値を持つこと、 各変数が、フィルター要素 または代入式内にある場合、 評価時点で値を持つこと、 および、各 代入変数 と集約変数が、 規則内で新しいものであり、規則の本体でそれ以前に使用されていないことです。
eltiを、次の列のi番目の要素とします。 規則要素の列であり、Nをその列の 長さとします。
V0を、その列の初期変数とします。
Viを、iが 1からNまでの場合について、 変数の集合で、スコープ内にあるものとします。その時点は要素 eltiの後です。
Vallを、次の値とします。 VN。
Viを帰納的に定義します。
{ avar } ∪ Vi-1。
集約は、変数の集合を置き換えます。その対象はスコープ内の変数です。
規則要素の列は、 整形式の列です。 ただし、変数の集合V0が与えられたとき、 次の条件が各iについて満たされる場合であり、 その範囲は1からNまでです。
規則は、整形式の 規則です。 ただし、規則要素の列で、規則の本体のものが、 整形式の列であり、その開始時に V0が 空集合であり、 かつ各変数が、トリプルテンプレート内にあって、そのテンプレートが規則の頭部のものであるとき、 Vallの要素である場合です。
規則R1は、2番目の規則の出力が
最初の規則の本体の評価に影響する場合、規則R2に依存します。すなわち、R2の頭部は
トリプルテンプレートを持ち、それは、次のものに一致するトリプルを生成できます。
トリプルパターンで、R1の本体内にあり、
トリプルパターン要素として、または否定要素内、
もしくは集約パターン内にあるものです。
依存関係には2種類あります。
閉じた依存関係と開いた
依存関係です。
閉じた依存関係は、規則R2が、
規則R1の実行前に、可能な出力をすべて生成済みであることを保証します。
規則の依存関係が閉じていない場合、それは開いた依存関係です。
これは、最初の規則R1の実行を許可します。
その一方で、規則R2は、さらにトリプルを生成するために再実行される可能性があり、
それによって、R2からの新しいトリプルを用いてR1が再評価されることがあります。
フラグ.evaldataがfalseに設定された規則は、
基本グラフを使用して照合を行い、その規則には依存関係がありません。
この最初の例では、最初の規則は開いた依存関係を持ちます。 その依存先は2番目の規則です。
この2番目の例では、最初の規則は閉じた依存関係を持ちます。
その依存先は2番目の規則です。トリプルパターン?x :status :criticallyExposedは、
最初の規則の否定要素内に現れ、
2番目の規則の頭部にあるトリプルテンプレートに一致します。
最初の規則は、2番目の規則が
可能な出力をすべて生成するまで評価できません。
トリプルパターンがトリプルテンプレートに一致するのは、 そのトリプルテンプレートが生成できるトリプルが、一致する場合です。その一致先は当該トリプルパターンです。
トリプルパターンは、 依存するといいます。その依存先が トリプルテンプレートであるのは、 そのトリプルパターンが、 一致できる場合です。 その一致先は、当該トリプルテンプレートです。
規則R1は、依存
するといいます。
その依存先が規則R2であるのは、
R1.evaldataがtrueであり、いずれかのトリプル
パターンで、R1の本体内にあり、
トリプルパターン要素として現れるもの、
または
否定要素neg内にあって、
neg.evaldataがtrueであるもの、
または集約パターン内にあるものが、
依存する場合です。その依存先はトリプル
テンプレートであり、
R2の頭部にあるものです。
規則の依存関係で、規則R1から規則
R2へのものは、閉じた依存関係です。
ただし、次のいずれかの条件が成り立つ場合です。
規則の依存関係で、規則R1から規則
R2へのものは、
開いた依存関係です。ただし、その依存関係が
閉じた依存関係ではない場合です。
トリプルテンプレートが
RDF トリプル T1 を
生成できるのは、
トリプルテンプレートの変数に対する値が存在し、
テンプレート内の変数を値で置換することでトリプル T2 が得られ、
T2 が T1 と等しい場合です。
同様に、トリプルパターンがトリプル T1に 一致するのは、
その変数に適切な値が存在し、
トリプルパターン内の変数をそれらの値で置き換える際に、
空白ノードを
変数として扱うことも含めて、
パターン内の変数を置き換えた結果、トリプル T2が得られ、
T2と 等しい
T1になる場合である。
トリプル テンプレート またはトリプルパターン内で変数が複数回使用される場合、 置換には同じ RDF 項が使用されます。
トリプルパターン内の変数を RDF 項で置換することには、 トリプル項内の変数を置換することも含まれます。
ルール間の依存関係は、依存関係グラフと呼ばれる有向グラフとして表されます。 グラフの頂点はルールセットのルールであり、辺には、 依存関係が開いた依存関係か閉じた依存関係かに応じて、 open または closed のラベルが付けられます。
R1 が R2 に依存する場合にルール R1 から
ルール R2 への辺が存在する有向グラフです。
その辺には、依存関係が
開いた依存関係か閉じた依存関係かに応じて、
open または closed のラベルが付けられます。
R1 からルール R2 への経路が
依存関係グラフ内に存在する場合、
ルール R1 はルール R2 に
推移的依存関係を持ちます。
依存関係グラフはベースグラフの影響を受けません。
次のアルゴリズムは、ルールセットから依存関係 グラフを構築する方法の一例を示します。 適合性は、依存関係グラフの定義を満たす依存関係グラフを生成することに依存し、 この手順を使用することには依存しません。
define mergeLabel(oldLabel, newLabel):
# 閉じた依存関係は開いた依存関係に優先します。
if oldLabel == "open" and newLabel == "open":
the result is "open"
else:
the result is "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:
let bodyDependencies = {}
if R1.evaldata then:
# 規則内の各トリプルパターンTPを、"open"または"closed"を必要とするものとして分類します
# その分類は、否定要素内または集約
# パターン内にあるかどうかによります。
foreach rule element RBE in R1.body:
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 filter element:
# 何もしません
else if RBE is a negation element:
if RBE.evaldata then:
foreach triple pattern TP in RBE.inner:
let item be a pair (TP, "closed")
add item to bodyDependencies
endfor
endif
else if RBE is an assignment element:
# 何もしません
else if RBE is an aggregation element:
foreach triple pattern TP in RBE.pattern:
let item be a pair (TP, "closed")
add item to bodyDependencies
endfor
endif
endfor
endif
foreach pair (triple pattern TP, depLabel) in bodyDependencies:
if R1 is a run-once rule:
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
階層化は、規則集合を 順序付きの階層化の層の列に分割するプロセスです(層は 「strata」、単数形では「stratum」とも呼ばれます)。低い層の規則は、 高い層の規則より前に評価されます。
階層化は、依存関係に制約を課します。その対象は規則間の依存関係であり、 否定要素、集約要素、 および単一実行規則が依存する対象を、 先行する(低い)層を使用して計算された結果、および 基本グラフのみに限定することを保証します。 これにより、単一で明確に定義された有限の 結果が、規則集合の評価から得られることが保証されます。その評価対象は、与えられた基本グラフです。
階層化プロセスは、評価に関する他の 決定にも使用できます。この文書は、一貫した評価に 必要な条件を説明し、階層化を形成するための 可能な方法の1つを示します。実装は、互換性のある動作を得るために、 ここで説明する条件を満たす必要がありますが、 提示されたとおりにアルゴリズムを実装する必要はありません。
階層化レイヤー SL は、対をなす
互いに素な集合であり、その要素は
ルールです(SL.once, SL.general)。
SL.once は、そのレイヤーの一度だけ実行される
ルールのみからなります。
これらのルールは、それぞれ評価されます。
その回数は、階層化レイヤーの評価開始時に、ちょうど一度です。
SL.general は、そのレイヤーの残りのルールの集合であり、
新しいトリプルが推論されなくなるまで繰り返し評価されます。
階層化は、ルール集合に対する、階層化レイヤーの列です。 ルール集合内の各ルールは、いずれか 1 つの集合にちょうど一度現れます。 その集合は、いずれか 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.
foreach i = 0 to maxStratum
stratumRules.set(i, {})
endfor
# stratumMap 内で同じレベル番号を持つルールを集めます
foreach 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
層別化条件の帰結として、 一度だけ実行されるルールが評価されると、 そのルールの結果を決定するために使用されたデータは、 その後の評価中に変化しません。
完全なルールセットに対して依存関係分析と 層別化を段階的に適用し、その後評価まで追跡する例は、 6.6 実例 に示されています。
Web から文書を読み込むことには、セキュリティ上の影響がある。 ルールセットのインポートへの対応は、SPARQL-RL プロセッサーでは任意である。 さらに、実装は 任意で部分的なサポートを提供してもよく、 例えば、特定のルールセットのインポートのみをサポートし、他はサポートしないことや、 検証済みのコピーからのみインポートすることなどがある。
インポートの処理には、次の条件が適用される。
IMPORTS 文が含まれる場合、それを拒否し、
エラーを通知しなければならない。
IMPORTS 文を処理する際)。
解決済みルールセットは、別のルールセットのインポートを基に、 そこに記載されたすべてのルールセットを再帰的に読み込むことにより、 その元となる ルールセットから生成される。
アルゴリズムの例を B. インポートの例示 アルゴリズムに示す。
この節は非規範的です。
SRL と SPARQL は密接な関係にあります。SRL は互換性を持つように設計されており、 その対象は SPARQL で、SRL の多くの構成要素は、 SPARQL のパターンマッチングから取り入れられたか、着想を得たものです。ただし、いくつかの違いがあります。
SRL では、RULE 変数は使用前に常に束縛されます。使用箇所が
FILTER または SET の式である場合も、トリプルテンプレートである場合も同様です。
これらが属するのは
ルールヘッドです。SPARQL の CONSTRUCT クエリと
INSERT 更新は、
変数が CONSTRUCT または
INSERT テンプレートに現れても WHERE 節で値を与えられていない場合、部分的な結果を生成します。
SET 形式と SPARQL の BIND 形式は、
エラー処理の動作が異なります。SET で発生したエラーは、
現在の解を除外しますが、BIND は
現在の解の変数を設定せずに、その解を引き渡します。
SET(?var := expr) は、次のものと同等です。
SPARQL で
BIND(expr AS ?var) の後に
FILTER(BOUND(?var)) を続けたものです。
WHERE 節の構文には、
UNION または OPTIONAL 構文は含まれません。
これらの SPARQL 要素は、未束縛の変数を生じさせる可能性があります。
UNION または OPTIONAL の効果は、
整形式のルールを使用して実現できます。
その他の違いには、次のものがあります。
NOT の構文は、内部の本体をトリプル
パターンとフィルターに制限し、入れ子のパターンを許可しません。
NOT は、ルール本体内の記述された位置でフィルターとして
実行され、SPARQL の FILTER NOT EXISTS とは異なります。
/ と ^ を使用するパスのみを対象とします。
これらはトリプルパターンに展開できます。
任意長の演算子 * と + は許可されません。
任意長のパスは、SPARQL-RL において、
より一般的な手法として再帰を使用して表現できます。
COALESCE と BOUND はありません。ハッシュ関数もありません。
RAND もありません。これは、呼び出されるたびに結果が
異なるためです。
NOW() は許可されており、同じ時点を返すように
定義されています。この時点は、ルール集合の評価全体を通じて変わりません。
BNODE を使用すると、呼び出しごとに異なる空白ノードが生成されます。
ルール集合の評価の結果として生成される推論グラフは、
グラフ同型になります。
UUID と STRUUID は、一意な識別子を生成するために使用できます。
ルールは、これらの生成された識別子を検査せず、
トリプルの生成にのみ使用するべきです。
再現性をテストするために、専用の生成器を使用できます。
これは、NOW の結果をテストする場合と同様です。
この節では、与えられたデータに対してルールセットを評価した結果を定義する。 実装はこのアルゴリズムを使用する必要はない。 実装は同じ結果を生成する任意のアルゴリズムを使用できる。
入力: ベースグラフと呼ばれるグラフ G、およびルールセット RS。 出力: 推論されたトリプルからなる RDF グラフ GI
推論されたトリプルには、 ベースグラフに存在するトリプルは含まれない。
μ : V → Tです。
ここで、V はすべての変数の集合であり、
T はすべてのRDF
用語の集合です。
μ の定義域は、
dom(μ)で表され、
μ が定義されている V の部分集合です。
解という用語は、解写像を意味することが明らかな場合に使用できます。
μ0 は、
dom(μ0)が空集合となる解写像を表すものとします。
置換関数、または単に置換は、
次の関数です。
subst(μ, トリプルパターン)
この関数は、トリプルパターンを返します。
ここで、トリプルパターンに出現する各変数
var のうち、
dom(μ)
に含まれるものは、RDF 用語に置き換えられます。これは、
解写像が var に対して与えるものです。
結果のトリプルパターンに変数がない場合、それは
RDF トリプルです。
関数
subst(μ, トリプルテンプレート)
も同様に定義されます。各変数の出現箇所について、
トリプルテンプレート内の変数は、RDF 用語に置き換えられます。これは、
解写像が var に対して与えるものです。
replaceBlankNodes(list of トリプルテンプレート)
この関数は、
トリプルテンプレートのリストを返し、各空白ノードは、
引数内で新しい空白ノードに置き換えられます。
同じ空白ノードの複数の出現箇所は、
同じ新しい空白ノードに置き換えられます。
G をRDF グラフ、TP をトリプルパターンとします。
関数 graphMatch(G, TP) は、可能なすべての
解の集合を返します。これらの解は、
トリプルパターンに適用すると、
グラフ G 内にあるトリプルを生成します。
S1 と S2 を解とします。
compatible(μ1, μ2) = true
if forall v in dom(μ1) intersection dom(μ2)
μ1(v) = μ2(v)
compatible(μ1, μ2) = false otherwise
merge(μ1, μ2) = μ such that
μ(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)
μ = merge(μ1, μ2) }
merge(μ1, μ2)の定義域は、
domain(μ1) ∪ domain(μ2)です。
2 つの解に共通する変数がない場合、それらは互換であり、 2 つの解のマージは、 μ1 と μ2 の和集合です。
EBV(x) は、実効ブール値を返します。
対象は、RDF 用語です。
ルールセットの評価には、インポートされたすべてのルールセットを収集し、 4.5 インポートの 処理で説明されているように、単一の結合されたルールセットを構築することが含まれます。
次に、結合されたルールセットを 以下の手順で評価用に準備します。
式は、フィルター要素で使用される場合でも、 代入要素で使用される場合でも、 ソリューションマッピングに関して評価されます。 ソリューションマッピングは、式内の各変数に RDF 項の値を提供します。 4.2 整形式条件の要件により、 式内のすべての変数が ソリューションマッピングに現れることが保証されます。
define evalFunction(F, μ):
# F は式であり、RDF 項、変数、または op(expr1, ..., exprN) である。
# ここで、op は関数または関数形式である。
# μ は解マッピングである。
# 評価中にエラーが発生すると、evalFunction はエラーを返す。
if F is an error:
return error
if F is an RDF term:
return F
if F is a variable:
# 整形式性により、F ∈ dom(μ) である。
return μ(F)
# F は F = op(expr1, ..., exprN) という形式である。
if op is a functional form (e.g., IF, logical-or):
# op に固有の方法で評価される。op は一部の引数のみを評価する場合がある。
# 例えば、IF(c, t, f) は c を評価し、その後、必ず
# t または f の一方だけが評価される。
return the value defined for op over expr1, ..., exprN under μ
# op は通常の関数である。最初にすべての引数を評価する。
return op(evalFunction(expr1, μ), ..., evalFunction(exprN, μ))
enddefine
define evalAggregate(AGGF, SEQ)
@@
# AGGF は、引数として変数
# と解列を取る集約関数です。RDF 用語の値を返します。
# DISTINCT は COUNT にのみ許可されることに注意してください
# COUNT(*) は特別なケースです。
endefine
| 集約関数 | SPARQL での同等のもの |
|---|---|
COUNT |
SPARQL COUNT
で distinct を false に設定したもの |
COUNT DISTINCT |
COUNT
で distinct を true に設定したもの |
MIN |
SPARQL MIN |
MAX |
SPARQL MAX |
SUM |
SPARQL SUM |
集約関数の計算中にエラーが発生すると、 評価エラーとなり、このグループ化は結果に追加されません。
ルールは、解 列をルール本体から計算し、 次に各解写像を、その解列から使用して、 トリプルを生成することで評価されます。これにはルールヘッドを使用します。
ルール本体内では、トリプルパターン内の空白ノードは変数のように振る舞います。 これは、 SPARQL のグラフパターンマッチングと互換性があります。
# ルール本体を評価する
# この関数は解の列を返す
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
foreach rule element rElt in B:
if rElt is a triple pattern element TP:
X = graphMatch(G, TP)
SEQ1 = {}
foreach μ1 in X:
foreach μ2 in SEQ:
if compatible(μ1, μ2):
μ3 = merge(μ1, μ2)
add μ3 to SEQ1
endif
endfor
endfor
endif
if rElt is a filter element F:
SEQ1 = {}
foreach solution μ in SEQ:
let x = evalFunction(F.expr, μ)
if x is not an error and EBV(x) is true:
add μ to SEQ1
endif
endfor
endif
if rElt is a negation element N:
SEQ1 = {}
foreach solution μ in SEQ:
S = sequence{ μ }
if N.evaldata:
NEG = evalRuleElements(N.inner, S, G, GD)
else:
NEG = evalRuleElements(N.inner, S, GD, GD)
endif
if NEG is empty:
add μ to SEQ1
endif
endfor
endif
if rElt is an assignment element A:
SEQ1 = {}
foreach solution μ in SEQ:
let x = evalFunction(A.expr, μ)
if x is not an error:
# 写像 A.var -> x を解 μ に追加する
let μ2 be a solution mapping μ ∪ { (A.var, x) }
add μ2 to SEQ1
else:
# エラー: 解 μ を破棄する
endif
endfor
endif
## COUNT(*) はどうするか?
if rElt is an aggregation element AGG:
let SEQX = evalRuleElements(AGG.pattern, SEQ, G, GD)
let KGRP = empty map of solution mappings to solution sequences
# 解写像をグループに割り当てる。
foreach solution μx in SEQX:
let μk be μx restricted to AGG.grouping
if KGRP[μk] is defined:
Add μx to the solution sequence KGRP[μk]
else:
KGRP[μk] = solution sequence of one element μx
endif
endfor
# 各グループについて、集約関数を計算し、
# グループキーと
# 集約代入の結果を含む解写像を作成する。
let SEQ1 be an empty solution sequence
foreach key K of map KGRP:
let X be solution sequence of KGRP[K]
let Z be an empty solution mapping
foreach aggregation function F in AGG.assignments:
let V = calculate F.function(X)
add solution mapping (F.var, V) to Z
endfor
Z = merge(Z, K)
add Z to SEQ1
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
treating blank nodes as variables.
# どの変数も写像しない 1 つの解からなる解列。
let SEQ0: Solution sequence = { μ0 }
if R.evaldata:
let SEQ = evalRuleElements(B, SEQ0, G, GD)
else:
let SEQ = evalRuleElements(B, SEQ0, GD, GD)
endif
# ルールヘッドを評価する
let OUT = empty set
foreach μ in SEQ:
let S = {}
# 各空白ノードを新しい空白ノードに置き換えたルールヘッド
let HT = replaceBlankNodes(R.head)
foreach triple template TT in HT
let triple = subst(μ, TT)
Add triple to S
endfor
OUT = OUT ∪ S
endfor
return OUT
enddefine
OUT は、基底グラフにも存在するトリプルを含む場合があります。
ルールセットの評価は、そのルールセットの各 層を実行することとして定義される。 層化において、各層は 完全に実行され、 次の 層に進む前に、順番に処理される。 層は、まず その層の各 一度だけ実行されるルールを評価し、続いて 一般ルールを新しいトリプルが生成されなくなるまで繰り返し 評価することによって評価される。
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
# 推論グラフ
let GI = { t ∈ D | t ∉ G0 }
# 評価グラフとデータブロック
let GE = G0 ∪ D
foreach stratum ST in LS:
foreach 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
foreach 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
この節は非規範的です。
この節では、完全なルールセットの評価を段階的に説明します。ルールの依存関係を決定し (4.3 ルールの 依存関係)、 層別化を計算し (4.4 層別化)、 各層を順に評価して 推論グラフを生成します (6.5 ルールセットの 評価)。
この例では、ソフトウェアコンポーネントとその依存関係について説明します。
フロントエンドはアプリケーションサーバーに依存し、そのアプリケーションサーバーは
データベースとロギングライブラリに依存します。データベースには既知の
脆弱性があります。ルールは、依存関係チェーンに沿って脆弱性への露出を伝播させ、
深刻な脆弱性にさらされているコンポーネントに
:criticallyExposed というステータスを与え、重大ではないコンポーネントには
:safeToDeploy というステータスを与え、重大な脆弱性にさらされている各コンポーネントについて
通知を作成します。
(実際には、脆弱性がコンポーネントに影響するかどうかは
デプロイされているバージョンによって異なります。この例ではバージョンを省略し、
脆弱性を直接記述しています。)
簡潔にするため、ベースグラフでは、
3.1 トリプル
パターンのようにより具体的な関係から導出するのではなく、
:dependsOn トリプルを直接記述しています。
ルールにはコメント内で R1 から R5 のラベルが付けられており、
この節の残りではこれらのラベルを使用して参照します。
これらは、
3.2 再帰から
3.5 代入
と RDF 項の作成までで導入されたルールです。
ルールセットには IMPORTS がないため、インポート処理では
変更されず、DATA ブロックもないため、評価は
ベースグラフのみから開始します。
各ルールボディ内の各トリプルパターンを、 すべてのルールヘッド内のトリプルテンプレートと比較して、 どのルールがどのルールに依存するかを決定します (4.3 ルールの 依存関係)。
R1 のボディは単一のトリプルパターン
?x :hasVulnerability ?v です。述語 :hasVulnerability を持つ
トリプルを生成できるトリプルテンプレートを持つルールヘッドはないため、
このパターンはデータにのみ一致できます。
R1 には依存関係がありません。
R2 のボディには 2 つのトリプルパターンがあります。
?x :dependsOn ?y はどのルールヘッドにも一致できないため、
データにのみ一致します。?y :exposedTo ?v は
R1 のヘッドテンプレート ?x :exposedTo ?v と一致し、
R2 自身のヘッドにも一致します。
どちらもトリプルパターン要素であり、
(否定要素内には現れず、
R2 は
一度だけ実行されるルールでもないため)、
R2 は R1 に対して開いた依存関係を持ち、
自身に対しても開いた依存関係を持ちます。
R2 の自身に対する依存関係により、R2 は再帰的ルールになります。
R3 のボディでは、パターン ?x :exposedTo ?v が
R1 と R2 のヘッドに一致するため、
R3 はそれぞれに対して開いた依存関係を持ちます。
パターン ?v :severity ?s はどのルールヘッドにも一致しません。
R4 のボディでは、パターン ?x rdf:type :Component は
どのルールヘッドにも一致しません。述語 rdf:type を持つ唯一のヘッドテンプレートは
R5 にあり、そのオブジェクト :Notification は
:Component とは異なる RDF 項なので、生成された
トリプルが一致することはありません。
パターン ?x :status :criticallyExposed は、
否定要素
NOT { ?x :status :criticallyExposed } 内に現れ、
R3 のヘッドテンプレートと一致します。このパターンは
否定要素内に現れるため、R4 は R3 に対して
閉じた依存関係を持ちます。
R5 のボディでは、パターン ?x :status :criticallyExposed が
R3 のヘッドに一致します。R5 のヘッドには
空白ノードが含まれているため、R3 への依存関係は、
パターンが通常のトリプルパターン要素であっても、
閉じた依存関係です。
どのルールボディ内のパターンも R5 のヘッドテンプレートには一致しないため、
R5 に依存するルールはありません。
したがって、依存関係グラフには 5 つの頂点と 6 つの 辺があります。
R2 → R1 (open)
R2 → R2 (open)
R3 → R1 (open)
R3 → R2 (open)
R4 → R3 (closed)
R5 → R3 (closed)
R4 と R5 は R1 または
R2 に直接依存していませんが、それぞれ R3 を介して両方に
推移的依存関係を持ちます。
グラフ内の唯一の循環は自己辺 R2 → R2 であり、
これは開いた依存関係です。閉じた依存関係を含む循環はないため、
層別化条件は
満たされ、
ルールセットには明確に定義された結果があります。
層別化アルゴリズムに従い、 すべてのルールは層 0 から開始します。その後、変化がなくなるまで 辺を繰り返し調べます。
R4 → R3
(closed) では、R4 と R3 がどちらも層 0 にあるため、
R4 は層 1 に移動します。同様に、辺 R5 → R3
(closed) により R5 も層 1 に移動します。
さらに辺を一巡しても変更は生じないため、層は確定します。
次に各層を一度だけ実行されるルールと一般ルールに分割します。
R5 はヘッドに空白
ノードを持つため、一度だけ実行されるルールです。
ルールセット内の他のルールはいずれも一度だけ実行されるルールではありません。
層別化は次のとおりです。
R1、R2、R3。一度だけ実行されるルールはなしR5。一般ルール R4
この順序付けは、より高い層にあるルールの意図を反映しています。
コンポーネントを安全にデプロイできるかどうか、および
どのコンポーネントに通知が必要かは、
すべての :status :criticallyExposed トリプルが導出された後でのみ決定できます。
そして、それらを導出するルール R3 は、
それに入力を与えるルール R1 および R2 とともに
その下の層で完了します。
評価は、
6.5 ルールセットの
評価のアルゴリズムに従います。
評価グラフ GE はベースグラフとして開始し、
推論グラフ GI は空で開始します。各層は順番に完了まで評価されます。
層内のルールはパスごとに評価され、
新しいトリプルを生成しないパスになるまでパスを繰り返します。
このアルゴリズムでは、パス内で層のルールを評価する順序は
規定されていません。この追跡では
R1、R2、R3 の順序を使用します。
異なる順序では、同じ推論が異なる数のパスに分散する可能性がありますが、
層 0 は完了まで実行されるため、最終的には同じグラフが生成されます。
このルールセットには DATA ブロックがないため、評価中のすべての時点で
GE は G0 と GI の和集合です。したがって、この追跡では
GI のみを追跡し、評価の進行に伴う状態を示すとともに、
各新しいトリプルに、それを生成したルールを示します。
層 0、第 1 パス。
R1: ボディは
:db :hasVulnerability :vuln1 に一致し、
?x = :db および ?v = :vuln1 を束縛します。
ヘッドは :db :exposedTo :vuln1 を生成します。
このトリプルは GE にないため、GE と GI に追加されます。
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 :vuln1 が GE に存在しなかったためです。
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、一度だけ実行されるルール。 この層の一度だけ実行されるルールが最初に評価され、 それぞれ正確に一度だけ実行されます。
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 トリプル集合を参照できるため、
各層内でルールが評価される順序が
最終結果に影響しません。
SPARQL-RL 文書
は、RDF 文字列であり、UTF-8 [RFC3629]
で符号化され、
RuleSet
生成規則から始まり、次で定義されている追加の制約に適合します。
7.6 文法。
Unicode スカラー値のみが、
U+0000 から U+D7FF の範囲
および U+E000 から U+10FFFF の範囲で
許可されます。これにより、
サロゲートコードポイントの、
U+D800 から U+DFFF の範囲が除外されます。
バージョンラベルは、SPARQL-RL の構文および意味論への 適合性を識別する文字列です。
| バージョンラベル |
|---|
| "1.2" |
バージョン宣言は、文書の早い段階で行うべきです。
複数の VERSION ディレクティブが
SPARQL-RL 文書に現れる場合があります。
各ディレクティブは、そのディレクティブに続く文書の部分に適用され、
別のディレクティブが現れるか、文書の末尾に達するまで有効です。
バージョンラベルは、version
パラメーターによっても指定できます。
メディアタイプの。現在有効な
VERSION ディレクティブがない場合は、
メディアタイプの一部として指定されたバージョンが考慮されます。
空白文字
(生成規則 WS) は、
そうしなければ誤って1つの終端記号として認識される
2つの終端記号を分離するために使用される。
以下の大文字で表記された規則名は、空白文字が
重要となる箇所を示す。これらは、
SPARQL-RL パーサーを構築するための終端記号の選択肢の1つとなる。
次の生成規則では空白が意味を持ちます。
String。
コメントは、次の外側にある # で始まります。
IRIREF、
STRING_LITERAL1、
STRING_LITERAL2、
STRING_LITERAL_LONG1、または
STRING_LITERAL_LONG2、
そして行末(次によって示される)まで続きます。
LF、または
CR)、
または、コメントマーカーの後に行末がない場合はファイルの末尾まで続きます。
コメントは空白として扱われます。
相対 IRI 参照はベース IRI を使用し、Uniform Resource Identifier (URI): 汎用 構文 [RFC3986] に従い、 5.2 節の基本アルゴリズムのみを使用して解決されます。 構文ベースの正規化もスキームベースの正規化も (RFC3986 の 6.2.2 節および 6.2.3 節で説明されています)実行されません。 IRI 参照で追加で許可される文字は、 URI 参照における非予約文字と同じ方法で、国際化リソース識別子 (IRI) [RFC3987] の 6.5 節に従って扱われます。
BASE
ディレクティブは、次を解決するために使用されるベース IRI を定義します。
相対 IRI 参照を、[RFC3986] の
5.1.1 節「ベース URI の
コンテンツへの埋め込み」に従って解決します。
5.1.2 節「カプセル化する
エンティティからのベース URI」
は、有効範囲内のベース IRI がカプセル化文書からどのように得られるかを定義します。
たとえば、xml:base ディレクティブを持つ SOAP エンベロープや、MIME マルチパート文書の
Content-Location ヘッダーです。
5.1.3 節「取得 URI からのベース
URI」で特定される「取得 URI」は、
特定のSPARQL-RL 文書が取得された URL です。
上記のいずれもベース URI を指定していない場合は、デフォルトの
ベース URI(5.1.4 節「デフォルトのベース URI」)が
使用されます。
各 BASE ディレクティブは、新しい有効範囲内のベース URI を設定し、
直前のものを基準とします。
SPARQL-RL 文書では 3 種類のエスケープが使用されます。
数値エスケープシーケンスは、 Unicode コードポイントの値を表します。
数値エスケープシーケンスは、
生成してはなりません。コードポイント値が
U+D800 から U+DFFF の範囲にある場合、
これは
Unicode のサロゲートの範囲です。
| エスケープシーケンス | Unicode コードポイント |
|---|---|
\u hex
hex
hex
hex
|
Unicode コードポイント
U+0000 から U+D7FF の範囲
および U+E000 から U+FFFF
の範囲にあり、
4 桁の 16 進数字を解釈して符号化された値に対応し、
最上位桁から最下位桁の順に解釈されます。
|
\U hex
hex
hex
hex
hex
hex
hex
hex
|
Unicode コードポイント
U+0000 から
U+D7FF の範囲
および U+E000 から U+10FFFF
の範囲にあり、
8 桁の 16 進数字で符号化された値に対応し、
最上位桁から最下位桁の順に解釈されます。
|
ここで hex は 16 進文字です
HEX ::= [0-9] | [A-F] | [a-f]
文字列エスケープシーケンスは、文字列リテラルで従来 エスケープされている文字を表します。
| エスケープシーケンス | Unicode コードポイント |
|---|---|
\t |
U+0009 |
\b |
U+0008 |
\n |
U+000A |
\r |
U+000D |
\f |
U+000C |
\" |
U+0022 |
\' |
U+0027 |
\\ |
U+005C |
予約文字エスケープシーケンスは、
\の後に、
~.-!$&'()*+,;=/?#@%_ のいずれかの文字が続くものであり、
次の右側にある文字を表します。
\。
| 数値 エスケープ |
文字列 エスケープ |
予約文字 エスケープ |
|
|---|---|---|---|
IRI、
RDF 項として使用されるもの、
PREFIX、
または BASE 宣言
|
はい | いいえ | いいえ |
| ローカル名 | いいえ | いいえ | はい |
| 文字列 | はい | はい | いいえ |
% エンコードされたシーケンスは、
IRI の文字範囲に含まれ、
ローカル名でも明示的に許可されています。
これらは、%の後に
2 つの 16 進文字が続く形式で現れ、
同じ 3 文字のシーケンスを表します。これらのシーケンスはデコードされません
処理中には。
<http://a.example/%66oo-bar> と記述された項は、
IRI http://a.example/%66oo-bar を示し、
IRI http://a.example/foo-bar を示すものではありません。
接頭辞を伴って ex:%66oo-bar と記述された項は、
PREFIX ex: <http://a.example/>
同様に IRI http://a.example/%66oo-bar を示します。
ここで使用する EBNF は XML 1.0 で定義されています。 [EBNF-NOTATION]。
注記:
[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
|
[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 ')'
|
終端記号の生成規則:
[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 |
::= | '\' ( '_' | '~' | '.' | '-' | '!' | '$' | '&' | "'" | '(' | ')' | '*' | '+' | ',' | ';' | '=' | '/' | '?' | '#' | '@' | '%' )
|
この文法のテキスト版は、 "sparql-rl-grammar.bnfで入手できる。
この文書では、いくつかの終端記号のリテラル文字列を使用する [EBNF-NOTATION]。使用される Unicode コードポイントを明確にするため、 これらの 終端記号のリテラル文字列について、次の表で使用される具体的な 文字を示す。
| コード | グリフ | 説明 |
|---|---|---|
U+000A |
LF |
改行 |
U+000D |
CR |
復帰 |
U+0023 |
# |
番号記号 |
U+0025 |
% |
パーセント記号 |
U+005C |
\ |
バックスラッシュ |
この節は非規範的である。
次のアルゴリズムは、参照されるすべての文書を再帰的に
訪問することで IMPORTS 文を解決する方法の一例を示す。
2つのルールセットの ルールセットのマージは、RS1 と RS2 について、
次のように定義されるルールセット MR を生成する。
let RS be a rule set
let V = {}
if RS has a location:
V = { location of RS }
endif
define ruleSetMerge(rule set RS1, rule set RS2):
let MR be a rule set
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):
let RS2 be a rule set formed from RS.rules and RS.data
foreach URL x in RS.imports:
if x ∉ V:
V = V ∪ { x }
read rule set RS3 from URL x
RS2 = ruleSetMerge(RS2, imports(RS3))
endif
endfor
the result is RS2
enddefine
result is imports(RS)
ここで、rdf_merge は
RDF
マージ
演算である。
SPARQL-RL のインターネットメディアタイプ(旧称 MIME タイプ)は
"application/sparql-rl" である。
以下の情報は、審査、承認、および IANA への登録のために Internet Engineering Steering Group(IESG)に提出されている。
この節は非規範的である。
SPARQL-RL 文書には、他の
SPARQL-RL 文書を参照し、その内容を現在の
文書にインポートする IMPORTS 文が含まれる場合がある。
インポートされた文書自体に IMPORTS 文が含まれている場合、
それらの文書もインポートされる。
ルールセットのモジュール化には有用であるが、IMPORTS 文の使用は
セキュリティリスクをもたらす可能性がある。
リスクには、悪意によるものか偶発的なものかを問わず、ルールセットが
評価中に過剰な計算を引き起こすことや、
HTTP リクエストが傍受され、古いコピーを含む
別の文書が返されることなどが含まれるが、これらに限定されない。
SPARQL-RL ルールセットを RDF グラフに適用すると、 大量の計算処理やメモリー使用が発生する可能性があり、これが悪用されて サービス拒否を引き起こすおそれがある。 アプリケーションは、SPARQL-RL ルールセットの適用によって発生する 計算量とメモリー使用量を制限するよう注意するべきである。
SPARQL-RL 構文は UTF-8 [RFC3629] で符号化され、 文字列データ内で エスケープされていない制御文字の使用を許容する。 この仕様はその内容をエンドユーザーに直接公開しないが、 ユーザーエージェントを通じて表示される場合があり、そのような文字によって 表示されるテキストが誤解を招くものになる可能性がある。
SPARQL-RL は、任意のアプリケーションデータの処理と作成に使用できる。 セキュリティに関する考慮事項は、使用分野によって異なる。 テキストに適用できるセキュリティツールやプロトコル (例えば、PGP 暗号化、チェックサム検証、パスワード保護された圧縮)は、 SPARQL-RL 文書にも使用できる。 SPARQL-RL ルールセットの評価結果に含まれる情報の機密性に応じて、 セキュリティおよびプライバシーのプロトコルを適用しなければならない。
SPARQL-RL のセキュリティに関する考慮事項には、 RDF データや、 RDF Turtleなどの形式に関するものも含まれる。
この節は非規範的である。
SPARQL-RL 文書には、追加のアプリケーションデータが含まれる場合があり、 その中には個人を特定できる情報(PII)や、 その他の機密性が高いと見なされる情報が含まれる可能性がある。 このような情報を含むルールセットを公開する著者には、 そのような情報を公開する必要性や用途、 および、そのデータが利用され、場合によっては開示されると 想定される地域に適用される規制(例えば、 GDPR、 CCPA、 その他)を慎重に検討することが推奨される。 特に、そのデータへのアクセスに認可措置が必要かどうかを検討するべきである。
この節は非規範的である。
以下の人々は、Data Shapes ワーキンググループの ルールタスクフォースにおいて SPARQL-RL の開発に貢献した。 Robert David, David Habgood, Livio Robaldo, Ognjen Savkovic, Simon Steyskal, Ted Thibodeau Jr, and Andy Seaborne.
Data Shapes ワーキンググループのメンバーには @@ が含まれる。
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: