@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,398 @@
1
+ 'use strict';
2
+
3
+ // ---------------------------------------------------------------------------
4
+ // io/ManchesterSyntaxParser — parse OWL 2 Manchester Syntax (frame-style).
5
+ // Mirrors the syntax used by Protégé's "Manchester Syntax" rendering:
6
+ //
7
+ // Class: ex:Person
8
+ // SubClassOf: ex:Animal
9
+ // SubClassOf: ex:hasParent some ex:Person
10
+ // EquivalentTo: ex:Human
11
+ // DisjointWith: ex:Robot
12
+ // DisjointUnionOf: ex:Child, ex:Adult
13
+ //
14
+ // ObjectProperty: ex:hasParent
15
+ // Domain: ex:Person
16
+ // Range: ex:Person
17
+ // Characteristics: Transitive, Functional
18
+ // InverseOf: ex:hasChild
19
+ // SubPropertyOf: ex:hasAncestor
20
+ //
21
+ // Individual: ex:alice
22
+ // Types: ex:Person
23
+ // Facts: ex:hasParent ex:bob
24
+ // SameAs: ex:alicia
25
+ //
26
+ // Class expressions use: and / or / not / some / only / value / Self /
27
+ // min n / max n / exactly n / {ind1, ind2}
28
+ // ---------------------------------------------------------------------------
29
+
30
+ const { OWLOntology, OWLOntologyID } = require('../model/OWLOntology');
31
+ const {
32
+ OWLClass, OWLObjectProperty, OWLDataProperty, OWLNamedIndividual, OWLDatatype
33
+ } = require('../model/OWLEntity');
34
+ const AX = require('../model/OWLAxiom');
35
+ const CE = require('../model/OWLClassExpression');
36
+ const { OWLLiteral } = require('../model/OWLLiteral');
37
+ const { IRI } = require('../model/IRI');
38
+
39
+ const XSD = 'http://www.w3.org/2001/XMLSchema#';
40
+
41
+ const DEFAULT_PREFIXES = {
42
+ rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
43
+ rdfs: 'http://www.w3.org/2000/01/rdf-schema#',
44
+ owl: 'http://www.w3.org/2002/07/owl#',
45
+ xsd: XSD
46
+ };
47
+
48
+ class ManchesterSyntaxParser {
49
+ constructor(opts = {}) {
50
+ this.prefixes = Object.assign({}, DEFAULT_PREFIXES, opts.prefixes || {});
51
+ this.base = opts.base || 'http://example.org/';
52
+ }
53
+
54
+ expandIRI(token) {
55
+ if (token.startsWith('<') && token.endsWith('>')) return token.slice(1, -1);
56
+ if (token.startsWith('http://') || token.startsWith('https://') || token.startsWith('urn:')) return token;
57
+ const idx = token.indexOf(':');
58
+ if (idx > 0) {
59
+ const ns = this.prefixes[token.slice(0, idx)];
60
+ if (ns) return ns + token.slice(idx + 1);
61
+ }
62
+ return this.base + token;
63
+ }
64
+
65
+ /**
66
+ * Parse Manchester Syntax text into an OWLOntology.
67
+ * @param {string} text
68
+ * @returns {OWLOntology}
69
+ */
70
+ parse(text, ontologyIRI = null) {
71
+ const ont = new OWLOntology(new OWLOntologyID(ontologyIRI ? IRI.create(ontologyIRI) : null));
72
+ ont.format = 'Manchester';
73
+
74
+ // Parse Prefix: lines first
75
+ const lines = text.split(/\r?\n/);
76
+ const contentLines = [];
77
+ for (const line of lines) {
78
+ const m = /^Prefix:\s*([\w-]*):?\s*<([^>]+)>/.exec(line.trim());
79
+ if (m) {
80
+ this.prefixes[m[1] || ''] = m[2];
81
+ ont.addPrefix(m[1] || '', m[2]); // prefix fidelity (L5)
82
+ continue;
83
+ }
84
+ contentLines.push(line);
85
+ }
86
+
87
+ // Split into frames by "Class:" / "ObjectProperty:" / "DataProperty:" /
88
+ // "Individual:" / "Datatype:" / "AnnotationProperty:" headers
89
+ let frame = null;
90
+ for (const raw of contentLines) {
91
+ const line = raw;
92
+ if (!line.trim()) continue;
93
+ const fm = /^(Class|ObjectProperty|DataProperty|Individual|Datatype|AnnotationProperty):\s*(\S+)/.exec(line);
94
+ if (fm && !/^\s/.test(line)) {
95
+ frame = { kind: fm[1], iri: this.expandIRI(fm[2]) };
96
+ this._declareFrame(ont, frame);
97
+ continue;
98
+ }
99
+ if (frame) {
100
+ this._frameLine(ont, frame, line.trim());
101
+ }
102
+ }
103
+ return ont;
104
+ }
105
+
106
+ _declareFrame(ont, frame) {
107
+ const mk = {
108
+ Class: (i) => new OWLClass(i),
109
+ ObjectProperty: (i) => new OWLObjectProperty(i),
110
+ DataProperty: (i) => new OWLDataProperty(i),
111
+ Individual: (i) => new OWLNamedIndividual(i),
112
+ Datatype: (i) => new OWLDatatype(i),
113
+ AnnotationProperty: (i) => new (require('../model/OWLEntity').OWLAnnotationProperty)(i)
114
+ }[frame.kind];
115
+ if (mk) ont.addAxiom(new AX.OWLDeclarationAxiom(mk(frame.iri)));
116
+ }
117
+
118
+ _frameLine(ont, frame, line) {
119
+ // Split on the FIRST colon only — values may contain prefixed IRIs (ex:Foo)
120
+ const ci = line.indexOf(':');
121
+ const keyword = (ci >= 0 ? line.slice(0, ci) : line).trim();
122
+ const body = (ci >= 0 ? line.slice(ci + 1) : '').trim();
123
+ if (!body) return;
124
+ const items = splitTopLevel(body, ',');
125
+
126
+ switch (frame.kind) {
127
+ case 'Class': {
128
+ const cls = new OWLClass(frame.iri);
129
+ if (keyword === 'SubClassOf') {
130
+ for (const it of items) ont.addAxiom(new AX.OWLSubClassOfAxiom(cls, this._classExpr(it)));
131
+ } else if (keyword === 'EquivalentTo') {
132
+ // Keep {a,b,c} enumeration as ONE item
133
+ for (const it of items) ont.addAxiom(new AX.OWLEquivalentClassesAxiom([cls, this._classExpr(it)]));
134
+ } else if (keyword === 'DisjointWith') {
135
+ for (const it of items) ont.addAxiom(new AX.OWLDisjointClassesAxiom([cls, this._classExpr(it)]));
136
+ } else if (keyword === 'DisjointUnionOf') {
137
+ ont.addAxiom(new AX.OWLDisjointUnionAxiom(cls, items.map(i => this._classExpr(i))));
138
+ } else if (keyword === 'HasKey') {
139
+ const props = items.map(i => new OWLObjectProperty(this.expandIRI(i.trim())));
140
+ ont.addAxiom(new AX.OWLHasKeyAxiom(cls, props));
141
+ }
142
+ break;
143
+ }
144
+ case 'ObjectProperty': {
145
+ const p = new OWLObjectProperty(frame.iri);
146
+ if (keyword === 'SubPropertyOf') {
147
+ for (const it of items) ont.addAxiom(new AX.OWLSubObjectPropertyOfAxiom(p, new OWLObjectProperty(this.expandIRI(it))));
148
+ } else if (keyword === 'Domain') {
149
+ for (const it of items) ont.addAxiom(new AX.OWLObjectPropertyDomainAxiom(p, this._classExpr(it)));
150
+ } else if (keyword === 'Range') {
151
+ for (const it of items) ont.addAxiom(new AX.OWLObjectPropertyRangeAxiom(p, this._classExpr(it)));
152
+ } else if (keyword === 'InverseOf') {
153
+ for (const it of items) ont.addAxiom(new AX.OWLInverseObjectPropertiesAxiom(p, new OWLObjectProperty(this.expandIRI(it))));
154
+ } else if (keyword === 'Characteristics') {
155
+ for (const c of items) {
156
+ const cc = c.trim();
157
+ const map = {
158
+ Functional: AX.OWLFunctionalObjectPropertyAxiom,
159
+ InverseFunctional: AX.OWLInverseFunctionalObjectPropertyAxiom,
160
+ Transitive: AX.OWLTransitiveObjectPropertyAxiom,
161
+ Symmetric: AX.OWLSymmetricObjectPropertyAxiom,
162
+ Asymmetric: AX.OWLAsymmetricObjectPropertyAxiom,
163
+ Reflexive: AX.OWLReflexiveObjectPropertyAxiom,
164
+ Irreflexive: AX.OWLIrreflexiveObjectPropertyAxiom
165
+ };
166
+ if (map[cc]) ont.addAxiom(new map[cc](p));
167
+ }
168
+ } else if (keyword === 'SubPropertyChain') {
169
+ const chain = body.split(/\s*o\s*/).map(s => new OWLObjectProperty(this.expandIRI(s.trim())));
170
+ ont.addAxiom(new AX.OWLSubPropertyChainOfAxiom(chain, p));
171
+ }
172
+ break;
173
+ }
174
+ case 'DataProperty': {
175
+ const p = new OWLDataProperty(frame.iri);
176
+ if (keyword === 'SubPropertyOf') {
177
+ for (const it of items) ont.addAxiom(new AX.OWLSubDataPropertyOfAxiom(p, new OWLDataProperty(this.expandIRI(it))));
178
+ } else if (keyword === 'Domain') {
179
+ for (const it of items) ont.addAxiom(new AX.OWLDataPropertyDomainAxiom(p, this._classExpr(it)));
180
+ } else if (keyword === 'Range') {
181
+ for (const it of items) ont.addAxiom(new AX.OWLDataPropertyRangeAxiom(p, new OWLDatatype(this.expandIRI(it))));
182
+ } else if (keyword === 'Characteristics') {
183
+ if (items.some(c => c.trim() === 'Functional')) {
184
+ ont.addAxiom(new AX.OWLFunctionalDataPropertyAxiom(p));
185
+ }
186
+ }
187
+ break;
188
+ }
189
+ case 'Individual': {
190
+ const ind = new OWLNamedIndividual(frame.iri);
191
+ if (keyword === 'Types') {
192
+ for (const it of items) ont.addAxiom(new AX.OWLClassAssertionAxiom(ind, this._classExpr(it)));
193
+ } else if (keyword === 'SameAs') {
194
+ for (const it of items) ont.addAxiom(new AX.OWLSameIndividualAxiom([ind, new OWLNamedIndividual(this.expandIRI(it))]));
195
+ } else if (keyword === 'DifferentFrom') {
196
+ for (const it of items) ont.addAxiom(new AX.OWLDifferentIndividualsAxiom([ind, new OWLNamedIndividual(this.expandIRI(it))]));
197
+ } else if (keyword === 'Facts') {
198
+ // "Facts: p target, q target2"
199
+ for (const it of items) {
200
+ const m = /^(\S+)\s+(\S+)$/.exec(it.trim());
201
+ if (!m) continue;
202
+ const pIRI = this.expandIRI(m[1]);
203
+ const tgt = m[2];
204
+ if (tgt.startsWith('"')) {
205
+ ont.addAxiom(new AX.OWLDataPropertyAssertionAxiom(
206
+ ind, new OWLDataProperty(pIRI), this._literal(tgt)));
207
+ } else {
208
+ ont.addAxiom(new AX.OWLObjectPropertyAssertionAxiom(
209
+ ind, new OWLObjectProperty(pIRI), new OWLNamedIndividual(this.expandIRI(tgt))));
210
+ }
211
+ }
212
+ }
213
+ break;
214
+ }
215
+ }
216
+ }
217
+
218
+ // --- class expression (Manchester infix) ----------------------------------
219
+
220
+ _classExpr(text) {
221
+ const tokens = this._tokenizeExpr(text);
222
+ this._toks = tokens;
223
+ this._pos = 0;
224
+ const e = this._orExpr();
225
+ return e;
226
+ }
227
+
228
+ _tokenizeExpr(s) {
229
+ const out = [];
230
+ let i = 0;
231
+ while (i < s.length) {
232
+ const ch = s[i];
233
+ if (/\s/.test(ch)) { i++; continue; }
234
+ if (ch === '(' || ch === ')' || ch === '{' || ch === '}' || ch === ',') { out.push(ch); i++; continue; }
235
+ if (ch === '"') {
236
+ let j = i + 1, v = '';
237
+ while (j < s.length && s[j] !== '"') { v += s[j]; j++; }
238
+ out.push({ lit: v });
239
+ i = j + 1;
240
+ continue;
241
+ }
242
+ let j = i;
243
+ while (j < s.length && /[^\s(),{}]/.test(s[j])) j++;
244
+ out.push(s.slice(i, j));
245
+ i = j;
246
+ }
247
+ return out;
248
+ }
249
+
250
+ _peekT() { return this._toks[this._pos]; }
251
+ _nextT() { return this._toks[this._pos++]; }
252
+
253
+ _orExpr() {
254
+ let e = this._andExpr();
255
+ while (this._peekT() === 'or') {
256
+ this._nextT();
257
+ const rhs = this._andExpr();
258
+ e = new CE.OWLObjectUnionOf(flatten(e, T => T.OBJECT_UNION_OF).concat(flatten(rhs, T => T.OBJECT_UNION_OF)));
259
+ }
260
+ return e;
261
+ }
262
+
263
+ _andExpr() {
264
+ let e = this._unaryExpr();
265
+ while (this._peekT() === 'and') {
266
+ this._nextT();
267
+ const rhs = this._unaryExpr();
268
+ e = new CE.OWLObjectIntersectionOf(flatten(e, T => T.OBJECT_INTERSECTION_OF).concat(flatten(rhs, T => T.OBJECT_INTERSECTION_OF)));
269
+ }
270
+ return e;
271
+ }
272
+
273
+ _unaryExpr() {
274
+ if (this._peekT() === 'not') {
275
+ this._nextT();
276
+ return new CE.OWLObjectComplementOf(this._unaryExpr());
277
+ }
278
+ return this._restrictionExpr();
279
+ }
280
+
281
+ _restrictionExpr() {
282
+ const t = this._peekT();
283
+ // Property-based restriction: <prop> (some|only|value|Self|min|max|exactly) ...
284
+ if (typeof t === 'string' && t !== '(' && t !== '{') {
285
+ const next = this._toks[this._pos + 1];
286
+ if (typeof next === 'string' && /^(some|only|value|Self|min|max|exactly)$/.test(next)) {
287
+ const propTok = this._nextT();
288
+ const propIRI = this.expandIRI(propTok);
289
+ const kw = this._nextT();
290
+ const prop = new OWLObjectProperty(propIRI);
291
+ if (kw === 'some') return new CE.OWLObjectSomeValuesFrom(prop, this._unaryExpr());
292
+ if (kw === 'only') return new CE.OWLObjectAllValuesFrom(prop, this._unaryExpr());
293
+ if (kw === 'value') {
294
+ const indTok = this._nextT();
295
+ return new CE.OWLObjectHasValue(prop, new OWLNamedIndividual(this.expandIRI(typeof indTok === 'object' ? indTok.lit : indTok)));
296
+ }
297
+ if (kw === 'Self') return new CE.OWLObjectHasSelf(prop);
298
+ if (kw === 'min' || kw === 'max' || kw === 'exactly') {
299
+ const n = parseInt(this._nextT(), 10);
300
+ // Optional filler — only consume if next token is NOT a frame keyword
301
+ // or a closing bracket/comma. In Manchester, `min 2 ex:Foo` has filler;
302
+ // `min 2` alone is unqualified.
303
+ let filler = null;
304
+ const nt = this._peekT();
305
+ if (nt !== undefined && nt !== ')' && nt !== ',' && nt !== 'and' && nt !== 'or') {
306
+ filler = this._unaryExpr();
307
+ }
308
+ const T = CE.ClassExpressionType;
309
+ const type = kw === 'min' ? (filler ? T.OBJECT_MIN_QUALIFIED_CARDINALITY : T.OBJECT_MIN_CARDINALITY)
310
+ : kw === 'max' ? (filler ? T.OBJECT_MAX_QUALIFIED_CARDINALITY : T.OBJECT_MAX_CARDINALITY)
311
+ : (filler ? T.OBJECT_EXACT_QUALIFIED_CARDINALITY : T.OBJECT_EXACT_CARDINALITY);
312
+ return new CE.OWLObjectCardinalityRestriction(type, n, prop, filler);
313
+ }
314
+ }
315
+ }
316
+ return this._primary();
317
+ }
318
+
319
+ _primary() {
320
+ const t = this._peekT();
321
+ if (t === '(') {
322
+ this._nextT();
323
+ const e = this._orExpr();
324
+ if (this._peekT() === ')') this._nextT();
325
+ return e;
326
+ }
327
+ if (t === '{') {
328
+ this._nextT();
329
+ const inds = [];
330
+ while (this._peekT() !== '}' && this._peekT() !== undefined) {
331
+ const tok = this._nextT();
332
+ if (tok === ',') continue;
333
+ inds.push(new OWLNamedIndividual(this.expandIRI(typeof tok === 'object' ? tok.lit : tok)));
334
+ }
335
+ if (this._peekT() === '}') this._nextT();
336
+ return new CE.OWLObjectOneOf(inds);
337
+ }
338
+ const tok = this._nextT();
339
+ if (typeof tok === 'object' && tok.lit !== undefined) {
340
+ return new OWLLiteral(tok.lit);
341
+ }
342
+ return new OWLClass(this.expandIRI(tok));
343
+ }
344
+
345
+ _restOfPrimary() {
346
+ // Re-assemble remaining primary tokens until a natural stop (and/or/','/')')
347
+ const parts = [];
348
+ let depth = 0;
349
+ while (this._pos < this._toks.length) {
350
+ const t = this._peekT();
351
+ if (t === '(') depth++;
352
+ if (t === ')') { if (depth === 0) break; depth--; }
353
+ if (depth === 0 && (t === 'and' || t === 'or' || t === ',')) break;
354
+ parts.push(this._nextT());
355
+ }
356
+ // Parse collected tokens as a class expression by re-tokenizing
357
+ return this._classExprFromTokens(parts);
358
+ }
359
+
360
+ _classExprFromTokens(tokens) {
361
+ const savedToks = this._toks, savedPos = this._pos;
362
+ this._toks = tokens; this._pos = 0;
363
+ const e = this._orExpr();
364
+ this._toks = savedToks; this._pos = savedPos;
365
+ return e;
366
+ }
367
+
368
+ _literal(token) {
369
+ const m = /^"((?:[^"\\]|\\.)*)"(?:\^\^(.+))?$/.exec(token.trim());
370
+ if (!m) return new OWLLiteral(token.replace(/^"|"$/g, ''));
371
+ let dt = null;
372
+ if (m[2]) dt = new OWLDatatype(this.expandIRI(m[2]));
373
+ return new OWLLiteral(m[1], dt);
374
+ }
375
+ }
376
+
377
+ function flatten(expr, typeFn) {
378
+ const T = require('../model/OWLClassExpression').ClassExpressionType;
379
+ if (expr && expr.type && (expr.type === T.OBJECT_UNION_OF || expr.type === T.OBJECT_INTERSECTION_OF)) {
380
+ return expr.operands;
381
+ }
382
+ return [expr];
383
+ }
384
+
385
+ function splitTopLevel(s, sep) {
386
+ const out = [];
387
+ let depth = 0, cur = '';
388
+ for (const ch of s) {
389
+ if (ch === '(' || ch === '{') depth++;
390
+ if (ch === ')' || ch === '}') depth--;
391
+ if (ch === sep && depth === 0) { out.push(cur.trim()); cur = ''; continue; }
392
+ cur += ch;
393
+ }
394
+ if (cur.trim()) out.push(cur.trim());
395
+ return out;
396
+ }
397
+
398
+ module.exports = { ManchesterSyntaxParser };