@skaterqiang/protege-js 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +65 -0
- package/LICENSE +48 -0
- package/README.md +287 -0
- package/docs/API.md +654 -0
- package/docs/design/OWL2-/347/274/272/345/217/243/345/210/206/346/236/220.md +140 -0
- package/docs/owl2-rl/OWL2-RL-/350/247/204/345/210/231/347/273/206/345/210/231.md +168 -0
- package/docs/owl2-rl/owl2-profiles-spec-zh.html +1914 -0
- package/docs/owl2-rl/owl2-profiles-spec.html +1916 -0
- package/docs/owl2-rl/rl_rules.json +392 -0
- package/main.js +46 -0
- package/package.json +76 -0
- package/sample/README.md +74 -0
- package/sample/case1-ecommerce-risk.js +170 -0
- package/sample/case10-ecommerce-customer-service.js +454 -0
- package/sample/case2-family-swrl.js +147 -0
- package/sample/case3-pharma-safety.js +132 -0
- package/sample/case4-knowledge-publishing.js +111 -0
- package/sample/case5-obda-profiles.js +153 -0
- package/sample/case6-medical-ontology.js +152 -0
- package/sample/case7-manufacturing-ppr.js +155 -0
- package/sample/case8-real-medical-bfo-ogms.js +353 -0
- package/sample/case9-real-manufacturing-iao.js +360 -0
- package/sample/ontologies/bfo.owl +1715 -0
- package/sample/ontologies/iao.owl +8532 -0
- package/sample/ontologies/ogms.owl +4320 -0
- package/sample/ontologies/ro-core.owl +1010 -0
- package/scripts/verify-api.js +53 -0
- package/src/index.js +176 -0
- package/src/inference/OWL2ProfileReasoners.js +67 -0
- package/src/inference/OWL2RLReasoner.js +65 -0
- package/src/inference/ReasonerQueries.js +111 -0
- package/src/inference/SWRLReasoner.js +409 -0
- package/src/inference/TripleStore.js +82 -0
- package/src/inference/rdf.js +83 -0
- package/src/inference/rules/owl2el.js +33 -0
- package/src/inference/rules/owl2ql.js +29 -0
- package/src/inference/rules/owl2rl.js +823 -0
- package/src/io/FunctionalSyntaxParser.js +399 -0
- package/src/io/FunctionalSyntaxWriter.js +180 -0
- package/src/io/ManchesterSyntaxParser.js +398 -0
- package/src/io/OWLXMLParser.js +356 -0
- package/src/io/OntologyLoader.js +125 -0
- package/src/io/RDFGraphToOntology.js +702 -0
- package/src/io/RDFXMLParser.js +319 -0
- package/src/io/RDFXMLWriter.js +196 -0
- package/src/io/SWRLParser.js +150 -0
- package/src/io/TurtleParser.js +363 -0
- package/src/io/TurtleWriter.js +393 -0
- package/src/model/IRI.js +62 -0
- package/src/model/OWLAxiom.js +507 -0
- package/src/model/OWLClassExpression.js +242 -0
- package/src/model/OWLEntity.js +142 -0
- package/src/model/OWLLiteral.js +30 -0
- package/src/model/OWLModelManager.js +106 -0
- package/src/model/OWLOntology.js +119 -0
- package/src/model/SWRL.js +152 -0
- package/src/model/event/OWLModelManagerEvent.js +33 -0
- package/src/model/hierarchy/HierarchyProvider.js +214 -0
- package/src/profiles/OWL2Profiles.js +185 -0
- package/src/server/public/app.js +97 -0
- package/src/server/public/index.html +49 -0
- package/src/server/webServer.js +138 -0
- package/src/validation/GlobalRestrictionsValidator.js +172 -0
- package/test/core.test.js +111 -0
- package/test/exports-map.test.js +165 -0
- package/test/owl2/axioms.test.js +160 -0
- package/test/owl2/classExpressions.test.js +99 -0
- package/test/owl2/functional-syntax-writer.test.js +65 -0
- package/test/owl2/functional.test.js +113 -0
- package/test/owl2/global-restrictions.test.js +76 -0
- package/test/owl2/longtail.test.js +74 -0
- package/test/owl2/manchester-syntax.test.js +100 -0
- package/test/owl2/ontology-loader-imports.test.js +62 -0
- package/test/owl2/owlxml-parser.test.js +112 -0
- package/test/owl2/profile-reasoners.test.js +108 -0
- package/test/owl2/profiles.test.js +66 -0
- package/test/owl2/rdf-graph-to-ontology.test.js +177 -0
- package/test/owl2/rdfxml-punning.test.js +25 -0
- package/test/owl2/rdfxml-writer.test.js +55 -0
- package/test/owl2/rdfxml.test.js +91 -0
- package/test/owl2/reasoner-queries.test.js +58 -0
- package/test/owl2/sample-e2e.test.js +195 -0
- package/test/owl2/swrl-parser.test.js +60 -0
- package/test/owl2/swrl.test.js +131 -0
- package/test/owl2/turtle-writer.test.js +84 -0
- package/test/owl2/turtle.test.js +124 -0
- package/test/owl2rl/cax.test.js +57 -0
- package/test/owl2rl/cls.test.js +210 -0
- package/test/owl2rl/dt.test.js +72 -0
- package/test/owl2rl/eq.test.js +95 -0
- package/test/owl2rl/prp.test.js +198 -0
- package/test/owl2rl/scm.test.js +203 -0
package/docs/API.md
ADDED
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
# protege-js API 使用手册
|
|
2
|
+
|
|
3
|
+
完整的 OWL 2 / RDF / SWRL JavaScript 库,零依赖,可在 Node.js 和 Electron 中使用。
|
|
4
|
+
|
|
5
|
+
## 术语速览(先读这段)
|
|
6
|
+
|
|
7
|
+
为避免下文中缩写困扰,先集中解释常见缩写:
|
|
8
|
+
|
|
9
|
+
- **OWL** = **W**eb **O**ntology **L**anguage,万维网联盟(W3C, World Wide Web Consortium)制订的「本体」描述语言标准,用于形式化地定义「类」「属性」「个体」之间的关系。当前版本 OWL 2 发布于 2009/2012 年。
|
|
10
|
+
- **RDF** = **R**esource **D**escription **F**ramework,W3C 资源描述框架,把知识表达为「主语-谓语-宾语」三元组(Triple)。OWL 本体最终以 RDF 三元组存储。
|
|
11
|
+
- **RDFS** = **RDF S**chema,RDF 的最基础词汇扩展,提供 `rdfs:subClassOf`、`rdfs:label` 等。
|
|
12
|
+
- **IRI** = **I**nternationalized **R**esource **I**dentifier,国际化资源标识符,是 URI/URL 的国际化版本,允许中文字符。OWL 中一切资源(类、属性、个体、本体自身)都用 IRI 标识。
|
|
13
|
+
- **SWRL** = **S**emantic **W**eb **R**ule **L**anguage,语义网规则语言,可在 OWL 之上写「如果 ... 那么 ...」推导规则。
|
|
14
|
+
- **SPO** = **S**ubject / **P**redicate / **O**bject,三元组的三个槽位。
|
|
15
|
+
- **RL** = **R**ule **L**anguage,OWL 2 RL 是 OWL 2 的一个「基于规则的剖面(Profile)」,可以用一组 78 条规则做高效前向链推理。
|
|
16
|
+
|
|
17
|
+
## 目录
|
|
18
|
+
|
|
19
|
+
1. [核心模型](#1-核心模型)
|
|
20
|
+
2. [三元组存储 TripleStore](#2-triplestore)
|
|
21
|
+
3. [OWL 2 RL 推理](#3-owl-2-rl-推理)
|
|
22
|
+
4. [SWRL 规则推理](#4-swrl-规则推理)
|
|
23
|
+
5. [Turtle 解析器](#5-turtle-解析器)
|
|
24
|
+
6. [RDF/XML 解析器](#6-rdfxml-解析器)
|
|
25
|
+
7. [Functional-Style 解析器](#7-functional-style-解析器)
|
|
26
|
+
8. [完整示例](#8-完整示例)
|
|
27
|
+
9. [Manchester Syntax 解析器](#9-manchester-syntax-解析器)
|
|
28
|
+
10. [OWL/XML 解析器](#10-owlxml-解析器)
|
|
29
|
+
11. [Writers 序列化器](#11-writers-序列化器)
|
|
30
|
+
12. [QL / EL 推理机](#12-ql--el-推理机)
|
|
31
|
+
13. [Profile 检查与全局约束](#13-profile-检查与全局约束)
|
|
32
|
+
14. [推理查询 API](#14-推理查询-api)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 1. 核心模型
|
|
37
|
+
|
|
38
|
+
「核心模型」对应 OWL 2 结构规范(Structural Specification)的抽象语法层,把所有概念(类、属性、个体、公理、类表达式)都建成对应的 JS 类。这一层只做内存表示,不做推理。
|
|
39
|
+
|
|
40
|
+
### 1.1 IRI
|
|
41
|
+
|
|
42
|
+
**IRI** = **I**nternationalized **R**esource **I**dentifier,国际化资源标识符。它是 URI 的超集,允许出现中文字符。OWL 中每个资源(类、属性、个体、本体)都有一个唯一的 IRI 作为「身份证」。本类是不可变值对象,`IRI.create(s)` 内部有缓存,同一字符串返回同一实例。
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
const { IRI } = require('@skaterqiang/protege-js/src/model/IRI');
|
|
46
|
+
|
|
47
|
+
const iri = IRI.create('http://example.org/Person');
|
|
48
|
+
iri.toString(); // 'http://example.org/Person'
|
|
49
|
+
iri.getFragment(); // 'Person'
|
|
50
|
+
iri.getNamespace(); // 'http://example.org/'
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 1.2 实体(OWLEntity)
|
|
54
|
+
|
|
55
|
+
**OWLEntity** = **OWL Entity**,OWL 中的「具名实体」基类。OWL 把可命名的事物分为 6 种实体:
|
|
56
|
+
|
|
57
|
+
- **OWLClass**:类,比如 `Person`、`Student`,表示一组个体的集合。
|
|
58
|
+
- **OWLObjectProperty**:对象属性,连接两个个体,比如 `knows(alice, bob)`。
|
|
59
|
+
- **OWLDataProperty**:数据属性,连接个体和字面量,比如 `age(alice, "30")`。
|
|
60
|
+
- **OWLNamedIndividual**:具名个体,具体的「某个人」,比如 `alice`。
|
|
61
|
+
- **OWLDatatype**:数据类型,比如 XSD(XML Schema Definition)中的 `xsd:integer`、`xsd:string`。
|
|
62
|
+
- **OWLAnnotationProperty**:注解属性,用于给实体添加元数据(如 `rdfs:label`、`rdfs:comment`),不参与推理。
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
const {
|
|
66
|
+
OWLClass, OWLObjectProperty, OWLDataProperty,
|
|
67
|
+
OWLNamedIndividual, OWLDatatype, OWLAnnotationProperty
|
|
68
|
+
} = require('@skaterqiang/protege-js/src/model/OWLEntity');
|
|
69
|
+
|
|
70
|
+
const Person = new OWLClass(IRI.create('http://example.org/Person'));
|
|
71
|
+
const knows = new OWLObjectProperty(IRI.create('http://example.org/knows'));
|
|
72
|
+
const age = new OWLDataProperty(IRI.create('http://example.org/age'));
|
|
73
|
+
const alice = new OWLNamedIndividual(IRI.create('http://example.org/alice'));
|
|
74
|
+
const xsdInt = new OWLDatatype(IRI.create('http://www.w3.org/2001/XMLSchema#integer'));
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 1.3 字面量(OWLLiteral)
|
|
78
|
+
|
|
79
|
+
**OWLLiteral** = **OWL Literal**,OWL 字面量。字面量是「具体的值」,对应编程中的字符串、数字、日期等。OWL 字面量有三种形态:
|
|
80
|
+
|
|
81
|
+
1. **纯字符串**:`"Alice"`,隐式类型是 `xsd:string`。
|
|
82
|
+
2. **带数据类型的字面量**:`"30"^^xsd:integer`,常见于属性值。
|
|
83
|
+
3. **带语言标签的字面量**:`"你好"@zh`,用于国际化文本。
|
|
84
|
+
|
|
85
|
+
XSD = **X**ML **S**chema **D**efinition,W3C 定义的标准数据类型集(integer、string、boolean、dateTime 等)。
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
const { OWLLiteral } = require('@skaterqiang/protege-js/src/model/OWLLiteral');
|
|
89
|
+
|
|
90
|
+
const name = new OWLLiteral('Alice'); // 字符串
|
|
91
|
+
const age30 = new OWLLiteral('30', xsdInt); // 带类型
|
|
92
|
+
const title = new OWLLiteral('你好', null, 'zh'); // 带语言
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 1.4 公理(OWLAxiom)— 38 种
|
|
96
|
+
|
|
97
|
+
**OWLAxiom** = **OWL Axiom**,OWL 公理。公理是「陈述事实的一句话」,是 OWL 本体的最小可陈述单元。一个本体就是一组公理。OWL 2 规范共定义了 38 种公理,本库全部实现,按用途分为:
|
|
98
|
+
|
|
99
|
+
- **声明公理(Declaration)**:声明某个 IRI 是类/属性/个体,不带来推理效果。
|
|
100
|
+
- **类公理**:类之间的层级(SubClassOf)、等价(EquivalentClasses)、互斥(DisjointClasses)、不相交并集(DisjointUnion)。
|
|
101
|
+
- **对象属性公理**:属性的层级、等价、互斥、逆属性、定义域(Domain)、值域(Range)、属性链(PropertyChain)。
|
|
102
|
+
- **属性特性公理(7 种)**:函数性(Functional)、反函数性(InverseFunctional)、自反(Reflexive)、反自反(Irreflexive)、对称(Symmetric)、反对称(Asymmetric)、传递(Transitive)。
|
|
103
|
+
- **数据属性公理**:与对象属性对称的一组。
|
|
104
|
+
- **断言(Assertion)**:关于具体个体的事实,例如「alice 是 Person 的实例」「alice 认识 bob」。
|
|
105
|
+
- **键(HasKey)**:指定一组属性组合可以唯一标识一个类的实例。
|
|
106
|
+
- **注解公理**:对实体或公理本身附加说明文字,不参与逻辑推理。
|
|
107
|
+
|
|
108
|
+
```js
|
|
109
|
+
const AX = require('@skaterqiang/protege-js/src/model/OWLAxiom');
|
|
110
|
+
|
|
111
|
+
// 类公理
|
|
112
|
+
new AX.OWLDeclarationAxiom(Person);
|
|
113
|
+
new AX.OWLSubClassOfAxiom(Student, Person);
|
|
114
|
+
new AX.OWLEquivalentClassesAxiom([Person, Human]);
|
|
115
|
+
new AX.OWLDisjointClassesAxiom([Cat, Dog]);
|
|
116
|
+
new AX.OWLDisjointUnionAxiom(Color, [Red, Green, Blue]);
|
|
117
|
+
|
|
118
|
+
// 属性公理
|
|
119
|
+
new AX.OWLSubObjectPropertyOfAxiom(hasMother, hasParent);
|
|
120
|
+
new AX.OWLSubPropertyChainOfAxiom([hasParent, hasBrother], hasUncle);
|
|
121
|
+
new AX.OWLEquivalentObjectPropertiesAxiom([hasFather, hasDad]);
|
|
122
|
+
new AX.OWLInverseObjectPropertiesAxiom(hasParent, hasChild);
|
|
123
|
+
new AX.OWLObjectPropertyDomainAxiom(knows, Person);
|
|
124
|
+
new AX.OWLObjectPropertyRangeAxiom(knows, Person);
|
|
125
|
+
|
|
126
|
+
// 属性特性(7 种)
|
|
127
|
+
new AX.OWLFunctionalObjectPropertyAxiom(hasMother);
|
|
128
|
+
new AX.OWLInverseFunctionalObjectPropertyAxiom(isMotherOf);
|
|
129
|
+
new AX.OWLReflexiveObjectPropertyAxiom(knows);
|
|
130
|
+
new AX.OWLIrreflexiveObjectPropertyAxiom(isParentOf);
|
|
131
|
+
new AX.OWLSymmetricObjectPropertyAxiom(isSiblingOf);
|
|
132
|
+
new AX.OWLAsymmetricObjectPropertyAxiom(isParentOf);
|
|
133
|
+
new AX.OWLTransitiveObjectPropertyAxiom(hasAncestor);
|
|
134
|
+
new AX.OWLFunctionalDataPropertyAxiom(age);
|
|
135
|
+
|
|
136
|
+
// 数据属性
|
|
137
|
+
new AX.OWLSubDataPropertyOfAxiom(ageInYears, age);
|
|
138
|
+
new AX.OWLEquivalentDataPropertiesAxiom([age, years]);
|
|
139
|
+
new AX.OWLDisjointDataPropertiesAxiom([name, ssn]);
|
|
140
|
+
new AX.OWLDataPropertyDomainAxiom(age, Person);
|
|
141
|
+
new AX.OWLDataPropertyRangeAxiom(age, xsdInt);
|
|
142
|
+
|
|
143
|
+
// 个体断言
|
|
144
|
+
new AX.OWLClassAssertionAxiom(alice, Person);
|
|
145
|
+
new AX.OWLObjectPropertyAssertionAxiom(alice, knows, bob);
|
|
146
|
+
new AX.OWLDataPropertyAssertionAxiom(alice, age, age30);
|
|
147
|
+
new AX.OWLSameIndividualAxiom([alice, alicia]);
|
|
148
|
+
new AX.OWLDifferentIndividualsAxiom([alice, bob]);
|
|
149
|
+
new AX.OWLNegativeObjectPropertyAssertionAxiom(alice, knows, carol);
|
|
150
|
+
new AX.OWLNegativeDataPropertyAssertionAxiom(alice, age, age30);
|
|
151
|
+
|
|
152
|
+
// 其他
|
|
153
|
+
new AX.OWLDatatypeDefinitionAxiom(Age, xsdInt);
|
|
154
|
+
new AX.OWLHasKeyAxiom(Person, [ssn]);
|
|
155
|
+
new AX.OWLAnnotationAssertionAxiom(subjectIRI, labelProp, literal);
|
|
156
|
+
new AX.OWLSubAnnotationPropertyOfAxiom(subProp, superProp);
|
|
157
|
+
new AX.OWLAnnotationPropertyDomainAxiom(prop, iri);
|
|
158
|
+
new AX.OWLAnnotationPropertyRangeAxiom(prop, iri);
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 1.5 类表达式(OWLClassExpression)— 26 种
|
|
162
|
+
|
|
163
|
+
**OWLClassExpression** = **OWL Class Expression**,OWL 类表达式。OWL 除了能用 OWLClass 引用「具名类」之外,还能通过运算符构造「匿名类」。例如「认识 bob 的所有人」可写作 `ObjectSomeValuesFrom(knows, OneOf(bob))`。OWL 2 共定义 26 种类表达式构造器,本库全部实现:
|
|
164
|
+
|
|
165
|
+
- **命题布尔运算**:交集(IntersectionOf)、并集(UnionOf)、补集(ComplementOf)、枚举(OneOf)。
|
|
166
|
+
- **对象属性限制**:存在限制(SomeValuesFrom,「至少认识一个 Person」)、全称限制(AllValuesFrom)、值限制(HasValue)、自反限制(HasSelf)。
|
|
167
|
+
- **基数限制**:最小/最大/精确基数(Min/Max/ExactCardinality),如「最多 5 个邮箱」。
|
|
168
|
+
- **数据属性限制**:与对象限制对称的一组,但目标是数据范围。
|
|
169
|
+
- **数据范围(DataRange)**:数据类型的布尔组合、字面量枚举、限定面(FacetRestriction)——如「[0, 120] 之间的整数」。
|
|
170
|
+
|
|
171
|
+
**Facet**(限定面)是 XSD 定义的约束,如 `minInclusive` / `maxInclusive` / `length` / `pattern`。
|
|
172
|
+
|
|
173
|
+
```js
|
|
174
|
+
const CE = require('@skaterqiang/protege-js/src/model/OWLClassExpression');
|
|
175
|
+
|
|
176
|
+
// 布尔运算
|
|
177
|
+
new CE.OWLObjectIntersectionOf([A, B]);
|
|
178
|
+
new CE.OWLObjectUnionOf([A, B]);
|
|
179
|
+
new CE.OWLObjectComplementOf(A);
|
|
180
|
+
new CE.OWLObjectOneOf([alice, bob]);
|
|
181
|
+
|
|
182
|
+
// 对象限制
|
|
183
|
+
new CE.OWLObjectSomeValuesFrom(knows, Person);
|
|
184
|
+
new CE.OWLObjectAllValuesFrom(knows, Person);
|
|
185
|
+
new CE.OWLObjectHasValue(knows, bob);
|
|
186
|
+
new CE.OWLObjectHasSelf(likes);
|
|
187
|
+
|
|
188
|
+
// 基数限制
|
|
189
|
+
new CE.OWLObjectCardinalityRestriction(CE.ClassExpressionType.OBJECT_MIN_CARDINALITY, 2, hasChild, Person);
|
|
190
|
+
new CE.OWLObjectCardinalityRestriction(CE.ClassExpressionType.OBJECT_MAX_CARDINALITY, 5, hasEmail, null);
|
|
191
|
+
new CE.OWLObjectCardinalityRestriction(CE.ClassExpressionType.OBJECT_EXACT_CARDINALITY, 1, hasSSN, null);
|
|
192
|
+
|
|
193
|
+
// 数据限制
|
|
194
|
+
new CE.OWLDataSomeValuesFrom(age, xsdInt);
|
|
195
|
+
new CE.OWLDataAllValuesFrom(age, xsdInt);
|
|
196
|
+
new CE.OWLDataHasValue(age, age30);
|
|
197
|
+
new CE.OWLDataCardinalityRestriction(CE.ClassExpressionType.DATA_MIN_CARDINALITY, 1, age, null);
|
|
198
|
+
|
|
199
|
+
// 数据范围
|
|
200
|
+
new CE.OWLDataIntersectionOf([dt1, dt2]);
|
|
201
|
+
new CE.OWLDataUnionOf([dt1, dt2]);
|
|
202
|
+
new CE.OWLDataComplementOf(dt);
|
|
203
|
+
new CE.OWLDataOneOf([lit1, lit2]);
|
|
204
|
+
new CE.OWLDatatypeRestriction(xsdInt, [
|
|
205
|
+
{ facet: IRI.create('http://www.w3.org/2001/XMLSchema#minInclusive'), value: new OWLLiteral('0') },
|
|
206
|
+
{ facet: IRI.create('http://www.w3.org/2001/XMLSchema#maxInclusive'), value: new OWLLiteral('120') }
|
|
207
|
+
]);
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## 2. TripleStore
|
|
213
|
+
|
|
214
|
+
**TripleStore** = 三元组存储,RDF 数据的内存容器。RDF = Resource Description Framework,把所有事实表达为「主语-谓语-宾语」三元组(SPO)。例如 `⟨alice, rdf:type, Person⟩` 表示「alice 是一个 Person」。本实现使用索引化哈希表,支持任意槽位的通配查询。
|
|
215
|
+
|
|
216
|
+
**NS** = **N**ame**s**pace,命名空间常量集合。RDF/RDFS/OWL/XSD 都预定义了一组词汇 IRI 前缀,此处集中导出避免硬编码。
|
|
217
|
+
|
|
218
|
+
```js
|
|
219
|
+
const { TripleStore } = require('@skaterqiang/protege-js/src/inference/TripleStore');
|
|
220
|
+
const { NS } = require('@skaterqiang/protege-js/src/inference/rdf');
|
|
221
|
+
|
|
222
|
+
const store = new TripleStore();
|
|
223
|
+
|
|
224
|
+
// 添加
|
|
225
|
+
store.add(subject, predicate, object);
|
|
226
|
+
|
|
227
|
+
// 查询(任一参数传 null 表示通配)
|
|
228
|
+
store.match(s, p, o); // → [[s,p,o], ...]
|
|
229
|
+
store.match(null, NS.RDF + 'type', 'http://example.org/Person'); // 找所有 Person
|
|
230
|
+
|
|
231
|
+
// 单值查询
|
|
232
|
+
store.objects(s, p); // → [o1, o2, ...]
|
|
233
|
+
store.subjects(p, o); // → [s1, s2, ...]
|
|
234
|
+
|
|
235
|
+
// RDF List(用于 owl:unionOf / owl:intersectionOf 等)
|
|
236
|
+
store.listElements(listHead); // → [item1, item2, ...]
|
|
237
|
+
|
|
238
|
+
// 命名空间常量
|
|
239
|
+
NS.RDF // http://www.w3.org/1999/02/22-rdf-syntax-ns#
|
|
240
|
+
NS.RDFS // http://www.w3.org/2000/01/rdf-schema#
|
|
241
|
+
NS.OWL // http://www.w3.org/2002/07/owl#
|
|
242
|
+
NS.XSD // http://www.w3.org/2001/XMLSchema#
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## 3. OWL 2 RL 推理
|
|
248
|
+
|
|
249
|
+
**OWL 2 RL** = **OWL 2 R**ule **L**anguage,W3C 定义的 OWL 2 三个「剖面」之一,专为「可以用规则引擎高效实现」的子集。该剖面把 OWL 2 语义改写为 78 条 if-then 规则(pD* 语义),通过**前向链物化(Forward-Chaining Materialization)**反复触发规则直到不再有新事实(不动点,fixpoint),从而推出所有蕴含的三元组。
|
|
250
|
+
|
|
251
|
+
**物化(Materialization)**指把所有可推出的事实真正写入存储,之后查询 O(1)。这与「反向链/查询时推理」相对。
|
|
252
|
+
|
|
253
|
+
```js
|
|
254
|
+
const { OWL2RLReasoner } = require('@skaterqiang/protege-js/src/inference/OWL2RLReasoner');
|
|
255
|
+
|
|
256
|
+
const r = new OWL2RLReasoner();
|
|
257
|
+
|
|
258
|
+
// 直接往 store 加三元组
|
|
259
|
+
r.store.add('ex:A', NS.RDFS + 'subClassOf', 'ex:B');
|
|
260
|
+
r.store.add('ex:x', NS.RDF + 'type', 'ex:A');
|
|
261
|
+
|
|
262
|
+
// 运行推理(fixpoint,自动终止)
|
|
263
|
+
const { added, rounds } = r.materialize();
|
|
264
|
+
|
|
265
|
+
// 查询蕴含
|
|
266
|
+
r.entails('ex:x', NS.RDF + 'type', 'ex:B'); // true
|
|
267
|
+
|
|
268
|
+
// 一致性检查
|
|
269
|
+
r.isConsistent(); // true / false
|
|
270
|
+
r.inconsistencies; // 不一致的三元组列表
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
支持规则类别:等值推理(eq)、属性推理(prp)、类表达式(cls)、类断言(cax)、数据类型(dt)、模式公理(scm)。
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## 4. SWRL 规则推理
|
|
278
|
+
|
|
279
|
+
**SWRL** = **S**emantic **W**eb **R**ule **L**anguage,语义网规则语言。它在 OWL 之上扩展了一阶规则能力:可以写「如果 x 是 Person 且 x 的父亲有兄弟 y,则 y 是 x 的叔叔」这类 OWL 本身表达不了的规则。SWRL 与 OWL 2 RL 的区别是:RL 是「受限的、可完全物化」的规则集,SWRL 是「表达力更强但不可判定」的通用规则。
|
|
280
|
+
|
|
281
|
+
**Atom**(原子)是规则中的最小谓词,例如 `Person(?x)`、`hasParent(?x,?y)`。本库实现 7 种原子类型。
|
|
282
|
+
|
|
283
|
+
**Built-in**(内置函数)是 SWRL 预定义的比较/算术/字符串函数,命名空间 `http://www.w3.org/2003/11/swrlb#`。
|
|
284
|
+
|
|
285
|
+
```js
|
|
286
|
+
const {
|
|
287
|
+
SWRLRule, SWRLClassAtom, SWRLObjectPropertyAtom,
|
|
288
|
+
SWRLDataPropertyAtom, SWRLBuiltInAtom, SWRLVariable
|
|
289
|
+
} = require('@skaterqiang/protege-js/src/model/SWRL');
|
|
290
|
+
const { SWRLReasoner } = require('@skaterqiang/protege-js/src/inference/SWRLReasoner');
|
|
291
|
+
|
|
292
|
+
// 变量(URI 格式 urn:swrl:var:NAME)
|
|
293
|
+
const vx = new SWRLVariable(IRI.create('urn:swrl:var:x'));
|
|
294
|
+
|
|
295
|
+
// 构造规则: Person(?x) ∧ hasParent(?x,?y) ∧ hasBrother(?y,?z) → hasUncle(?x,?z)
|
|
296
|
+
const rule = new SWRLRule(
|
|
297
|
+
[
|
|
298
|
+
new SWRLClassAtom(Person, vx),
|
|
299
|
+
new SWRLObjectPropertyAtom(hasParent, vx, vy),
|
|
300
|
+
new SWRLObjectPropertyAtom(hasBrother, vy, vz)
|
|
301
|
+
],
|
|
302
|
+
[new SWRLObjectPropertyAtom(hasUncle, vx, vz)]
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
// 推理
|
|
306
|
+
const store = new TripleStore();
|
|
307
|
+
store.add('ex:a', NS.RDF + 'type', 'ex:Person');
|
|
308
|
+
store.add('ex:a', 'ex:hasParent', 'ex:b');
|
|
309
|
+
store.add('ex:b', 'ex:hasBrother', 'ex:c');
|
|
310
|
+
|
|
311
|
+
const r = new SWRLReasoner(store);
|
|
312
|
+
const added = r.run([rule]); // → 1 (新增 hasUncle 三元组)
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### 内置函数(30+)
|
|
316
|
+
|
|
317
|
+
```js
|
|
318
|
+
const { SWRLBuiltins } = require('@skaterqiang/protege-js/src/inference/SWRLReasoner');
|
|
319
|
+
|
|
320
|
+
SWRLBuiltins.call('equal', [5, 5]); // true
|
|
321
|
+
SWRLBuiltins.call('lessThan', [3, 7]); // true
|
|
322
|
+
SWRLBuiltins.call('add', [2, 3]); // 5
|
|
323
|
+
SWRLBuiltins.call('multiply', [4, 5]); // 20
|
|
324
|
+
SWRLBuiltins.call('upperCase', ['abc']); // 'ABC'
|
|
325
|
+
SWRLBuiltins.call('stringLength', ['hello']); // 5
|
|
326
|
+
SWRLBuiltins.call('contains', ['hello world', 'world']); // true
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
支持:比较(equal/notEqual/lessThan/…)、算术(add/subtract/multiply/divide/mod/pow/abs/ceiling/floor/round/roundHalfToEven/sqrt/sin/cos/tan)、字符串(concat/substring/length/upperCase/lowerCase/contains/startsWith/endsWith/matches/replace)。
|
|
330
|
+
|
|
331
|
+
### SWRL 原子类型(7 种)
|
|
332
|
+
|
|
333
|
+
原子是 SWRL 规则的组成部分。每种原子对应 OWL 中一种可匹配的事实类型:
|
|
334
|
+
|
|
335
|
+
| 类型 | 构造器 | 说明 |
|
|
336
|
+
|------|--------|------|
|
|
337
|
+
| ClassAtom | `new SWRLClassAtom(classExpr, arg)` | 类成员 |
|
|
338
|
+
| ObjectPropertyAtom | `new SWRLObjectPropertyAtom(prop, s, o)` | 对象属性 |
|
|
339
|
+
| DataPropertyAtom | `new SWRLDataPropertyAtom(prop, s, v)` | 数据属性 |
|
|
340
|
+
| SameAsAtom | `new SWRLSameAsAtom(a, b)` | 同一性 |
|
|
341
|
+
| DifferentFromAtom | `new SWRLDifferentFromAtom(a, b)` | 不同性 |
|
|
342
|
+
| BuiltInAtom | `new SWRLBuiltInAtom(builtinIRI, args)` | 内置函数 |
|
|
343
|
+
| DataRangeAtom | `new SWRLDataRangeAtom(range, arg)` | 数据范围 |
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## 5. Turtle 解析器
|
|
348
|
+
|
|
349
|
+
**Turtle** = **T**erse **R**DF **T**riple **L**anguage,W3C RDF 的一种紧凑文本语法,是当前最常用的 RDF 书写格式(比 RDF/XML 可读性高得多)。文件后缀通常为 `.ttl`。
|
|
350
|
+
|
|
351
|
+
```js
|
|
352
|
+
const { TurtleParser } = require('@skaterqiang/protege-js/src/io/TurtleParser');
|
|
353
|
+
|
|
354
|
+
const store = new TurtleParser().parse(`
|
|
355
|
+
@prefix ex: <http://example.org/> .
|
|
356
|
+
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
|
357
|
+
|
|
358
|
+
ex:alice a foaf:Person ;
|
|
359
|
+
foaf:name "Alice" ;
|
|
360
|
+
foaf:age 30 ;
|
|
361
|
+
foaf:knows ex:bob, ex:carol .
|
|
362
|
+
|
|
363
|
+
ex:bob a foaf:Person ;
|
|
364
|
+
foaf:interest [ a foaf:Document ; foaf:title "RDF Primer" ] .
|
|
365
|
+
`);
|
|
366
|
+
|
|
367
|
+
store.match(null, NS.RDF + 'type', null); // 所有类型断言
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
支持语法:
|
|
371
|
+
- `@prefix` / `@base` / `PREFIX` / `BASE`
|
|
372
|
+
- `a` 缩写(rdf:type)
|
|
373
|
+
- `;` 同一主语多谓语、`,` 同一谓语多宾语
|
|
374
|
+
- 字符串 `"..."` / `'...'` / `"""..."""` / `'''...'''`
|
|
375
|
+
- 类型化字面量 `"30"^^xsd:integer`、语言标签 `"hello"@en`
|
|
376
|
+
- 数字自动类型化(`42` → integer、`3.14` → decimal、`1e3` → double)
|
|
377
|
+
- 布尔 `true` / `false`
|
|
378
|
+
- 空白节点 `[ ... ]`、集合 `( ... )`
|
|
379
|
+
- 注释 `# ...`
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## 6. RDF/XML 解析器
|
|
384
|
+
|
|
385
|
+
**RDF/XML** 是 RDF 的原始 XML 序列化语法(W3C 1999/2004),是早期 OWL 工具(如 Protégé 4-)的默认保存格式。文件后缀通常为 `.owl` 或 `.rdf`。XML 冗余但工具链成熟。
|
|
386
|
+
|
|
387
|
+
**OWL 本体文档**常以 RDF/XML 形式分发,本解析器同时识别 `<owl:Class>` 元素式与 `<rdf:Description>` + `<rdf:type>` 描述式两种风格。
|
|
388
|
+
|
|
389
|
+
```js
|
|
390
|
+
const { parseRDFXML } = require('@skaterqiang/protege-js/src/io/RDFXMLParser');
|
|
391
|
+
|
|
392
|
+
const ont = parseRDFXML(`<?xml version="1.0"?>
|
|
393
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
394
|
+
xmlns:owl="http://www.w3.org/2002/07/owl#"
|
|
395
|
+
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
|
|
396
|
+
xmlns:ex="http://example.org/">
|
|
397
|
+
|
|
398
|
+
<owl:Class rdf:about="http://example.org/Student">
|
|
399
|
+
<rdfs:subClassOf rdf:resource="http://example.org/Person"/>
|
|
400
|
+
<owl:disjointWith rdf:resource="http://example.org/Teacher"/>
|
|
401
|
+
</owl:Class>
|
|
402
|
+
|
|
403
|
+
<owl:ObjectProperty rdf:about="http://example.org/hasAncestor">
|
|
404
|
+
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#TransitiveProperty"/>
|
|
405
|
+
</owl:ObjectProperty>
|
|
406
|
+
|
|
407
|
+
<owl:NamedIndividual rdf:about="http://example.org/alice">
|
|
408
|
+
<rdf:type rdf:resource="http://example.org/Student"/>
|
|
409
|
+
<owl:sameAs rdf:resource="http://example.org/alicia"/>
|
|
410
|
+
</owl:NamedIndividual>
|
|
411
|
+
</rdf:RDF>`);
|
|
412
|
+
|
|
413
|
+
ont.getAxioms(); // → 所有解析出的公理
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
识别元素:
|
|
417
|
+
- `<owl:Class>` / `<owl:ObjectProperty>` / `<owl:DatatypeProperty>` / `<owl:NamedIndividual>` / `<rdf:Description>`
|
|
418
|
+
- 关系:`rdfs:subClassOf` / `owl:equivalentClass` / `owl:disjointWith` / `rdfs:subPropertyOf` / `owl:inverseOf` / `rdfs:domain` / `rdfs:range` / `rdf:type` / `owl:sameAs` / `owl:differentFrom`
|
|
419
|
+
- 特性:`owl:FunctionalProperty` / `InverseFunctionalProperty` / `TransitiveProperty` / `SymmetricProperty` / `AsymmetricProperty` / `ReflexiveProperty` / `IrreflexiveProperty`
|
|
420
|
+
- 注解:`rdfs:label` / `rdfs:comment`
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
## 7. Functional-Style 解析器
|
|
425
|
+
|
|
426
|
+
**Functional-Style Syntax**(函数式语法)是 OWL 2 规范文档本身使用的「权威语法」,用类似 Lisp 的 S 表达式书写公理,例如 `SubClassOf(Student Person)`。它的优势是结构严谨、与规范文法一一对应,常用于规范文档、测试套件、工具间交换。Manchester Syntax 是另一种以它为基准设计的「人类友好」语法。
|
|
427
|
+
|
|
428
|
+
```js
|
|
429
|
+
const { FunctionalSyntaxParser } = require('@skaterqiang/protege-js/src/io/FunctionalSyntaxParser');
|
|
430
|
+
|
|
431
|
+
const ont = new FunctionalSyntaxParser().parse(`
|
|
432
|
+
Prefix(ex:=<http://example.org/>)
|
|
433
|
+
Prefix(xsd:=<http://www.w3.org/2001/XMLSchema#>)
|
|
434
|
+
|
|
435
|
+
Ontology(<http://example.org/ont>
|
|
436
|
+
Declaration(Class(ex:Person))
|
|
437
|
+
Declaration(ObjectProperty(ex:knows))
|
|
438
|
+
Declaration(DataProperty(ex:age))
|
|
439
|
+
|
|
440
|
+
SubClassOf(ex:Student ex:Person)
|
|
441
|
+
DisjointUnion(ex:Color ex:Red ex:Green ex:Blue)
|
|
442
|
+
|
|
443
|
+
TransitiveObjectProperty(ex:hasAncestor)
|
|
444
|
+
SubObjectPropertyOf(ObjectPropertyChain(ex:hasParent ex:hasBrother) ex:hasUncle)
|
|
445
|
+
|
|
446
|
+
ClassAssertion(ex:Person ex:alice)
|
|
447
|
+
DataPropertyAssertion(ex:age ex:alice "30"^^xsd:integer)
|
|
448
|
+
|
|
449
|
+
HasKey(ex:Person ex:ssn)
|
|
450
|
+
SameIndividual(ex:alice ex:alicia)
|
|
451
|
+
)
|
|
452
|
+
`);
|
|
453
|
+
|
|
454
|
+
ont.getAxiomCount(); // 12
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
支持所有 37 种公理形式、所有类表达式和数据范围。
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
## 8. 完整示例
|
|
462
|
+
|
|
463
|
+
### 8.1 从 Turtle 加载 + OWL 2 RL 推理
|
|
464
|
+
|
|
465
|
+
```js
|
|
466
|
+
const { TurtleParser } = require('@skaterqiang/protege-js/src/io/TurtleParser');
|
|
467
|
+
const { OWL2RLReasoner } = require('@skaterqiang/protege-js/src/inference/OWL2RLReasoner');
|
|
468
|
+
const { NS } = require('@skaterqiang/protege-js/src/inference/rdf');
|
|
469
|
+
|
|
470
|
+
const ttl = `
|
|
471
|
+
@prefix ex: <http://example.org/> .
|
|
472
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
|
473
|
+
|
|
474
|
+
ex:Student rdfs:subClassOf ex:Person .
|
|
475
|
+
ex:alice a ex:Student .
|
|
476
|
+
`;
|
|
477
|
+
|
|
478
|
+
const r = new OWL2RLReasoner();
|
|
479
|
+
new TurtleParser().parse(ttl, r.store); // 填充三元组
|
|
480
|
+
r.materialize();
|
|
481
|
+
|
|
482
|
+
r.entails('http://example.org/alice', NS.RDF + 'type', 'http://example.org/Person'); // true
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### 8.2 SWRL 规则链
|
|
486
|
+
|
|
487
|
+
```js
|
|
488
|
+
const { SWRLRule, SWRLClassAtom, SWRLObjectPropertyAtom, SWRLDataPropertyAtom, SWRLBuiltInAtom, SWRLVariable } = require('@skaterqiang/protege-js/src/model/SWRL');
|
|
489
|
+
const { SWRLReasoner } = require('@skaterqiang/protege-js/src/inference/SWRLReasoner');
|
|
490
|
+
|
|
491
|
+
const v = (n) => new SWRLVariable(IRI.create('urn:swrl:var:' + n));
|
|
492
|
+
|
|
493
|
+
const rules = [
|
|
494
|
+
// 叔叔规则
|
|
495
|
+
new SWRLRule(
|
|
496
|
+
[new SWRLObjectPropertyAtom(hasParent, v('x'), v('y')),
|
|
497
|
+
new SWRLObjectPropertyAtom(hasBrother, v('y'), v('z'))],
|
|
498
|
+
[new SWRLObjectPropertyAtom(hasUncle, v('x'), v('z'))]
|
|
499
|
+
),
|
|
500
|
+
// 成年规则(≥18)
|
|
501
|
+
new SWRLRule(
|
|
502
|
+
[new SWRLDataPropertyAtom(age, v('p'), v('a')),
|
|
503
|
+
new SWRLBuiltInAtom(IRI.create('http://www.w3.org/2003/11/swrlb#greaterThanOrEqual'),
|
|
504
|
+
[v('a'), { lexicalValue: '18', datatype: { iri: IRI.create(NS.XSD + 'integer') } }])],
|
|
505
|
+
[new SWRLClassAtom(Adult, v('p'))]
|
|
506
|
+
)
|
|
507
|
+
];
|
|
508
|
+
|
|
509
|
+
const r = new SWRLReasoner(store);
|
|
510
|
+
r.run(rules); // fixpoint,自动终止
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
### 8.3 Functional 语法 → 模型 → RL 推理
|
|
514
|
+
|
|
515
|
+
```js
|
|
516
|
+
const { FunctionalSyntaxParser } = require('@skaterqiang/protege-js/src/io/FunctionalSyntaxParser');
|
|
517
|
+
const { OWL2RLReasoner } = require('@skaterqiang/protege-js/src/inference/OWL2RLReasoner');
|
|
518
|
+
|
|
519
|
+
const ont = new FunctionalSyntaxParser().parse(`
|
|
520
|
+
Ontology(
|
|
521
|
+
SubClassOf(<http://x/Student> <http://x/Person>)
|
|
522
|
+
ClassAssertion(<http://x/Student> <http://x/alice>)
|
|
523
|
+
)
|
|
524
|
+
`);
|
|
525
|
+
|
|
526
|
+
// 公理 → 三元组 → RL 推理
|
|
527
|
+
const r = new OWL2RLReasoner();
|
|
528
|
+
for (const ax of ont.getAxioms()) {
|
|
529
|
+
if (ax.getAxiomType() === 'SubClassOf') {
|
|
530
|
+
r.store.add(ax.subClass.getIRI().toString(), NS.RDFS + 'subClassOf', ax.superClass.getIRI().toString());
|
|
531
|
+
}
|
|
532
|
+
if (ax.getAxiomType() === 'ClassAssertion') {
|
|
533
|
+
r.store.add(ax.individual.getIRI().toString(), NS.RDF + 'type', ax.classExpression.getIRI().toString());
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
r.materialize();
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
---
|
|
540
|
+
|
|
541
|
+
## 测试
|
|
542
|
+
|
|
543
|
+
```bash
|
|
544
|
+
npm test # 256 个测试全部通过
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
覆盖:86 个 OWL 2 RL 规则测试 + 170 个全规范测试(axioms / classExpressions / turtle / functional / rdfxml / swrl / manchester / owlxml / writers / profiles / punning / longtail)。
|
|
548
|
+
|
|
549
|
+
---
|
|
550
|
+
|
|
551
|
+
## 9. Manchester Syntax 解析器
|
|
552
|
+
|
|
553
|
+
解析 Protégé 风格的 Manchester Syntax 帧语法。
|
|
554
|
+
|
|
555
|
+
```js
|
|
556
|
+
const { ManchesterSyntaxParser } = require('@skaterqiang/protege-js/src/io/ManchesterSyntaxParser');
|
|
557
|
+
const ont = new ManchesterSyntaxParser({ prefixes: { ex: 'http://ex.org/' } }).parse(`
|
|
558
|
+
Prefix: ex: <http://ex.org/>
|
|
559
|
+
Class: ex:Person
|
|
560
|
+
SubClassOf: ex:Animal
|
|
561
|
+
EquivalentTo: ex:hasParent some ex:Person
|
|
562
|
+
ObjectProperty: ex:hasParent
|
|
563
|
+
Domain: ex:Person
|
|
564
|
+
Range: ex:Person
|
|
565
|
+
Characteristics: Transitive
|
|
566
|
+
Individual: ex:alice
|
|
567
|
+
Types: ex:Person
|
|
568
|
+
`);
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
支持的帧关键字:`SubClassOf` / `EquivalentTo` / `DisjointWith` / `DisjointUnionOf` / `HasKey` / `Domain` / `Range` / `Characteristics` / `InverseOf` / `SubPropertyOf` / `SubPropertyChain` / `Types` / `SameAs` / `DifferentFrom` / `Facts`。
|
|
572
|
+
|
|
573
|
+
类表达式关键字:`some` / `only` / `value` / `Self` / `min` / `max` / `exactly` / `and` / `or` / `not` / `{a, b, c}`。
|
|
574
|
+
|
|
575
|
+
## 10. OWL/XML 解析器
|
|
576
|
+
|
|
577
|
+
解析 W3C OWL 2 XML Serialization(与 RDF/XML 不同的另一种 XML 语法)。
|
|
578
|
+
|
|
579
|
+
```js
|
|
580
|
+
const { OWLXMLParser } = require('@skaterqiang/protege-js/src/io/OWLXMLParser');
|
|
581
|
+
const ont = new OWLXMLParser().parse(`<Ontology xmlns="http://www.w3.org/2002/07/owl#" ontologyIRI="http://ex.org/ont">
|
|
582
|
+
<Prefix name="ex" IRI="http://ex.org/"/>
|
|
583
|
+
<Declaration><Class IRI="http://ex.org/Person"/></Declaration>
|
|
584
|
+
<SubClassOf>
|
|
585
|
+
<Class IRI="http://ex.org/Student"/>
|
|
586
|
+
<Class IRI="http://ex.org/Person"/>
|
|
587
|
+
</SubClassOf>
|
|
588
|
+
</Ontology>`);
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
覆盖约 30 种公理元素与全部类表达式(含带基数的 `ObjectMin/Max/ExactCardinality`)和数据范围(含 `DatatypeRestriction`)。
|
|
592
|
+
|
|
593
|
+
## 11. Writers 序列化器
|
|
594
|
+
|
|
595
|
+
把 OWLOntology 写回各种语法,支持 round-trip(加载 → 修改 → 保存)。
|
|
596
|
+
|
|
597
|
+
```js
|
|
598
|
+
const { FunctionalSyntaxWriter, writeFunctionalSyntax } = require('@skaterqiang/protege-js/src/io/FunctionalSyntaxWriter');
|
|
599
|
+
const { TurtleWriter, writeTurtle } = require('@skaterqiang/protege-js/src/io/TurtleWriter');
|
|
600
|
+
const { RDFXMLWriter, writeRDFXML } = require('@skaterqiang/protege-js/src/io/RDFXMLWriter');
|
|
601
|
+
|
|
602
|
+
const fsText = writeFunctionalSyntax(ont); // Functional-Style Syntax
|
|
603
|
+
const ttlText = writeTurtle(ont); // Turtle(含 @prefix、blank node restriction)
|
|
604
|
+
const xmlText = writeRDFXML(ont); // RDF/XML
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
前缀保真:若解析时通过 `Prefix:` / `Prefix(...)` 声明了前缀,三者都会用 `ont.getPrefixes()` 中的缩写输出。
|
|
608
|
+
|
|
609
|
+
## 12. QL / EL 推理机
|
|
610
|
+
|
|
611
|
+
OWL 2 三个 profile 中的 QL(查询重写优化)与 EL(多项式分类)的最小实现,基于 RL 规则子集。
|
|
612
|
+
|
|
613
|
+
```js
|
|
614
|
+
const { OWL2QLReasoner, OWL2ELReasoner } = require('@skaterqiang/protege-js/src/inference/OWL2ProfileReasoners');
|
|
615
|
+
|
|
616
|
+
const ql = new OWL2QLReasoner(store); // 14 条 QL 规则(无 eq-*/prp-fp/ifp)
|
|
617
|
+
ql.materialize();
|
|
618
|
+
ql.entails('ex:x', NS.RDF + 'type', 'ex:B');
|
|
619
|
+
|
|
620
|
+
const el = new OWL2ELReasoner(store); // 14 条 EL 规则(含 prp-trp 传递性)
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
## 13. Profile 检查与全局约束
|
|
624
|
+
|
|
625
|
+
```js
|
|
626
|
+
const { checkRL, checkQL, checkEL, Profiles } = require('@skaterqiang/protege-js/src/profiles/OWL2Profiles');
|
|
627
|
+
const violations = checkRL(ont); // [{axiom, reason}, ...]
|
|
628
|
+
|
|
629
|
+
const { GlobalRestrictionsValidator } = require('@skaterqiang/protege-js/src/validation/GlobalRestrictionsValidator');
|
|
630
|
+
const errs = new GlobalRestrictionsValidator().validate(ont); // 正则性 / simple property 检查
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
## 14. 推理查询 API
|
|
634
|
+
|
|
635
|
+
```js
|
|
636
|
+
const { ReasonerQueries } = require('@skaterqiang/protege-js/src/inference/ReasonerQueries');
|
|
637
|
+
const q = new ReasonerQueries(store);
|
|
638
|
+
q.getSubClasses('ex:Animal');
|
|
639
|
+
q.getInstances('ex:Person');
|
|
640
|
+
q.isSubClassOf('ex:Student', 'ex:Person');
|
|
641
|
+
q.isSatisfiable('ex:Nothing');
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
## 规范引用
|
|
645
|
+
|
|
646
|
+
- [OWL 2 Structural Specification](https://www.w3.org/TR/owl2-syntax/) — OWL 2 结构规范,定义所有公理与类表达式
|
|
647
|
+
- [OWL 2 Profiles](https://www.w3.org/TR/owl2-profiles/) — RL / QL / EL 三个剖面
|
|
648
|
+
- [OWL 2 Functional-Style Syntax](https://www.w3.org/TR/owl2-syntax/#Functional-Style_Syntax) — 函数式语法文法
|
|
649
|
+
- [OWL 2 Manchester Syntax](https://www.w3.org/TR/owl2-manchester-syntax/) — Manchester 语法(供参考)
|
|
650
|
+
- [SWRL Submission](https://www.w3.org/Submission/SWRL/) — SWRL 规则语言
|
|
651
|
+
- [Turtle 1.1](https://www.w3.org/TR/turtle/) — Turtle 语法
|
|
652
|
+
- [RDF/XML](https://www.w3.org/TR/rdf-syntax-grammar/) — RDF/XML 语法
|
|
653
|
+
- [RDF 1.1 Concepts](https://www.w3.org/TR/rdf11-concepts/) — RDF 核心概念
|
|
654
|
+
- [XML Schema Datatypes](https://www.w3.org/TR/xmlschema-2/) — XSD 数据类型
|