@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.
Files changed (92) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/LICENSE +48 -0
  3. package/README.md +287 -0
  4. package/docs/API.md +654 -0
  5. package/docs/design/OWL2-/347/274/272/345/217/243/345/210/206/346/236/220.md +140 -0
  6. package/docs/owl2-rl/OWL2-RL-/350/247/204/345/210/231/347/273/206/345/210/231.md +168 -0
  7. package/docs/owl2-rl/owl2-profiles-spec-zh.html +1914 -0
  8. package/docs/owl2-rl/owl2-profiles-spec.html +1916 -0
  9. package/docs/owl2-rl/rl_rules.json +392 -0
  10. package/main.js +46 -0
  11. package/package.json +76 -0
  12. package/sample/README.md +74 -0
  13. package/sample/case1-ecommerce-risk.js +170 -0
  14. package/sample/case10-ecommerce-customer-service.js +454 -0
  15. package/sample/case2-family-swrl.js +147 -0
  16. package/sample/case3-pharma-safety.js +132 -0
  17. package/sample/case4-knowledge-publishing.js +111 -0
  18. package/sample/case5-obda-profiles.js +153 -0
  19. package/sample/case6-medical-ontology.js +152 -0
  20. package/sample/case7-manufacturing-ppr.js +155 -0
  21. package/sample/case8-real-medical-bfo-ogms.js +353 -0
  22. package/sample/case9-real-manufacturing-iao.js +360 -0
  23. package/sample/ontologies/bfo.owl +1715 -0
  24. package/sample/ontologies/iao.owl +8532 -0
  25. package/sample/ontologies/ogms.owl +4320 -0
  26. package/sample/ontologies/ro-core.owl +1010 -0
  27. package/scripts/verify-api.js +53 -0
  28. package/src/index.js +176 -0
  29. package/src/inference/OWL2ProfileReasoners.js +67 -0
  30. package/src/inference/OWL2RLReasoner.js +65 -0
  31. package/src/inference/ReasonerQueries.js +111 -0
  32. package/src/inference/SWRLReasoner.js +409 -0
  33. package/src/inference/TripleStore.js +82 -0
  34. package/src/inference/rdf.js +83 -0
  35. package/src/inference/rules/owl2el.js +33 -0
  36. package/src/inference/rules/owl2ql.js +29 -0
  37. package/src/inference/rules/owl2rl.js +823 -0
  38. package/src/io/FunctionalSyntaxParser.js +399 -0
  39. package/src/io/FunctionalSyntaxWriter.js +180 -0
  40. package/src/io/ManchesterSyntaxParser.js +398 -0
  41. package/src/io/OWLXMLParser.js +356 -0
  42. package/src/io/OntologyLoader.js +125 -0
  43. package/src/io/RDFGraphToOntology.js +702 -0
  44. package/src/io/RDFXMLParser.js +319 -0
  45. package/src/io/RDFXMLWriter.js +196 -0
  46. package/src/io/SWRLParser.js +150 -0
  47. package/src/io/TurtleParser.js +363 -0
  48. package/src/io/TurtleWriter.js +393 -0
  49. package/src/model/IRI.js +62 -0
  50. package/src/model/OWLAxiom.js +507 -0
  51. package/src/model/OWLClassExpression.js +242 -0
  52. package/src/model/OWLEntity.js +142 -0
  53. package/src/model/OWLLiteral.js +30 -0
  54. package/src/model/OWLModelManager.js +106 -0
  55. package/src/model/OWLOntology.js +119 -0
  56. package/src/model/SWRL.js +152 -0
  57. package/src/model/event/OWLModelManagerEvent.js +33 -0
  58. package/src/model/hierarchy/HierarchyProvider.js +214 -0
  59. package/src/profiles/OWL2Profiles.js +185 -0
  60. package/src/server/public/app.js +97 -0
  61. package/src/server/public/index.html +49 -0
  62. package/src/server/webServer.js +138 -0
  63. package/src/validation/GlobalRestrictionsValidator.js +172 -0
  64. package/test/core.test.js +111 -0
  65. package/test/exports-map.test.js +165 -0
  66. package/test/owl2/axioms.test.js +160 -0
  67. package/test/owl2/classExpressions.test.js +99 -0
  68. package/test/owl2/functional-syntax-writer.test.js +65 -0
  69. package/test/owl2/functional.test.js +113 -0
  70. package/test/owl2/global-restrictions.test.js +76 -0
  71. package/test/owl2/longtail.test.js +74 -0
  72. package/test/owl2/manchester-syntax.test.js +100 -0
  73. package/test/owl2/ontology-loader-imports.test.js +62 -0
  74. package/test/owl2/owlxml-parser.test.js +112 -0
  75. package/test/owl2/profile-reasoners.test.js +108 -0
  76. package/test/owl2/profiles.test.js +66 -0
  77. package/test/owl2/rdf-graph-to-ontology.test.js +177 -0
  78. package/test/owl2/rdfxml-punning.test.js +25 -0
  79. package/test/owl2/rdfxml-writer.test.js +55 -0
  80. package/test/owl2/rdfxml.test.js +91 -0
  81. package/test/owl2/reasoner-queries.test.js +58 -0
  82. package/test/owl2/sample-e2e.test.js +195 -0
  83. package/test/owl2/swrl-parser.test.js +60 -0
  84. package/test/owl2/swrl.test.js +131 -0
  85. package/test/owl2/turtle-writer.test.js +84 -0
  86. package/test/owl2/turtle.test.js +124 -0
  87. package/test/owl2rl/cax.test.js +57 -0
  88. package/test/owl2rl/cls.test.js +210 -0
  89. package/test/owl2rl/dt.test.js +72 -0
  90. package/test/owl2rl/eq.test.js +95 -0
  91. package/test/owl2rl/prp.test.js +198 -0
  92. package/test/owl2rl/scm.test.js +203 -0
@@ -0,0 +1,393 @@
1
+ 'use strict';
2
+
3
+ // ---------------------------------------------------------------------------
4
+ // io/TurtleWriter — serialize an OWLOntology to Turtle (W3C Mapping to RDF
5
+ // Graphs, forward direction). Round-trip capable with TurtleParser +
6
+ // RDFGraphToOntology.
7
+ // ---------------------------------------------------------------------------
8
+
9
+ const { ClassExpressionType: T } = require('../model/OWLClassExpression');
10
+ const { AxiomType: A } = require('../model/OWLAxiom');
11
+
12
+ const RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
13
+ const RDFS = 'http://www.w3.org/2000/01/rdf-schema#';
14
+ const OWL = 'http://www.w3.org/2002/07/owl#';
15
+ const XSD = 'http://www.w3.org/2001/XMLSchema#';
16
+
17
+ function iri(x) {
18
+ const s = x && x.getIRI ? x.getIRI().toString() : String(x);
19
+ return `<${s}>`;
20
+ }
21
+
22
+ function lit(l) {
23
+ const v = (l.lexicalValue !== undefined ? l.lexicalValue : l.getLiteral()).replace(/"/g, '\\"');
24
+ const dt = l.datatype ? (l.datatype.getIRI ? l.datatype.getIRI().toString() : l.datatype) : null;
25
+ const lang = l.lang || null;
26
+ if (lang) return `"${v}"@${lang}`;
27
+ if (dt && dt !== XSD + 'string') return `"${v}"^^<${dt}>`;
28
+ return `"${v}"`;
29
+ }
30
+
31
+ class TurtleWriter {
32
+ constructor(ont) {
33
+ this.ont = ont;
34
+ this.lines = [];
35
+ this.bn = 0; // blank node counter
36
+ }
37
+
38
+ write() {
39
+ const o = this.ont;
40
+ const id = o.getOntologyID();
41
+ const oIRI = id && id.ontologyIRI ? (id.ontologyIRI.toString ? id.ontologyIRI.toString() : String(id.ontologyIRI)) : null;
42
+
43
+ this.lines.push('@prefix rdf: <' + RDF + '> .');
44
+ this.lines.push('@prefix rdfs: <' + RDFS + '> .');
45
+ this.lines.push('@prefix owl: <' + OWL + '> .');
46
+ this.lines.push('@prefix xsd: <' + XSD + '> .');
47
+ this.lines.push('');
48
+
49
+ // Ontology header
50
+ if (oIRI) {
51
+ const header = [`<${oIRI}> a owl:Ontology`];
52
+ for (const imp of (o.imports || [])) {
53
+ const s = imp && imp.toString ? imp.toString() : String(imp);
54
+ header.push(` ; owl:imports <${s}>`);
55
+ }
56
+ if (id.versionIRI) {
57
+ header.push(` ; owl:versionIRI <${id.versionIRI}>`);
58
+ }
59
+ for (const ann of (o.getOntologyAnnotations() || [])) {
60
+ header.push(` ; ${this._annProp(ann.property)} ${this._annVal(ann.value)}`);
61
+ }
62
+ this.lines.push(header.join('\n') + ' .');
63
+ this.lines.push('');
64
+ }
65
+
66
+ // Axioms
67
+ for (const ax of o.getAxioms()) {
68
+ this._axiom(ax);
69
+ }
70
+ return this.lines.join('\n') + '\n';
71
+ }
72
+
73
+ _annProp(p) { return iri(p); }
74
+ _annVal(v) {
75
+ if (v && v.lexicalValue !== undefined) return lit(v);
76
+ if (v && v.getIRI) return iri(v);
77
+ return iri(v);
78
+ }
79
+
80
+ _emit(s, p, o) {
81
+ this.lines.push(`${s} ${p} ${o} .`);
82
+ }
83
+
84
+ _bnode() { return `_:b${this.bn++}`; }
85
+
86
+ // --- class expression → RDF node (returns node string, emits triples) -----
87
+
88
+ _ce(e) {
89
+ if (!e) return '<' + OWL + 'Thing>';
90
+ if (e.getIRI) return iri(e); // named class
91
+ switch (e.type) {
92
+ case T.OBJECT_INTERSECTION_OF: {
93
+ const b = this._bnode();
94
+ this._emit(b, 'a', 'owl:Class');
95
+ this._emit(b, 'owl:intersectionOf', this._rdfList(e.operands.map(x => this._ce(x))));
96
+ return b;
97
+ }
98
+ case T.OBJECT_UNION_OF: {
99
+ const b = this._bnode();
100
+ this._emit(b, 'a', 'owl:Class');
101
+ this._emit(b, 'owl:unionOf', this._rdfList(e.operands.map(x => this._ce(x))));
102
+ return b;
103
+ }
104
+ case T.OBJECT_COMPLEMENT_OF: {
105
+ const b = this._bnode();
106
+ this._emit(b, 'a', 'owl:Class');
107
+ this._emit(b, 'owl:complementOf', this._ce(e.operand));
108
+ return b;
109
+ }
110
+ case T.OBJECT_ONE_OF: {
111
+ const b = this._bnode();
112
+ this._emit(b, 'a', 'owl:Class');
113
+ this._emit(b, 'owl:oneOf', this._rdfList(e.operands.map(x => iri(x))));
114
+ return b;
115
+ }
116
+ case T.OBJECT_SOME_VALUES_FROM: {
117
+ const b = this._bnode();
118
+ this._emit(b, 'a', 'owl:Restriction');
119
+ this._emit(b, 'owl:onProperty', iri(e.property));
120
+ this._emit(b, 'owl:someValuesFrom', this._ce(e.filler));
121
+ return b;
122
+ }
123
+ case T.OBJECT_ALL_VALUES_FROM: {
124
+ const b = this._bnode();
125
+ this._emit(b, 'a', 'owl:Restriction');
126
+ this._emit(b, 'owl:onProperty', iri(e.property));
127
+ this._emit(b, 'owl:allValuesFrom', this._ce(e.filler));
128
+ return b;
129
+ }
130
+ case T.OBJECT_HAS_VALUE: {
131
+ const b = this._bnode();
132
+ this._emit(b, 'a', 'owl:Restriction');
133
+ this._emit(b, 'owl:onProperty', iri(e.property));
134
+ this._emit(b, 'owl:hasValue', iri(e.value));
135
+ return b;
136
+ }
137
+ case T.OBJECT_HAS_SELF: {
138
+ const b = this._bnode();
139
+ this._emit(b, 'a', 'owl:Restriction');
140
+ this._emit(b, 'owl:onProperty', iri(e.property));
141
+ this._emit(b, 'owl:hasSelf', '"true"^^xsd:boolean');
142
+ return b;
143
+ }
144
+ case T.OBJECT_MIN_CARDINALITY: case T.OBJECT_MIN_QUALIFIED_CARDINALITY: {
145
+ const b = this._bnode();
146
+ this._emit(b, 'a', 'owl:Restriction');
147
+ this._emit(b, 'owl:onProperty', iri(e.property));
148
+ const pred = e.type === T.OBJECT_MIN_QUALIFIED_CARDINALITY ? 'owl:minQualifiedCardinality' : 'owl:minCardinality';
149
+ this._emit(b, pred, `"${e.cardinality}"^^xsd:nonNegativeInteger`);
150
+ if (e.filler) this._emit(b, 'owl:onClass', this._ce(e.filler));
151
+ return b;
152
+ }
153
+ case T.OBJECT_MAX_CARDINALITY: case T.OBJECT_MAX_QUALIFIED_CARDINALITY: {
154
+ const b = this._bnode();
155
+ this._emit(b, 'a', 'owl:Restriction');
156
+ this._emit(b, 'owl:onProperty', iri(e.property));
157
+ const pred = e.type === T.OBJECT_MAX_QUALIFIED_CARDINALITY ? 'owl:maxQualifiedCardinality' : 'owl:maxCardinality';
158
+ this._emit(b, pred, `"${e.cardinality}"^^xsd:nonNegativeInteger`);
159
+ if (e.filler) this._emit(b, 'owl:onClass', this._ce(e.filler));
160
+ return b;
161
+ }
162
+ case T.OBJECT_EXACT_CARDINALITY: case T.OBJECT_EXACT_QUALIFIED_CARDINALITY: {
163
+ const b = this._bnode();
164
+ this._emit(b, 'a', 'owl:Restriction');
165
+ this._emit(b, 'owl:onProperty', iri(e.property));
166
+ const pred = e.type === T.OBJECT_EXACT_QUALIFIED_CARDINALITY ? 'owl:qualifiedCardinality' : 'owl:cardinality';
167
+ this._emit(b, pred, `"${e.cardinality}"^^xsd:nonNegativeInteger`);
168
+ if (e.filler) this._emit(b, 'owl:onClass', this._ce(e.filler));
169
+ return b;
170
+ }
171
+ case T.DATA_SOME_VALUES_FROM: {
172
+ const b = this._bnode();
173
+ this._emit(b, 'a', 'owl:Restriction');
174
+ this._emit(b, 'owl:onProperty', iri(e.property));
175
+ this._emit(b, 'owl:someValuesFrom', this._dr(e.filler));
176
+ return b;
177
+ }
178
+ case T.DATA_ALL_VALUES_FROM: {
179
+ const b = this._bnode();
180
+ this._emit(b, 'a', 'owl:Restriction');
181
+ this._emit(b, 'owl:onProperty', iri(e.property));
182
+ this._emit(b, 'owl:allValuesFrom', this._dr(e.filler));
183
+ return b;
184
+ }
185
+ case T.DATA_HAS_VALUE: {
186
+ const b = this._bnode();
187
+ this._emit(b, 'a', 'owl:Restriction');
188
+ this._emit(b, 'owl:onProperty', iri(e.property));
189
+ this._emit(b, 'owl:hasValue', lit(e.value));
190
+ return b;
191
+ }
192
+ default:
193
+ return iri(e);
194
+ }
195
+ }
196
+
197
+ _dr(dr) {
198
+ if (!dr) return 'rdfs:Literal';
199
+ if (dr.getIRI) return iri(dr);
200
+ switch (dr.type) {
201
+ case T.DATA_INTERSECTION_OF: {
202
+ const b = this._bnode();
203
+ this._emit(b, 'a', 'rdfs:Datatype');
204
+ this._emit(b, 'owl:intersectionOf', this._rdfList(dr.operands.map(x => this._dr(x))));
205
+ return b;
206
+ }
207
+ case T.DATA_UNION_OF: {
208
+ const b = this._bnode();
209
+ this._emit(b, 'a', 'rdfs:Datatype');
210
+ this._emit(b, 'owl:unionOf', this._rdfList(dr.operands.map(x => this._dr(x))));
211
+ return b;
212
+ }
213
+ case T.DATA_COMPLEMENT_OF: {
214
+ const b = this._bnode();
215
+ this._emit(b, 'a', 'rdfs:Datatype');
216
+ this._emit(b, 'owl:datatypeComplementOf', this._dr(dr.operand));
217
+ return b;
218
+ }
219
+ case T.DATA_ONE_OF: {
220
+ const b = this._bnode();
221
+ this._emit(b, 'a', 'rdfs:Datatype');
222
+ this._emit(b, 'owl:oneOf', this._rdfList(dr.operands.map(x => lit(x))));
223
+ return b;
224
+ }
225
+ case T.DATATYPE_RESTRICTION: {
226
+ const b = this._bnode();
227
+ this._emit(b, 'a', 'rdfs:Datatype');
228
+ this._emit(b, 'owl:onDatatype', iri(dr.datatype));
229
+ const facetNodes = dr.facetRestrictions.map(f => {
230
+ const fb = this._bnode();
231
+ this._emit(fb, iri(f.facet), lit(f.value));
232
+ return fb;
233
+ });
234
+ this._emit(b, 'owl:withRestrictions', this._rdfList(facetNodes));
235
+ return b;
236
+ }
237
+ default:
238
+ return iri(dr);
239
+ }
240
+ }
241
+
242
+ _rdfList(items) {
243
+ if (items.length === 0) return 'rdf:nil';
244
+ const head = this._bnode();
245
+ let prev = head;
246
+ for (let i = 0; i < items.length; i++) {
247
+ this._emit(prev, 'rdf:first', items[i]);
248
+ const next = (i === items.length - 1) ? 'rdf:nil' : this._bnode();
249
+ this._emit(prev, 'rdf:rest', next);
250
+ prev = next;
251
+ }
252
+ return head;
253
+ }
254
+
255
+ // --- axioms ----------------------------------------------------------------
256
+
257
+ _axiom(ax) {
258
+ switch (ax.getAxiomType()) {
259
+ case A.DECLARATION: {
260
+ const e = ax.entity;
261
+ const typeMap = {
262
+ OWLClass: 'owl:Class',
263
+ OWLObjectProperty: 'owl:ObjectProperty',
264
+ OWLDataProperty: 'owl:DatatypeProperty',
265
+ OWLNamedIndividual: 'owl:NamedIndividual',
266
+ OWLAnnotationProperty: 'owl:AnnotationProperty',
267
+ OWLDatatype: 'rdfs:Datatype'
268
+ };
269
+ const t = typeMap[e.constructor.name] || 'owl:Thing';
270
+ this._emit(iri(e), 'a', t);
271
+ break;
272
+ }
273
+ case A.SUBCLASS_OF:
274
+ this._emit(this._ce(ax.subClass), 'rdfs:subClassOf', this._ce(ax.superClass));
275
+ break;
276
+ case A.EQUIVALENT_CLASSES: {
277
+ const ces = ax.classExpressions;
278
+ for (let i = 0; i < ces.length - 1; i++) {
279
+ this._emit(this._ce(ces[i]), 'owl:equivalentClass', this._ce(ces[i + 1]));
280
+ }
281
+ break;
282
+ }
283
+ case A.DISJOINT_CLASSES: {
284
+ const ces = ax.classExpressions;
285
+ for (let i = 0; i < ces.length; i++) {
286
+ for (let j = i + 1; j < ces.length; j++) {
287
+ this._emit(this._ce(ces[i]), 'owl:disjointWith', this._ce(ces[j]));
288
+ }
289
+ }
290
+ break;
291
+ }
292
+ case A.DISJOINT_UNION: {
293
+ this._emit(this._ce(ax.owlClass), 'owl:disjointUnionOf', this._rdfList(ax.classExpressions.map(x => this._ce(x))));
294
+ break;
295
+ }
296
+ case A.SUB_OBJECT_PROPERTY_OF:
297
+ this._emit(iri(ax.subProperty), 'rdfs:subPropertyOf', iri(ax.superProperty));
298
+ break;
299
+ case A.SUB_DATA_PROPERTY_OF:
300
+ this._emit(iri(ax.subProperty), 'rdfs:subPropertyOf', iri(ax.superProperty));
301
+ break;
302
+ case A.SUB_PROPERTY_CHAIN_OF: {
303
+ this._emit(iri(ax.superProperty), 'owl:propertyChainAxiom', this._rdfList(ax.propertyChain.map(p => iri(p))));
304
+ break;
305
+ }
306
+ case A.INVERSE_OBJECT_PROPERTIES:
307
+ this._emit(iri(ax.property1), 'owl:inverseOf', iri(ax.property2));
308
+ break;
309
+ case A.OBJECT_PROPERTY_DOMAIN:
310
+ this._emit(iri(ax.property), 'rdfs:domain', this._ce(ax.domain));
311
+ break;
312
+ case A.OBJECT_PROPERTY_RANGE:
313
+ this._emit(iri(ax.property), 'rdfs:range', this._ce(ax.range));
314
+ break;
315
+ case A.DATA_PROPERTY_DOMAIN:
316
+ this._emit(iri(ax.property), 'rdfs:domain', this._ce(ax.domain));
317
+ break;
318
+ case A.DATA_PROPERTY_RANGE:
319
+ this._emit(iri(ax.property), 'rdfs:range', this._dr(ax.range));
320
+ break;
321
+ case A.FUNCTIONAL_OBJECT_PROPERTY:
322
+ this._emit(iri(ax.property), 'a', 'owl:FunctionalProperty');
323
+ break;
324
+ case A.INVERSE_FUNCTIONAL_OBJECT_PROPERTY:
325
+ this._emit(iri(ax.property), 'a', 'owl:InverseFunctionalProperty');
326
+ break;
327
+ case A.TRANSITIVE_OBJECT_PROPERTY:
328
+ this._emit(iri(ax.property), 'a', 'owl:TransitiveProperty');
329
+ break;
330
+ case A.SYMMETRIC_OBJECT_PROPERTY:
331
+ this._emit(iri(ax.property), 'a', 'owl:SymmetricProperty');
332
+ break;
333
+ case A.ASYMMETRIC_OBJECT_PROPERTY:
334
+ this._emit(iri(ax.property), 'a', 'owl:AsymmetricProperty');
335
+ break;
336
+ case A.REFLEXIVE_OBJECT_PROPERTY:
337
+ this._emit(iri(ax.property), 'a', 'owl:ReflexiveProperty');
338
+ break;
339
+ case A.IRREFLEXIVE_OBJECT_PROPERTY:
340
+ this._emit(iri(ax.property), 'a', 'owl:IrreflexiveProperty');
341
+ break;
342
+ case A.FUNCTIONAL_DATA_PROPERTY:
343
+ this._emit(iri(ax.property), 'a', 'owl:FunctionalProperty');
344
+ break;
345
+ case A.CLASS_ASSERTION:
346
+ this._emit(iri(ax.individual), 'a', this._ce(ax.classExpression));
347
+ break;
348
+ case A.OBJECT_PROPERTY_ASSERTION:
349
+ this._emit(iri(ax.subject), iri(ax.property), iri(ax.object));
350
+ break;
351
+ case A.DATA_PROPERTY_ASSERTION:
352
+ this._emit(iri(ax.subject), iri(ax.property), lit(ax.literal));
353
+ break;
354
+ case A.SAME_INDIVIDUAL: {
355
+ const inds = ax.individuals;
356
+ for (let i = 0; i < inds.length - 1; i++) {
357
+ this._emit(iri(inds[i]), 'owl:sameAs', iri(inds[i + 1]));
358
+ }
359
+ break;
360
+ }
361
+ case A.DIFFERENT_INDIVIDUALS: {
362
+ const inds = ax.individuals;
363
+ for (let i = 0; i < inds.length; i++) {
364
+ for (let j = i + 1; j < inds.length; j++) {
365
+ this._emit(iri(inds[i]), 'owl:differentFrom', iri(inds[j]));
366
+ }
367
+ }
368
+ break;
369
+ }
370
+ case A.HAS_KEY:
371
+ this._emit(this._ce(ax.classExpression), 'owl:hasKey', this._rdfList(ax.properties.map(p => iri(p))));
372
+ break;
373
+ case A.ANNOTATION_ASSERTION: {
374
+ const v = ax.value && ax.value.lexicalValue !== undefined ? lit(ax.value) : iri(ax.value);
375
+ this._emit(iri(ax.subject), iri(ax.property), v);
376
+ break;
377
+ }
378
+ default:
379
+ break;
380
+ }
381
+ }
382
+ }
383
+
384
+ /**
385
+ * Serialize an OWLOntology to Turtle.
386
+ * @param {OWLOntology} ont
387
+ * @returns {string} Turtle text
388
+ */
389
+ function writeTurtle(ont) {
390
+ return new TurtleWriter(ont).write();
391
+ }
392
+
393
+ module.exports = { writeTurtle, TurtleWriter };
@@ -0,0 +1,62 @@
1
+ 'use strict';
2
+
3
+ // ---------------------------------------------------------------------------
4
+ // IRI — mirrors org.semanticweb.owlapi.model.IRI
5
+ // ---------------------------------------------------------------------------
6
+
7
+ class IRI {
8
+ constructor(iriString) {
9
+ if (!iriString || typeof iriString !== 'string') {
10
+ throw new Error('IRI requires a non-empty string');
11
+ }
12
+ this._iri = iriString;
13
+ }
14
+
15
+ static create(iriString) {
16
+ return new IRI(iriString);
17
+ }
18
+
19
+ toString() {
20
+ return this._iri;
21
+ }
22
+
23
+ /** Fragment after the last '#' or '/'. */
24
+ getFragment() {
25
+ const h = this._iri.lastIndexOf('#');
26
+ if (h >= 0 && h < this._iri.length - 1) return this._iri.slice(h + 1);
27
+ const s = this._iri.lastIndexOf('/');
28
+ if (s >= 0 && s < this._iri.length - 1) return this._iri.slice(s + 1);
29
+ return null;
30
+ }
31
+
32
+ /** Everything before the fragment separator. */
33
+ getNamespace() {
34
+ const h = this._iri.lastIndexOf('#');
35
+ if (h >= 0) return this._iri.slice(0, h + 1);
36
+ const s = this._iri.lastIndexOf('/');
37
+ if (s >= 0) return this._iri.slice(0, s + 1);
38
+ return this._iri;
39
+ }
40
+
41
+ getShortForm() {
42
+ return this.getFragment() || this._iri;
43
+ }
44
+
45
+ equals(other) {
46
+ return other instanceof IRI && other._iri === this._iri;
47
+ }
48
+
49
+ hashCode() {
50
+ return IRI._hash(this._iri);
51
+ }
52
+
53
+ static _hash(s) {
54
+ let h = 0;
55
+ for (let i = 0; i < s.length; i++) {
56
+ h = ((h << 5) - h + s.charCodeAt(i)) | 0;
57
+ }
58
+ return h;
59
+ }
60
+ }
61
+
62
+ module.exports = { IRI };