Copyright © 2025-2026 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
이 문서는 SHACL 규칙을 정의합니다.
SHACL, 즉 Shapes Constraint Language는 RDF 그래프의 구조를 설명하기 위한 언어입니다. SHACL은 검증, 추론, 도메인 모델링, 다른 에이전트에 정보를 제공하기 위한 온톨로지 생성, 사용자 인터페이스 구축, 코드 생성, 데이터 통합 등 다양한 목적으로 사용될 수 있습니다.
SHACL 규칙은 규칙 집합과 기본 데이터 그래프의 조합으로부터 새로운 RDF 데이터를 생성하여 추론을 제공합니다. 규칙은 RDF 또는 Shape Rules Language(SRL)로 표현될 수 있습니다.
이 명세는 Data Shapes 워킹 그룹에서 발행합니다.
이 절은 발행 당시 이 문서의 상태를 설명합니다. 현재 W3C 발행물 목록과 이 기술 보고서의 최신 개정판은 W3C 표준 및 초안 색인에서 확인할 수 있습니다.
이 문서는 Data Shapes 워킹 그룹에서 Recommendation 트랙을 사용하여 작업 초안으로 발행했습니다.
작업 초안으로 발행되었다고 해서 W3C 및 그 회원들의 승인을 의미하지는 않습니다.
이 문서는 초안 문서이며 언제든지 다른 문서에 의해 갱신, 대체 또는 폐기될 수 있습니다. 이 문서를 진행 중인 작업 이외의 것으로 인용하는 것은 적절하지 않습니다. 향후 이 예정된 Recommendation의 업데이트에는 새 기능이 포함될 수 있습니다.
이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성했습니다. W3C는 해당 그룹의 산출물과 관련하여 이루어진 모든 특허 공개의 공개 목록을 유지하며, 해당 페이지에는 특허 공개를 위한 지침도 포함되어 있습니다. 개인이 필수 청구항을 포함한다고 믿는 특허에 대해 실제 지식을 가지고 있는 경우, 그 개인은 Essential Claim(s)에 대한 정보를 W3C 특허 정책 제6절에 따라 공개해야 합니다.
이 문서는 2025년 8월 18일 W3C Process Document의 적용을 받습니다.
이 명세는 SHACL 1.2 명세 제품군의 일부입니다. 더 자세한 소개는 SHACL 1.2 개요를 참조하십시오.
명세는 다음과 같습니다:
작업 초안:
워킹 그룹 노트 초안:
구현자는 위 명세에 대한 자신의 적합성 수준을 SHACL 1.2 테스트 스위트의 테스트 케이스를 성공적으로 통과함으로써 부분적으로 확인할 수 있습니다. 그러나 테스트 스위트의 모든 테스트를 통과한다고 해서 해당 명세에 대한 완전한 적합성을 의미하지는 않는다는 점에 유의하십시오. 이는 구현이 테스트 스위트에서 테스트한 측면에 적합하다는 것만을 의미합니다.
이 문서는 선언적 규칙을 통해 기존 RDF 데이터에서 새로운 RDF 트리플을 도출하는 메커니즘인 SHACL 1.2의 추론 규칙을 소개합니다. 이 문서는 규칙 기반 추론의 구문과 의미론을 정의합니다.
SHACL Rules의 구현은 두 가지 작업을 제공합니다. infer 작업은 주어진 기본 그래프에 규칙을 적용하고 규칙 실행으로 도출된 RDF 트리플을 포함하는 추론 그래프를 생성합니다. 추론 그래프를 기본 그래프와 결합하는 것은 선택 사항이며 사용자에게 맡겨집니다. query 작업은 주어진 목표 패턴이 규칙을 사용하여 기본 그래프로부터 도출될 수 있는지를 판정합니다.
SHACL Rules는 규칙의 머리부에 있는 트리플 템플릿에서 사용할 수 있는 빈 노드를 포함하여 새로운 RDF 용어의 사용을 허용합니다.
SHACL Rules는 또한 실패로서의 부정과 같은 구조를 지원하며, 이러한 구조는 규칙이 실행되는 순서에 따라 서로 다른 추론 그래프로 이어질 수 있습니다. 이를 피하기 위해 규칙은 계층화 기법을 사용하여 평가되며, 이는 규칙 간에 단일한 암묵적 순서를 설정하여 항상 동일한 추론 그래프가 생성되도록 보장합니다.
다음의 다른 명세들은 이 문서에서 사용되는 기본 용어를 제공합니다:
이 문서의 일부 예제는 RDF 1.2 Turtle [RDF12-TURTLE]을 사용합니다.
이 문서 전체에서 다음 네임스페이스 접두사 바인딩이 사용됩니다:
| 접두사 | 네임스페이스 |
|---|---|
rdf: |
http://www.w3.org/1999/02/22-rdf-syntax-ns# |
rdfs: |
http://www.w3.org/2000/01/rdf-schema# |
srl: |
http://www.w3.org/ns/shacl-rules# |
xsd: |
http://www.w3.org/2001/XMLSchema# |
sparql: |
http://www.w3.org/ns/sparql# |
ex: |
http://example.com/ |
문서 전체에서 Turtle의 RDF 그래프를 포함하는 색상 코드 상자가 나타납니다. 이러한 Turtle 문서 조각은 위에 제공된 접두사 바인딩을 사용합니다.
재설정. 적절한 곳에서는 reSpec 기본 모양을 사용합니다.
# This box represents rules
# This box represents input data
# This box represents inferred data
비규범으로 표시된 절뿐 아니라, 이 명세의 모든 작성 지침, 도표, 예제 및 참고는 비규범입니다. 이 명세의 그 밖의 모든 내용은 규범입니다.
이 문서에서 핵심 단어 MUST NOT 및 SHOULD는 여기에 표시된 것처럼 모두 대문자로 나타나는 경우에만, BCP 14 [RFC2119] [RFC8174]에 설명된 대로 해석되어야 합니다.
이 명세는 다음에 대한 적합성 기준을 정의합니다:
적합한
Shape Rules
Language 문서는
RDF
문자열이며,
RuleSet
생성 규칙에서 시작하는 문법에 적합하고,
7. Shape Rules Language
문법에 정의된 추가 제약을 따라야 합니다.
이 명세는 SHACL Rules 처리기가 적합하지 않은 규칙 집합을 처리하는 방법을 정의하지 않습니다.
버전 레이블은 Shape Rules Language에 대한 구문 및 의미론 적합성을 식별하는 문자열입니다.
| 버전 레이블 |
|---|
| "1.2" |
버전 선언은 문서의 앞부분에서 이루어지는 것이 SHOULD입니다.
하나의 Shape Rules Language 문서에는 여러 버전 지시문이 나타날 수 있습니다. 각 지시문은 해당 지시문 뒤의 문서 부분에 적용되며, 다른 지시문이 나타나거나 문서의 끝에 도달할 때까지 적용됩니다.
버전 레이블은
미디어 유형의 version
매개변수로도 제공될 수 있습니다. 현재 버전 지시문이 없는 경우에는
미디어 유형의 일부로 지정된 버전이 고려됩니다.
이 절은 비규범입니다.
SHACL 규칙은 기본 그래프와 규칙 집합이 주어졌을 때 새로운 트리플을 추론합니다. 평가의 출력은 기본 그래프에 나타나지 않는 도출된 트리플을 포함하는 추론 그래프입니다.
각 규칙은 본문이라고 하는 패턴과, 머리부라고 하는 결과 템플릿을 가집니다. 규칙은 본문 안의 변수 값들을 찾아 실행되며, 이때 본문은 결합된 기본 그래프 및 지금까지의 실행에서 나온 모든 추론 트리플과 일치해야 합니다. 그런 다음 이러한 값은 규칙 머리부의 트리플 템플릿을 인스턴스화하는 데 사용되어 새로운 추론 트리플을 생성합니다.
규칙은 더 이상 트리플이 추론되지 않을 때까지 실행되며, 새로운 추론 트리플을 사용할 수 있게 되면 규칙이 두 번 이상 실행될 수 있습니다.
SHACL Rules 실행은 새로운 빈 노드를 포함한 새로운 RDF 용어를 만들 때나 패턴의 부재를 테스트할 때, 규칙 실행 순서가 서로 다른 결과를 초래하지 않도록 정의됩니다. 즉, 규칙 실행 순서와 관계없이 동일한 추론 그래프가 생성됩니다.
SHACL Rules에는 RDF 구문뿐 아니라 SPARQL 1.2 Query Language에서 영감을 받은 사람이 읽기 쉬운 구문도 있습니다. 규칙 집합 평가는 SPARQL과 유사한 요소를 포함하지만, 규칙 실행 순서와 관계없이 동일한 추론 그래프가 생성되도록 하기 위해 세부 사항에서 차이가 있습니다.
이 첫 번째 예제에는 다음 데이터 그래프와 규칙 집합이 있습니다:
위의 규칙을 데이터에 적용하면
:X가 :A와 :B의 :childOf임을
결론짓습니다:
그런 다음 다른 규칙이 생성한 :childOf 트리플에 의존하는 규칙을
추가하여 :descendedFrom 관계를 도출할 수 있습니다:
:descendedFrom 트리플에 의존하는 규칙을 추가하여
:X가 :C의 :descendedFrom임을 추론할 수 있습니다:
이것은 :X :descendedFrom :C 트리플을 추가합니다.
이 마지막 규칙은 재귀 규칙이며, 규칙의 본문은 규칙의 머리부에 의존합니다.
규칙 본문에서 표현식을 사용하여 본문의 일치에서 변수 값을 제한할 수 있습니다. 예를 들어, 마을과 그 인구에 대한 데이터가 주어졌을 때, 인구가 1500보다 큰 마을에 대한 클래스를 추론할 수 있습니다:
FILTER는 표현식을 평가하고 표현식이 true로 평가되면 현재
변수 바인딩 집합을 유지하며, 표현식이 false로 평가되면 현재 변수
바인딩 집합을 폐기합니다.
이는
SPARQL의 FILTER 작업과
동일하며, SHACL Rules는 SPARQL과 동일한 많은 함수와 연산자를 제공합니다.
부정은 일치해서는 안 되는 패턴을 지정할 수 있게 합니다. 이를 "실패로서의 부정"이라고 합니다.
부정 요소를 평가하기 위해 규칙 평가 알고리즘은 부정 요소의 패턴과 일치하는 트리플을 생성할 수 있는 모든 규칙이 완료되었는지 보장합니다. 이를 계층화라고 하며, 부정이 데이터에서 온 것이든 다른 규칙이 추론한 추론 트리플에서 온 것이든 모든 관련 가능한 트리플에 기반하도록 보장합니다.
할당은 규칙 본문에서 표현식의 결과를 변수에 할당할 수 있게 합니다. 이는 데이터를 기반으로 새로운 RDF 용어를 생성하는 데 사용할 수 있습니다.
빈 노드는 규칙 머리부에서 사용할 수 있으며, 규칙 평가가 트리플을 생성할 때마다 각각 새 빈 노드를 생성합니다.
할당을 포함하는 규칙과 규칙 머리부에서 빈 노드를 생성하는 규칙은 한 번만 실행되는 규칙입니다. 이러한 규칙은 자신이 의존하는 데이터를 생성할 수 있는 모든 규칙이 실행된 뒤, 그리고 자신이 생성하는 데이터에 의존하는 모든 규칙보다 먼저 실행됩니다. 규칙 머리부에 빈 노드를 포함하는 규칙도 새로운 RDF 용어를 생성하며 한 번만 실행되는 규칙입니다.
이 조건은 RDF 용어를 생성하는 규칙이 잠재적으로 서로 다른 결과로 새로운 용어를 여러 번 생성하지 않도록 하고, 또한 그러한 규칙이 자신에게 되돌아가 무한한 수의 RDF 용어를 발생시키지 않도록 보장합니다.
SHACL 규칙 집합은 규칙 집합의 규칙 가져오기에 다른 규칙 집합의 URL을 포함함으로써 다른 규칙 집합을 통합할 수 있습니다. 이를 통해 규칙을 규칙 집합 간에 공유되는 라이브러리로 구조화할 수 있습니다.
규칙 집합의 IMPORTS 문은 규칙 집합의 어떤 규칙도 평가되기 전에 처리됩니다.
가져오기 단계에서 가져온 규칙 집합이 자체 가져오기를 가지고 있는 경우,
그것들도 재귀적으로 처리됩니다.
규칙 집합을 처리하는 동안 IMPORTS 문을 순회하면
순환 가져오기가 발생할 수 있습니다. 규칙 집합은 한 번만 가져옵니다.
가져오기 문 그래프의 순환은 무한 루프로 이어지지 않습니다.
데이터 블록은 규칙 집합 평가에 직접 RDF 트리플을 간결하게 제공할 수 있게 합니다. 데이터 블록의 트리플은 추론 그래프에 추가되며 규칙 본문의 일치에 사용할 수 있습니다.
@@예제가 업데이트될 예정
규칙은 규칙 집합으로 구성됩니다. 규칙 집합과 데이터 그래프(기본 그래프)는 평가의 입력입니다. 출력은 추론 그래프라고 하는 그래프이며, 여기서 추론된 트리플은 데이터 그래프에 나타나지 않습니다.
평가 중에는 한 규칙을 기반으로 추론된 트리플이 다른 규칙에서의 일치에 사용할 수 있습니다. 규칙 집합 평가는 추론 그래프가 규칙 집합과 데이터 그래프의 입력으로부터 가능한 모든 트리플을 포함할 때까지 진행됩니다.
평가는 규칙 자체가 평가되기 전에 규칙 집합을 준비하기 위한 두 단계로 시작됩니다:
규칙 집합이 준비되면, 평가는 계층화에서 각 층을 순서대로 가져와 그 층의 규칙을 완료될 때까지 평가하고, 그런 다음 다음 층으로 이동하는 방식으로 진행됩니다.
이 절은 비규범입니다.
SHACL Rules와 SPARQL은 밀접한 관계가 있습니다. SHACL Rules는 SPARQL과 호환되도록 설계되었으며, SHACL Rules의 많은 구조는 SPARQL에서 영감을 받았습니다. 그러나 몇 가지 차이가 있습니다:
CONSTRUCT 쿼리와 유사하지만,
OPTIONAL이 없는 것과 같은 제한이 있습니다.
이러한 제한은 변수가 항상 바인딩되도록 보장하는 반면, SPARQL에서는 일부
변수가 모든 패턴 해에서 바인딩되지 않을 수 있습니다.
SET 형식과 SPARQL BIND 형식은 오류 처리
동작이 다릅니다. SET에서 오류가 발생하면 현재 해가 필터링되어
제외되는 반면, BIND는 현재 해에서 변수를 설정하지 않습니다.
SET(?var := expr)는
BIND(expr AS ?var) 뒤에
FILTER(BOUND(?var))가 오는 SPARQL과 같습니다.
NOT은 SPARQL EXISTS 및 NOT EXISTS와 달리
본문이 트리플 패턴과 필터로 제한됩니다.
중첩 패턴을 허용하지 않습니다.
* 및 +는 허용하지 않습니다.
COALESCE도, BOUND도 없습니다.
해시 함수도 없습니다.
호출될 때마다 다른 결과를 내는 RAND도 없습니다.
NOW()는 허용되며, SPARQL의 동작과 유사하게
규칙 집합 평가 전체에서 동일한 시점을 반환하도록 정의됩니다.
위험 요소:
규칙 튜플은 트리플과 서로소입니다. 이들은 RDF 용어의 튜플(변수 없음)이며 규칙 집합의 평가 중에만 존재합니다. 규칙 평가 중 중간 결과를 기록하고 규칙 간에 데이터를 전달하는 데 사용할 수 있습니다.
튜플 패턴, 템플릿 및 튜플의 구문:
TUPLE(termOrVar , ...)$(termOrVar , ...)종종 첫 번째 인수는 고정된 이름이 됩니다.
평가의 수명 동안 튜플을 보관하는 튜플 저장소가 있습니다. 튜플 저장소는 중복 데이터 튜플을 보관합니다(집합인 RDF 그래프와 달리).
Shape Rules 추상 구문은 SHACL Rules의 논리적 구조입니다. 이는 SHACL Rules의 실행 알고리즘을 정의하는 데 사용됩니다. SHACL Rules의 두 가지 구체 구문 형식인 Shape Rules Language(SRL)와 RDF 구문(SRL/RDF)은 각각 추상 구문을 표현하는 방법을 제공합니다.
트리플 패턴 또는 트리플 템플릿에서, 튜플의 위치 1은 비공식적으로 주어, 위치 2는 비공식적으로 술어, 그리고 위치 3은 비공식적으로 목적어라고 불립니다.
규칙 요소 시퀀스의 요소에는 1부터 시작하는 레이블이 붙습니다.
올바른 형식은 규칙 집합의 추상 구문에 대한 조건들의 집합입니다. 이러한 조건들은 함께 규칙의 머리부에 있는 변수가 규칙의 본문에서 정의된 값을 갖도록 하고, 필터 요소 또는 할당 표현식의 각 변수가 평가 시점에 값을 갖도록 하며, 규칙의 각 할당이 새 변수를 도입하고, 그 변수가 규칙 본문의 앞부분에서 사용되지 않았음을 보장합니다.
우리는 초기 변수 집합이 주어졌을 때 규칙 요소 시퀀스에 대한 올바른 형식을 정의합니다.
elti를 규칙 요소 시퀀스의 i번째 요소라고 합니다.
varsi를 elti에 의해 정의되는 변수들의 집합이라고 하며, 여기서:
V0을 시퀀스의 초기 변수라고 합니다.
Vi는 V0와, j가 i보다 작은 모든 varsj의 합집합입니다.
Vall은 시퀀스의 길이가 N일 때 VN입니다.
올바른 형식의 시퀀스는 변수 집합 V0가 주어졌을 때, 다음 조건을 만족하는 규칙 요소의 시퀀스입니다:
규칙은 규칙 본문의 시퀀스가 빈 집합인 V0가 주어졌을 때 올바른 형식의 시퀀스이고, 규칙 머리부의 트리플 템플릿에 있는 각 변수가 Vall의 원소이면 올바른 형식의 규칙입니다.
규칙 집합은 그 규칙 집합의 모든 규칙이 올바른 형식의 규칙인 경우에만 올바른 형식의 규칙 집합입니다.
규칙 R1은 두 번째 규칙의 출력이 첫 번째 규칙의 본문 평가에
영향을 미치는 경우 규칙 R2에 의존합니다. 즉, R2의
머리부에는 R1의 본문 안에 있는
트리플 패턴과 일치하는 트리플을 생성할 수 있는
트리플 템플릿이 있습니다.
이는 트리플 패턴 요소로서든
부정 요소 내부에서든 해당됩니다.
의존성에는 두 가지 종류가 있습니다:
닫힌 의존성과 열린
의존성입니다.
닫힌 의존성은 규칙 R1이 실행되기 전에 규칙 R2가
가능한 모든 출력을 생성했음을 보장합니다.
규칙 의존성이 닫힌 것이 아니면 열린 의존성이며,
이는 규칙 R2가 추가 트리플을 생성하기 위해 다시 실행될 수 있는
동안에도 첫 번째 규칙 R1이 실행될 수 있게 하고,
그러면 R2의 새 트리플로 인해 R1이 다시 평가될 수 있습니다.
이 첫 번째 예제에서 첫 번째 규칙은 두 번째 규칙에 대해 열린 의존성을 가집니다.
이 두 번째 예제에서 첫 번째 규칙은 두 번째 규칙에 대해 닫힌 의존성을 가집니다.
트리플 패턴은 트리플 템플릿이 트리플 패턴과 일치하는 트리플을 생성할 수 있는 경우 트리플 템플릿과 일치합니다.
트리플 패턴은 해당 트리플 패턴이 트리플 템플릿과 일치할 가능성이 있는 경우 트리플 템플릿에 의존합니다.
트리플 패턴은 규칙 머리부에 있는 트리플 템플릿 중 어느 하나에 대해 의존성이 있는 경우 규칙에 의존합니다.
규칙 R1은 R1의 본문 안에 있는 어떤
트리플 패턴이,
트리플 패턴 요소로서든
부정 요소 내부에서든,
R2의 머리부 안에 있는
트리플 템플릿에
의존하는
경우
규칙 R2에 의존합니다.
규칙 R1이 규칙
R2에 갖는 규칙 의존성은 그 의존성이
닫힌 의존성이 아닌 경우
열린 의존성입니다.
즉, R2에 의존하는 R1의 모든
트리플 패턴은
트리플 패턴 요소로서만 나타납니다.
구성 요소가 tSubj, tPred, tObj인
트리플 템플릿은
다음 조건이 모두 참인 경우 RDF 용어 구성 요소
s, p, o를 가진 트리플을
생성할 수 있습니다:
tSubj가 변수이거나, tSubj가 s와
동일한 RDF 용어입니다
tPred가 변수이거나, tPred가 p와
동일한 RDF 용어입니다
tObj가 변수이거나, tObj가 o와
동일한 RDF 용어입니다
또한 tSubj, tPred, tObj 중 어떤 쌍이
동일한 변수라면,
대응하는 s, p, o의 쌍도
동일해야 합니다.
규칙 간의 의존성은 의존성 그래프라고 하는 방향 그래프로 표현됩니다. 그래프의 정점은 규칙 집합의 규칙이고, 간선에는 해당 의존성이 열린 의존성인지 닫힌 의존성인지에 따라 open 또는 closed 레이블이 붙습니다.
R1이 R2에 의존하는 경우 규칙
R1에서 규칙 R2로 간선이 존재하는 방향 그래프입니다.
해당 간선에는 의존성이 열린 의존성인지
닫힌 의존성인지에 따라
open 또는 closed 레이블이 붙습니다.
R1에서 R2로 가는 경로가
의존성 그래프 안에 있으면,
규칙 R1은 규칙 R2에 대해
추이적 의존성을 가집니다.
의존성 그래프는 데이터 그래프의 영향을 받지 않습니다.
다음 알고리즘은 의존성 그래프를 규칙 집합으로부터 구성하기 위한 한 가지 가능한 방법을 제공합니다. 적합성은 이 절차의 사용 여부가 아니라, 의존성 그래프의 정의를 만족하는 의존성 그래프를 생성하는 데 달려 있습니다.
define mergeLabel(oldLabel, newLabel):
## Closed dependency overrides open dependency.
if oldLabel == "open" and newLabel == "open":
return "open"
else:
return "closed"
endif
enddefine
## output -- Dependency graph with rule vertices and labeled edges.
define buildDependencyGraph(ruleSet):
## edgeLabelMap maps (R1, R2) to "open" or "closed"
let edgeLabelMap be a map from pair (rule, rule) to label
foreach rule R1 in ruleSet:
## Classify each triple pattern TP in the rule as requiring "open" or "closed"
## depending on whether it is in a negation element or not.
let bodyDependencies = {}
foreach rule element RBE in the body of R1:
if RBE is a negation element:
foreach triple pattern TP in RBE:
let item be a pair (TP, "closed")
add item to bodyDependencies
endfor
else if RBE is a triple pattern element of triple pattern TP:
let item be a pair (TP, "open")
add item to bodyDependencies
else if RBE is a condition element:
## Do nothing
else if RBE is an assignment element:
## Do nothing
endif
endfor
foreach pair (triple pattern TP, depLabel) in bodyDependencies:
if R1 has an assignment element:
set depLabel to "closed"
endif
if R1 has a triple template with a blank node:
set depLabel to "closed"
endif
## Find depenencies for this triple pattern element or negation element.
foreach rule R2 in ruleSet:
foreach triple template TT in head of R2:
## "possibly generate" / matching is defined in
## section 3.3
if TT can possibly match triple pattern TP:
let key = (R1, R2)
if edgeLabelMap contains key:
let oldLabel = edgeLabelMap.get(key)
let merged = mergeLabel(oldLabel, depLabel)
edgeLabelMap.set(key, merged)
else:
edgeLabelMap.set(key, depLabel)
endif
endif
endfor
endfor
endfor
endfor
let DP = { }
foreach entry ((R1, R2), label) in edgeLabelMap:
add edge (R1 -> R2) labeled label to DP
endfor
the result is DP
enddefine
예:
계층화는 규칙 집합을 계층화 층(또한 "strata", 단수 "stratum"이라고도 함)의 순서 있는 시퀀스로 분할하는 과정입니다. 더 낮은 strata의 규칙은 더 높은 strata의 규칙보다 먼저 평가됩니다.
계층화는 규칙 간의 의존성에 제약을 부과하여 부정 요소, 할당 요소, 그리고 규칙 머리부에서 생성된 빈 노드가 더 이른(낮은) strata와 기본 그래프를 사용해 계산된 결과에만 의존하도록 보장합니다. 이는 주어진 기본 그래프에 대한 규칙 집합의 평가에서 단일하고 잘 정의되며 유한한 결과를 보장합니다.
계층화 과정은 다른 평가 결정을 내리는 데에도 사용될 수 있습니다. 이 문서는 일관된 평가에 필요한 조건을 설명하고, 계층화를 형성하는 한 가지 가능한 방법을 제공합니다. 구현은 호환 가능한 동작을 얻기 위해 여기에 설명된 조건을 만족해야 하지만, 제시된 알고리즘을 그대로 구현할 필요는 없습니다.
계층화 층 SL은 서로소인
규칙 집합 두 개(SL.once, SL.general)의 쌍입니다.
SL.once는 한 번만 실행되는 규칙을 포함하며,
이는 할당 요소를 사용하거나
규칙 머리부에 빈 노드를 생성하는
규칙입니다; 이러한 규칙은 계층화 층 평가의 시작 시
각각 정확히 한 번 평가됩니다.
SL.general은 남은 규칙을 포함하며, 이 규칙들은
새로운 트리플이 더 이상 추론되지 않을 때까지 반복적으로 평가됩니다.
계층화는 다음 조건이 만족될 때에만 정의됩니다. 규칙 집합이 이 조건을 충족하지 않으면, 이 명세는 그러한 규칙 집합의 평가 결과를 정의하지 않습니다.
달리 말해, 의존성 그래프의 어떤 추이적 의존성 순환에도
NOT 또는 한 번만 실행되는 규칙(할당 또는 빈 노드를 포함하는 규칙
트리플 템플릿)이 없습니다.
다음 알고리즘은 오직 규칙 집합만을 기반으로 하는 한 가지 가능한 계층화를 제공합니다.
## output -- Map: Integer -> Set of rules.
define stratification(ruleSet):
let DP = Dependency graph for the rule set.
let stratumMap be a map from rule to integer
## The dependency graph should satisfy the stratification condition.
## The check for unbounded stratification is a guard
## due to a violation of the stratification condition.
let limit = num rules + 1
let maxStratum = 0
## initialize stratumMap
foreach rule in ruleSet:
stratumMap.set(rule, 0)
endfor
boolean changed = true;
while changed:
changed = false;
foreach edge E in DP:
## Edge from pRule to qRule with a label
let pRule = source of edge
let qRule = destination of the edge
let label = edge label
if label == "open" :
if stratumMap.get(pRule) < stratumMap.get(qRule) :
stratumMap.set(pRule, stratumMap.get(qRule))
changed = true;
endif
endif
if label == "closed" :
if stratumMap.get(pRule) <= stratumMap.get(qRule) :
let xStratum = 1 + stratumMap.get(qRule)
if ( xStratum > limit )
## Stratification requirement violated
error "Stratification error"
endif
stratumMap.set(pRule, xStratum)
maxStratum = max(maxStratum, xStratum)
changed = true;
endif
endif
endfor
endwhile
## Initialize the result map.
let stratumRules be a map from integer to rules.
for i = 0 to maxStratum
stratumRules.set(i, {})
endfor
## Gather rules in stratumMap with the same level number
for rule R in map stratumMap:
let stratumNum = stratumMap.get(R)
add R to stratumRules.get(stratumNum)
endfor
## Partition each level into once and general
let stratumLevels be a sequence of pairs of sets of rules.
for i = 0 to maxStratum:
let rules = stratumRules.get(i)
let once = { R in rules | R is a run-once rule }
let general = rules \ once
stratumLevels.set(i, pair(once, general))
endfor
the result is stratumLevels
enddefine
계층화 조건의 한 결과는 한 번만 실행되는 규칙이 평가되면, 그 규칙의 결과를 결정하는 데 사용된 데이터가 이후 평가 중에는 변경되지 않는다는 것입니다.
두 가지 구체 구문이 있습니다.
Shape Rules Language:
RDF Rules 구문:
문법은 아래에 제공됩니다.
AST를 추상 구문에 매핑합니다.
추가 도우미(단축 약어):
이들은 잘 알려진 규칙 패턴을 허용하며, 기본 엔진에서의 특수한 구현도 가능하게 합니다.
TRANSITIVE(uri)SYMMETRIC(uri)INVERSE(uri, uri)
어휘: rdf-syntax-vocab.ttl
SHACL 셰이프: rdf-syntax-shapes.ttl
올바른 형식:
추상 모델이 트리플에 매핑되는 방법을 설명합니다.
과정: 누산기, bottom up/구조 순회.
구문에 없는 모든 트리플은 무시됩니다. 다른 "srl:" 술어는 허용되지 않습니다(??).
@@ 그림: 텍스트 및 RDF 구문의 SHACL 규칙 집합: 모든 기능:
PREFIX : <http://example/>
DATA { :s :p :o }
RULE { ?x :q :o } WHERE { ?x :p :o }
RULE { ?x :q :o } WHERE { ?x :p :o1 ; :p :o2 }
RULE { ?x :q :o } WHERE { ?x :p ?o . FILTER (?o < 18) }
RULE { ?x :q ?o } WHERE { ?x :p :o . SET (?o := 18) }
RULE { ?x :q ?o } WHERE { ?x :p :o . NOT { ?s :p ?o . FILTER(?o < 18) } }
PREFIX : <http://example/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX sh: <http://www.w3.org/ns/shacl#>
PREFIX sparql: <http://www.w3.org/ns/sparql#>
PREFIX srl: <http://www.w3.org/ns/shacl-rules#>
:ruleSet-1
rdf:type srl:RuleSet;
srl:data (
[ srl:subject :s ; srl:predicate :p; srl:object :o ; ]
);
srl:rules (
[
rdf:type srl:Rule;
srl:body (
[ srl:subject [ srl:varName "x" ] ; srl:predicate :p ; srl:object :o ; ]
) ;
srl:head (
[ srl:subject [ srl:varName "x" ] ; srl:predicate :q ; srl:object :o ; ]
)
]
[
rdf:type srl:Rule ;
srl:body (
[ srl:subject [ srl:varName "x" ] ; srl:predicate :p ; srl:object :o1 ; ]
[ srl:subject [ srl:varName "x" ] ; srl:predicate :p ; srl:object :o2 ; ]
) ;
srl:head (
[ srl:subject [ srl:varName "x" ] ; srl:predicate :q ; srl:object :o ; ]
)
]
[
rdf:type srl:Rule ;
srl:body (
[ srl:subject [ srl:varName "x" ] ; srl:predicate :p ; srl:object [ srl:varName "o" ] ; ]
[
srl:filter [
sparql:less-than (
[ srl:varName "o" ]
18
)
]
]
) ;
srl:head (
[ srl:subject [ srl:varName "x" ] ; srl:predicate :q ; srl:object :o ; ]
)
]
[
rdf:type srl:Rule ;
srl:body (
[ srl:subject [ srl:varName "x" ] ; srl:predicate :p ; srl:object :o ; ]
[
srl:assign [
srl:assignValue 18 ;
srl:assignVar [ srl:varName "o" ]
]
]
) ;
srl:head (
[ srl:subject [ srl:varName "x" ] ; srl:predicate :q ; srl:object [ srl:varName "o" ] ; ]
)
]
[
rdf:type srl:Rule ;
srl:body (
[ srl:subject [ srl:varName "x" ] ; srl:predicate :p ; srl:object :o ; ]
[
srl:not (
[ srl:subject [ srl:varName "s" ] ; srl:predicate :p ; srl:object [ srl:varName "o" ] ; ]
[
srl:filter [
sparql:less-than (
[ srl:varName "o" ]
18
)
]
]
)
]
) ;
srl:head (
[ srl:subject [ srl:varName "x" ] ; srl:predicate :q ; srl:object [ srl:varName "o" ] ; ]
)
]
) .
이 절은 주어진 데이터에 대해 규칙 집합을 평가한 결과를 정의합니다. 이는 구현 방법으로서 알고리즘을 규정하지 않습니다. 구현은 동일한 결과를 생성하는 어떤 알고리즘도 사용할 수 있습니다.
Inputs: data graph G, called the base graph, and a rule set RS.
Output: an RDF graph GI of inferred triples
추론된 트리플은 기본 그래프의 트리플 집합에 존재하는 트리플을 포함하지 않습니다.
μ : V → T이며,
여기서 V는 모든 변수의 집합이고
T는 모든 RDF
용어의 집합입니다.
μ의 정의역은
dom(μ)로 표시하며, 이는
μ가 정의되어 있는 V의 부분집합입니다. 명확하게
해 매핑을 의미하는 경우에는
해라는 용어를 사용합니다.
dom(μ0)가 공집합인
해 매핑을 μ0로 씁니다.
subst(μ, triple pattern)
이며, 트리플 패턴을 반환합니다.
여기서 트리플 패턴 안에서
dom(μ)에 속한 변수의 각 출현은
var에 대한
해 매핑이 주는
RDF 용어로 대체됩니다.
그 결과 트리플 패턴에 변수가 없으면 이는 RDF 트리플입니다.
G를 RDF 그래프라고 하고 TP를
트리플 패턴이라고 합니다.
함수 graphMatch(G, TP)는 트리플 패턴에 적용되었을 때
평가 그래프 안에 있는
트리플을 생성하는 모든 가능한
해의 집합을 반환합니다.
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) = { μ |
μ(v) = μ1(v) if v in dom(μ1)
μ(v) = μ2(v) otherwise }
merge(S1, S2) = { μ |
μ1 in S1, μ2 in S2
and compatible(μ1, μ2)
μ(v) = merge(μ1, μ2) }
정의역이 dom(S1) ∪︀ dom(S2)라고 말합니다.
공통 변수가 없는 두 해는 호환된다고 말합니다.
규칙 집합을 평가하는 첫 단계는 하나의 유효한 규칙 집합을 준비하는 것입니다. 여기에는 가져온 모든 규칙 집합을 모으고, 하나의 결합된 규칙 집합을 만든 다음, 결합된 규칙 집합에 대한 계층화를 계산하는 것이 포함됩니다.
해결된 규칙 집합은 다른 규칙 집합의 가져오기에 언급된 모든 규칙 집합을 재귀적으로 읽어, 다른 규칙 집합으로부터 생성됩니다.
규칙 집합에는 세 가지 구성 요소가 있습니다:
R.rules, R.data, 및 R.imports.
두 규칙 집합 RS1과 RS2의
규칙
집합 병합은 다음과 같이 정의되는 규칙 집합 MR입니다:
MR.rules = RS1.rules ∪︀ RS2.rules
MR.data = merge(RS1.data, RS2.data)
MR.imports = {}
여기서 merge는
RDF 병합
작업입니다.
define imports(rule set RS, set of URLs V), returning rule set
let I = the set of import URLs declared for the rule set RS
let RS2 be a rule set formed from RS.rules and RS.data
foreach URL x in I:
if x ∉ V:
V = V ∪︀ { x }
read rule set RS3 from URL x
RS2 = rulesetMerge(RS2, imports(RS3, V))
endif
endfor
result is RS2
enddefine
let RS be a rule set
let V = {}
if RS has a location, V = { location of RS }
result is imports(RS, V)
해결된 규칙 집합을 만든 뒤, 의존성 그래프를 계산하고 (4.3.2 의존성 그래프 알고리즘 참조), 그런 다음 [=계층화]를 계산합니다 (4.4.2 계층화 알고리즘 참조).
필터 요소 또는 할당 요소에서 사용되는 표현식은, 표현식 안의 각 변수에 대해 RDF 용어인 값을 제공하는 해 매핑과 관련하여 평가됩니다. 4.2 올바른 형식 조건의 올바른 형식 요구사항은 표현식 안의 모든 변수가 해 매핑에 나타나도록 보장합니다.
define evalFunction(F, μ):
## F is an expression: an RDF term, a variable, or op(expr1, ..., exprN)
## where op is a function or a functional form.
if F is an RDF term:
return F
if F is a variable:
## By well-formedness, F ∈ dom(μ).
return μ(F)
## F is of the form F= op(expr1, ..., exprN)
if op is a functional form (e.g. IF, logical-or):
## Evaluated specifically for op; op may evaluate only some arguments.
## For example, IF(c, t, f) evaluates c, then exactly one of t or f.
return the value defined for op over expr1, ..., exprN under μ
## op is an ordinary function: evaluate all arguments first.
return F(evalFunction(expr1, row), ..., evalFunction(exprN, row))
enddefine
함수 EBV(x)는 RDF 용어에 대한
유효
불리언 값을 반환합니다.
규칙은 규칙 본문으로부터 해 시퀀스를 계산한 다음, 해 시퀀스의 각 해 매핑을 사용하여 규칙 머리부를 통해 트리플을 생성함으로써 평가됩니다.
let R be a well-formed rule.
let rule R = (H, B) where
H is the sequence of triple templates in the head
B is the sequence of triple pattern elements,
condition elements, negation elements,
and assignment elements in the body
# Solution sequence of one solution that does not map any variables.
let SEQ0: Solution sequence = { μ0 }
let G = evaluation graph
# Evaluate rule body
# This function returns a sequence of solutions
define evalRuleElements(B, SEQ, G):
for each rule element rElt in B:
if rElt is a triple pattern TP:
X = graphMatch(G, TP)
SEQ1 = {}
for each μ1 in X:
for each μ2 in SEQ:
if compatible(μ1, μ2)
μ3 = merge(μ1, μ2)
add μ3 to SEQ1
endif
endfor
endfor
endif
if rElt is a condition element with expression F:
SEQ1 = {}
for each solution μ in SEQ:
let x = evalFunction(F, μ)
if EBV(x) is true:
add μ to SEQ1
endif
endfor
endif
if rElt is a negation expression with body elements N:
SEQ1 = {}
for each solution μ in SEQ:
S = sequence{ μ }
NEG = evalRuleElements(N, S, G)
if NEG is empty
add μ to SEQ1
endif
endfor
endif
if rElt is an assignment with variable V and expression expr
SEQ1 = {}
for each solution μ in SEQ:
let x = evalFunction(expr, μ)
if x is not an error:
## Add mapping V -> x to solution μ
let μ2 be a solution mapping μ ∪︀ { (V, x) }
add μ2 to SEQ1
else
# Error: drop solution μ
endif
endfor
endif
if SEQ1 is empty
SEQ = {}
return SEQ
endif
SEQ = SEQ1
endfor
return SEQ
enddefine
let SEQ = evalRuleElements(B, SEQ0, G)
# Evaluate rule head
let OUT = empty set
for each μ in SEQ:
let S = {}
for each triple template TT in H:
let triple = subst(μ, TT)
Add triple to S
endfor
OUT = OUT union S
endfor
result eval(R, G) is OUT
OUT은 데이터 그래프에도 있는 트리플을 포함할 수 있음에 유의하십시오.
규칙 집합의 평가는 규칙 집합의 계층화에 있는 각 stratum의 실행으로 정의됩니다. 여기서 각 stratum은 다음 stratum으로 이동하기 전에 완전히, 그리고 순서대로 실행됩니다. stratum은 먼저 해당 stratum의 한 번만 실행되는 규칙 각각을 평가한 다음, 새로운 트리플이 생성되지 않을 때까지 그 stratum의 일반 규칙을 반복적으로 평가함으로써 평가됩니다.
let G0 be the input base graph
let RS be the rule set
let D be the graph of all DATA triples in RS
Apply stratification to RS
let LS be the sequence of layers after stratification
# Inference graph
let GI = { t ∈ D | t ∉ G0 }
# Evaluation graph.
let GE = G0 ∪︀ D
for each stratum ST in LS:
for each rule R in ST.once:
let X = eval(R, GE)
let Y = { t ∈ X | t ∉ GE }
GI = Y ∪︀ GI
GE = Y ∪︀ GE
endfor
let finished = false
while !finished:
finished = true
for each rule R in ST.general:
let X = eval(R, GE)
let Y = { t ∈ X | t ∉ GE }
if Y is not empty:
finished = false
GI = Y ∪︀ GI
GE = Y ∪︀ GE
endif
endfor
endwhile
endfor
the result is GI
Shape Rules Language 문서는 UTF-8
[RFC3629]로
인코딩된 RDF
문자열입니다.
U+0000에서 U+D7FF
및 U+E000에서 U+10FFFF
범위의 유니코드 스칼라 값만
허용됩니다. 이는
서러게이트 코드 포인트,
범위 U+D800에서 U+DFFF를
제외합니다.
공백
(생성 규칙 WS)은 그렇지 않으면 하나의
터미널로 (잘못) 인식될 수 있는 두 터미널을 분리하는 데 사용됩니다.
아래에서 대문자로 된 규칙 이름은 공백이 중요한 곳을 나타내며,
이는 Shape Rules Language 파서를 구성하기 위한 터미널의 가능한 선택을 이룹니다.
공백은
String 생성 규칙에서 중요합니다.
주석은
IRIREF,
STRING_LITERAL1,
STRING_LITERAL2,
STRING_LITERAL_LONG1, 또는
STRING_LITERAL_LONG2 밖에 있는
#로 시작하며,
LF 또는
CR로 표시되는
행 끝까지 계속되거나,
주석 표시 뒤에 행 끝이 없는 경우 파일 끝까지 계속됩니다.
주석은 공백으로 처리됩니다.
상대 IRI 참조는 Uniform Resource Identifier (URI): Generic Syntax [RFC3986]에 따라 기본 알고리즘인 5.2절만 사용하여 Base IRI로 해석됩니다. RFC3986의 6.2.2절과 6.2.3절에 설명된 Syntax-Based Normalization 또는 Scheme-Based Normalization은 수행되지 않습니다. IRI 참조에서 추가로 허용되는 문자는 Internationalized Resource Identifiers (IRIs) [RFC3987]의 6.5절에 따라 URI 참조의 예약되지 않은 문자가 처리되는 것과 같은 방식으로 처리됩니다.
BASE
지시문은 [RFC3986]
5.1.1절, "Base URI
Embedded in Content"에 따라
상대 IRI
참조를 해석하는 데 사용되는 Base IRI를 정의합니다.
5.1.2절, "Base
URI from the Encapsulating Entity"는
SOAP envelope의 xml:base 지시문이나 MIME multipart 문서의
Content-Location 헤더와 같은 캡슐화 문서에서
In-Scope Base IRI가 어떻게 올 수 있는지 정의합니다.
5.1.3, Base "URI from the Retrieval
URI"에서 식별된 "Retrieval URI"는 특정
Shape Rules Language 문서가
검색된 URL입니다.
위의 어느 것도 Base URI를 지정하지 않으면 기본
Base URI(5.1.4절, "Default Base URI")가
사용됩니다.
각 BASE 지시문은 이전 것에 상대적으로
새로운 In-Scope Base URI를 설정합니다.
Shape Rules 문서에서 사용되는 이스케이프에는 세 가지 형식이 있습니다:
숫자 이스케이프 시퀀스는 유니코드 코드 포인트의 값을 나타냅니다.
숫자 이스케이프 시퀀스는
유니코드 서러게이트 범위인
U+D800에서 U+DFFF까지의
코드 포인트 값을 생성해서는 MUST NOT 됩니다.
| 이스케이프 시퀀스 | 유니코드 코드 포인트 |
|---|---|
\u hex
hex
hex
hex
|
가장 유효한 자리부터 가장 덜 유효한 자리까지 해석한
네 개의 16진수 숫자로 인코딩된 값에 대응하는,
U+0000에서 U+D7FF
및 U+E000에서 U+FFFF
범위의 유니코드 코드 포인트
|
\U hex
hex
hex
hex
hex
hex
hex
hex
|
가장 유효한 자리부터 가장 덜 유효한 자리까지 해석한
여덟 개의 16진수 숫자로 인코딩된 값에 대응하는,
U+0000에서
U+D7FF
및 U+E000에서 U+10FFFF
범위의
유니코드 코드 포인트
|
여기서 hex는 16진수 문자입니다
HEX ::= [0-9] | [A-F] |
[a-f]
문자열 이스케이프 시퀀스는 문자열 리터럴에서 전통적으로 이스케이프되는 문자를 나타냅니다:
| 이스케이프 시퀀스 | 유니코드 코드 포인트 |
|---|---|
\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 선언
|
yes | no | no |
| 로컬 이름 | no | no | yes |
| 문자열 | yes | yes | no |
%-인코딩된 시퀀스는
IRI의 문자 범위에 있으며
로컬 이름에서 명시적으로 허용됩니다.
이들은 % 뒤에
두 개의 16진수 문자가 오는 형태로 나타나며, 동일한 세 문자 시퀀스를
나타냅니다. 이러한 시퀀스는 처리 중에 디코딩되지 않습니다.
<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를 지정합니다.
여기서 사용되는 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 |
::= | Rule1 | Rule2 | Declaration
|
[12] |
Rule1 |
::= | 'RULE' iri? HeadTemplate 'WHERE' BodyPattern
|
[13] |
Rule2 |
::= | 'IF' BodyPattern 'THEN' HeadTemplate
|
[14] |
Declaration |
::= | ( 'TRANSITIVE' '(' iri ')' | 'SYMMETRIC' '(' iri ')' | 'INVERSE' '(' iri ',' iri ')' )
|
[15] |
Data |
::= | 'DATA' '{' TriplesDataBlock? '}'
|
[16] |
TriplesDataBlock
|
::= | TriplesSameSubject ( '.' TriplesDataBlock? )?
|
[17] |
HeadTemplate |
::= | '{' HeadTemplateBlock? '}'
|
[18] |
BodyPattern |
::= | '{' BodyTriplesBlock? ( BodyNotTriples '.'? BodyTriplesBlock? )* '}'
|
[19] |
BodyNotTriples |
::= | Filter | Negation | Assignment
|
[20] |
BodyTriplesBlock
|
::= | TriplesBlock |
[21] |
Negation |
::= | 'NOT' '{' BodyBasic '}'
|
[22] |
BodyBasic |
::= | BodyTriplesBlock? ( BodyBasicNotTriples '.'? BodyTriplesBlock? )*
|
[23] |
BodyBasicNotTriples
|
::= | Filter |
[24] |
HeadTemplateBlock
|
::= | TriplesBlock |
[25] |
TriplesBlock |
::= | TriplesSameSubjectPath ( '.' TriplesBlock? )?
|
[26] |
ReifiedTripleBlock
|
::= | ReifiedTriple PropertyList
|
[27] |
ReifiedTripleBlockPath
|
::= | ReifiedTriple PropertyListPath
|
[28] |
Assignment |
::= | 'SET' '(' Var ':=' Expression ')'
|
[29] |
Reifier |
::= | '~' VarOrReifierId?
|
[30] |
VarOrReifierId |
::= | Var | iri | BlankNode
|
[31] |
Filter |
::= | 'FILTER' Constraint
|
[32] |
Constraint |
::= | BrackettedExpression | BuiltInCall | FunctionCall
|
[33] |
FunctionCall |
::= | iri ArgList
|
[34] |
ArgList |
::= | NIL | '(' Expression ( ',' Expression )* ')'
|
[35] |
ExpressionList |
::= | NIL | '(' Expression ( ',' Expression )* ')'
|
[36] |
TriplesSameSubject
|
::= | VarOrTerm PropertyListNotEmpty | TriplesNode PropertyList | ReifiedTripleBlock
|
[37] |
PropertyList |
::= | PropertyListNotEmpty?
|
[38] |
PropertyListNotEmpty
|
::= | Verb ObjectList ( ';' ( Verb ObjectList )? )*
|
[39] |
Verb |
::= | VarOrIri | 'a'
|
[40] |
ObjectList |
::= | Object ( ',' Object )*
|
[41] |
Object |
::= | GraphNode Annotation
|
[42] |
TriplesSameSubjectPath
|
::= | VarOrTerm PropertyListPathNotEmpty | TriplesNodePath PropertyListPath | ReifiedTripleBlockPath
|
[43] |
PropertyListPath
|
::= | PropertyListPathNotEmpty?
|
[44] |
PropertyListPathNotEmpty
|
::= | ( VerbPath | VerbSimple ) ObjectListPath ( ';' ( ( VerbPath | VerbSimple ) ObjectListPath )? )*
|
[45] |
VerbPath |
::= | Path |
[46] |
VerbSimple |
::= | Var |
[47] |
ObjectListPath |
::= | ObjectPath ( ',' ObjectPath )*
|
[48] |
ObjectPath |
::= | GraphNodePath AnnotationPath
|
[49] |
Path |
::= | PathSequence |
[50] |
PathSequence |
::= | PathEltOrInverse ( '/' PathEltOrInverse )*
|
[51] |
PathEltOrInverse
|
::= | PathElt | '^' PathElt
|
[52] |
PathElt |
::= | PathPrimary |
[53] |
PathPrimary |
::= | iri | 'a' | '(' Path ')'
|
[54] |
TriplesNode |
::= | Collection | BlankNodePropertyList
|
[55] |
BlankNodePropertyList
|
::= | '[' PropertyListNotEmpty ']'
|
[56] |
TriplesNodePath |
::= | CollectionPath | BlankNodePropertyListPath
|
[57] |
BlankNodePropertyListPath
|
::= | '[' PropertyListPathNotEmpty ']'
|
[58] |
Collection |
::= | '(' GraphNode+ ')'
|
[59] |
CollectionPath |
::= | '(' GraphNodePath+ ')'
|
[60] |
AnnotationPath |
::= | ( Reifier | AnnotationBlockPath )*
|
[61] |
AnnotationBlockPath
|
::= | '{|' PropertyListPathNotEmpty '|}'
|
[62] |
Annotation |
::= | ( Reifier | AnnotationBlock )*
|
[63] |
AnnotationBlock |
::= | '{|' PropertyListNotEmpty '|}'
|
[64] |
GraphNode |
::= | VarOrTerm | TriplesNode | ReifiedTriple
|
[65] |
GraphNodePath |
::= | VarOrTerm | TriplesNodePath | ReifiedTriple
|
[66] |
VarOrTerm |
::= | Var | RDFTerm
|
[67] |
RDFTerm |
::= | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | NIL | TripleTerm
|
[68] |
ReifiedTriple |
::= | '<<' ReifiedTripleSubject Verb ReifiedTripleObject Reifier? '>>'
|
[69] |
ReifiedTripleSubject
|
::= | Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple | TripleTerm
|
[70] |
ReifiedTripleObject
|
::= | Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple | TripleTerm
|
[71] |
TripleTerm |
::= | '<<(' TripleTermSubject Verb TripleTermObject ')>>'
|
[72] |
TripleTermSubject
|
::= | Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTerm
|
[73] |
TripleTermObject
|
::= | Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTerm
|
[74] |
TripleTermData |
::= | '<<(' TripleTermDataSubject ( iri | 'a' ) TripleTermDataObject ')>>'
|
[75] |
TripleTermDataSubject
|
::= | iri | RDFLiteral | NumericLiteral | BooleanLiteral
|
[76] |
TripleTermDataObject
|
::= | iri | RDFLiteral | NumericLiteral | BooleanLiteral | TripleTermData
|
[77] |
VarOrIri |
::= | Var | iri
|
[78] |
Var |
::= | VAR1 | VAR2
|
[79] |
Expression |
::= | ConditionalOrExpression
|
[80] |
ConditionalOrExpression
|
::= | ConditionalAndExpression ( '||' ConditionalAndExpression )*
|
[81] |
ConditionalAndExpression
|
::= | ValueLogical ( '&&' ValueLogical )*
|
[82] |
ValueLogical |
::= | RelationalExpression
|
[83] |
RelationalExpression
|
::= | NumericExpression ( '=' NumericExpression | '!=' NumericExpression | '<' NumericExpression | '>' NumericExpression | '<=' NumericExpression | '>=' NumericExpression | 'IN' ExpressionList | 'NOT' 'IN' ExpressionList )?
|
[84] |
NumericExpression
|
::= | AdditiveExpression
|
[85] |
AdditiveExpression
|
::= | MultiplicativeExpression ( '+' MultiplicativeExpression | '-' MultiplicativeExpression | ( NumericLiteralPositive | NumericLiteralNegative ) ( ( '*' UnaryExpression ) | ( '/' UnaryExpression ) )* )*
|
[86] |
MultiplicativeExpression
|
::= | UnaryExpression ( '*' UnaryExpression | '/' UnaryExpression )*
|
[87] |
UnaryExpression |
::= | '!' PrimaryExpression
|
[88] |
PrimaryExpression
|
::= | BrackettedExpression | BuiltInCall | iriOrFunction | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprTripleTerm
|
[89] |
ExprTripleTerm |
::= | '<<(' ExprTripleTermSubject Verb ExprTripleTermObject ')>>'
|
[90] |
ExprTripleTermSubject
|
::= | iri | RDFLiteral | NumericLiteral | BooleanLiteral | Var
|
[91] |
ExprTripleTermObject
|
::= | iri | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprTripleTerm
|
[92] |
BrackettedExpression
|
::= | '(' Expression ')'
|
[93] |
BuiltInCall |
::= | 'STR' '(' Expression ')'
|
[94] |
iriOrFunction |
::= | iri ArgList?
|
[95] |
RDFLiteral |
::= | String ( LANG_DIR | '^^' iri )?
|
[96] |
NumericLiteral |
::= | NumericLiteralUnsigned | NumericLiteralPositive | NumericLiteralNegative
|
[97] |
NumericLiteralUnsigned
|
::= | INTEGER | DECIMAL | DOUBLE
|
[98] |
NumericLiteralPositive
|
::= | INTEGER_POSITIVE | DECIMAL_POSITIVE | DOUBLE_POSITIVE
|
[99] |
NumericLiteralNegative
|
::= | INTEGER_NEGATIVE | DECIMAL_NEGATIVE | DOUBLE_NEGATIVE
|
[100] |
BooleanLiteral |
::= | 'true' | 'false'
|
[101] |
String |
::= | STRING_LITERAL1 | STRING_LITERAL2 | STRING_LITERAL_LONG1 | STRING_LITERAL_LONG2
|
[102] |
iri |
::= | IRIREF | PrefixedName
|
[103] |
PrefixedName |
::= | PNAME_LN | PNAME_NS
|
[104] |
BlankNode |
::= | BLANK_NODE_LABEL | ANON
|
터미널에 대한 생성 규칙:
[105] |
IRIREF |
::= | '<' ([^<>"{}|^`\]-[#x00-#x20] | UCHAR )* '>'
|
[106] |
PNAME_NS |
::= | PN_PREFIX? ':' |
[107] |
PNAME_LN |
::= | PNAME_NS PN_LOCAL
|
[108] |
BLANK_NODE_LABEL
|
::= | '_:' ( PN_CHARS_U | [0-9] ) ((PN_CHARS|'.')* PN_CHARS)?
|
[109] |
VAR1 |
::= | '?' VARNAME |
[110] |
VAR2 |
::= | '$' VARNAME |
[111] |
LANG_DIR |
::= | '@' [a-zA-Z]+ ('-' [a-zA-Z0-9]+)* ('--' [a-zA-Z]+)?
|
[112] |
INTEGER |
::= | [0-9]+ |
[113] |
DECIMAL |
::= | [0-9]* '.' [0-9]+ |
[114] |
DOUBLE |
::= | ( ([0-9]+ ('.'[0-9]*)? ) | ( '.' ([0-9])+ ) ) [eE][+-]?[0-9]+
|
[115] |
INTEGER_POSITIVE
|
::= | '+' INTEGER
|
[116] |
DECIMAL_POSITIVE
|
::= | '+' DECIMAL
|
[117] |
DOUBLE_POSITIVE |
::= | '+' DOUBLE
|
[118] |
INTEGER_NEGATIVE
|
::= | '-' INTEGER
|
[119] |
DECIMAL_NEGATIVE
|
::= | '-' DECIMAL
|
[120] |
DOUBLE_NEGATIVE |
::= | '-' DOUBLE
|
[121] |
STRING_LITERAL1 |
::= | "'" ( ([^#x27#x5C#xA#xD]) | ECHAR | UCHAR )* "'"
|
[122] |
STRING_LITERAL2 |
::= | '"' ( ([^#x22#x5C#xA#xD]) | ECHAR | UCHAR )* '"'
|
[123] |
STRING_LITERAL_LONG1
|
::= | "'''" ( ( "'" | "''" )? ( [^'\] | ECHAR | UCHAR ) )* "'''"
|
[124] |
STRING_LITERAL_LONG2
|
::= | '"""' ( ( '"' | '""' )? ( [^"\] | ECHAR | UCHAR ) )* '"""'
|
[125] |
ECHAR |
::= | '\' [tbnrf\"'] |
[126] |
UCHAR |
::= | ('\u' HEX HEX HEX HEX) | ('\U' HEX HEX HEX HEX HEX HEX HEX HEX)
|
[127] |
NIL |
::= | '(' WS* ')' |
[128] |
WS |
::= | #x20 | #x9 | #xD | #xA |
[129] |
ANON |
::= | '[' WS* ']' |
[130] |
PN_CHARS_BASE |
::= | [A-Z] | [a-z] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | [#x00F8-#x02FF] | [#x0370-#x037D] | [#x037F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
|
[131] |
PN_CHARS_U |
::= | PN_CHARS_BASE | '_'
|
[132] |
VARNAME |
::= | ( PN_CHARS_U | [0-9] ) ( PN_CHARS_U | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] )*
|
[133] |
PN_CHARS |
::= | PN_CHARS_U | '-' | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040]
|
[134] |
PN_PREFIX |
::= | PN_CHARS_BASE ((PN_CHARS|'.')* PN_CHARS)?
|
[135] |
PN_LOCAL |
::= | (PN_CHARS_U | ':' | [0-9] | PLX ) ((PN_CHARS | '.' | ':' | PLX)* (PN_CHARS | ':' | PLX) )?
|
[136] |
PLX |
::= | PERCENT | PN_LOCAL_ESC
|
[137] |
PERCENT |
::= | '%' HEX HEX
|
[138] |
HEX |
::= | [0-9] | [A-F] | [a-f] |
[139] |
PN_LOCAL_ESC |
::= | '\' ( '_' | '~' | '.' | '-' | '!' | '$' | '&' | "'" | '(' | ')' | '*' | '+' | ',' | ';' | '=' | '/' | '?' | '#' | '@' | '%' )
|
이 문법의 텍스트 버전은 여기에서 사용할 수 있습니다.
이 문서는 몇몇 특정 터미널 리터럴 문자열 [EBNF-NOTATION]을 사용합니다. 이러한 터미널 리터럴 문자열에 사용되는 유니코드 코드 포인트를 명확히 하기 위해, 다음 표는 이 절에서 사용되는 특정 문자를 설명합니다.
| 코드 | 글리프 | 설명 |
|---|---|---|
U+000A |
LF |
줄 바꿈 |
U+000D |
CR |
캐리지 리턴 |
U+0023 |
# |
숫자 기호 |
U+0025 |
% |
퍼센트 기호 |
U+005C |
\ |
백슬래시 |
Shape Rules Language의 인터넷 미디어 유형(이전의 MIME Type)은
"application/shape-rules"입니다.
뒤따르는 정보는 IANA에 검토, 승인 및 등록하기 위해 Internet Engineering Steering Group(IESG)에 제출되었습니다.
versionversion의 허용 가능한 값은
버전 레이블에 정의되어 있습니다.
profileprofile 매개변수의 값은
공백으로 구분된 URI의 비어 있지 않은 목록입니다.
자세한 정보와 배경은 [RFC6906]을 참조하십시오.
이 절은 비규범입니다.
TODO
이 절은 비규범입니다.
TODO
이 절은 비규범입니다.
TODO
이 절은 비규범입니다.
TODO
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: