@oml/owl 0.7.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 (46) hide show
  1. package/README.md +46 -0
  2. package/out/index.d.ts +10 -0
  3. package/out/index.js +12 -0
  4. package/out/index.js.map +1 -0
  5. package/out/owl/owl-abox.d.ts +79 -0
  6. package/out/owl/owl-abox.js +765 -0
  7. package/out/owl/owl-abox.js.map +1 -0
  8. package/out/owl/owl-imports.d.ts +9 -0
  9. package/out/owl/owl-imports.js +102 -0
  10. package/out/owl/owl-imports.js.map +1 -0
  11. package/out/owl/owl-interfaces.d.ts +121 -0
  12. package/out/owl/owl-interfaces.js +3 -0
  13. package/out/owl/owl-interfaces.js.map +1 -0
  14. package/out/owl/owl-mapper.d.ts +80 -0
  15. package/out/owl/owl-mapper.js +1217 -0
  16. package/out/owl/owl-mapper.js.map +1 -0
  17. package/out/owl/owl-service.d.ts +65 -0
  18. package/out/owl/owl-service.js +552 -0
  19. package/out/owl/owl-service.js.map +1 -0
  20. package/out/owl/owl-shacl.d.ts +28 -0
  21. package/out/owl/owl-shacl.js +337 -0
  22. package/out/owl/owl-shacl.js.map +1 -0
  23. package/out/owl/owl-sparql.d.ts +71 -0
  24. package/out/owl/owl-sparql.js +260 -0
  25. package/out/owl/owl-sparql.js.map +1 -0
  26. package/out/owl/owl-store.d.ts +32 -0
  27. package/out/owl/owl-store.js +142 -0
  28. package/out/owl/owl-store.js.map +1 -0
  29. package/out/owl/owl-tbox.d.ts +98 -0
  30. package/out/owl/owl-tbox.js +575 -0
  31. package/out/owl/owl-tbox.js.map +1 -0
  32. package/out/owl-module.d.ts +15 -0
  33. package/out/owl-module.js +22 -0
  34. package/out/owl-module.js.map +1 -0
  35. package/package.json +52 -0
  36. package/src/index.ts +12 -0
  37. package/src/owl/owl-abox.ts +930 -0
  38. package/src/owl/owl-imports.ts +108 -0
  39. package/src/owl/owl-interfaces.ts +145 -0
  40. package/src/owl/owl-mapper.ts +1510 -0
  41. package/src/owl/owl-service.ts +642 -0
  42. package/src/owl/owl-shacl.ts +400 -0
  43. package/src/owl/owl-sparql.ts +317 -0
  44. package/src/owl/owl-store.ts +173 -0
  45. package/src/owl/owl-tbox.ts +727 -0
  46. package/src/owl-module.ts +52 -0
@@ -0,0 +1,765 @@
1
+ // Copyright (c) 2026 Modelware. All rights reserved.
2
+ import { DataFactory } from 'n3';
3
+ const { namedNode, quad } = DataFactory;
4
+ const RDF_TYPE = namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
5
+ export class ABoxEntailmentCache {
6
+ constructor() {
7
+ this.state = new Map();
8
+ this.deltaPlus = new Map();
9
+ this.deltaMinus = new Map();
10
+ this.validationWarnings = new Map();
11
+ }
12
+ markDirty(modelUri) {
13
+ this.state.set(modelUri, 'dirty');
14
+ }
15
+ markDirtyWithDelta(modelUri, asserted, retracted) {
16
+ if (asserted.length > 0) {
17
+ const plus = this.deltaPlus.get(modelUri) ?? new Map();
18
+ for (const q of asserted) {
19
+ plus.set(this.quadKey(q), q);
20
+ }
21
+ this.deltaPlus.set(modelUri, plus);
22
+ }
23
+ if (retracted.length > 0) {
24
+ const minus = this.deltaMinus.get(modelUri) ?? new Map();
25
+ for (const q of retracted) {
26
+ minus.set(this.quadKey(q), q);
27
+ }
28
+ this.deltaMinus.set(modelUri, minus);
29
+ }
30
+ this.markDirty(modelUri);
31
+ }
32
+ markClean(modelUri) {
33
+ this.state.set(modelUri, 'clean');
34
+ }
35
+ markDirtyAll(modelUris) {
36
+ for (const modelUri of modelUris) {
37
+ this.markDirty(modelUri);
38
+ }
39
+ }
40
+ isDirty(modelUri) {
41
+ return this.state.get(modelUri) === 'dirty';
42
+ }
43
+ isAbsent(modelUri) {
44
+ const value = this.state.get(modelUri);
45
+ return value === undefined || value === 'absent';
46
+ }
47
+ consumeDelta(modelUri) {
48
+ const plus = [...(this.deltaPlus.get(modelUri)?.values() ?? [])];
49
+ const minus = [...(this.deltaMinus.get(modelUri)?.values() ?? [])];
50
+ this.deltaPlus.delete(modelUri);
51
+ this.deltaMinus.delete(modelUri);
52
+ return { plus, minus };
53
+ }
54
+ getValidationWarnings(modelUri) {
55
+ return this.validationWarnings.get(modelUri) ?? [];
56
+ }
57
+ setValidationWarnings(modelUri, warnings) {
58
+ this.validationWarnings.set(modelUri, [...new Set(warnings)]);
59
+ }
60
+ invalidate(modelUri) {
61
+ this.state.delete(modelUri);
62
+ this.deltaPlus.delete(modelUri);
63
+ this.deltaMinus.delete(modelUri);
64
+ this.validationWarnings.delete(modelUri);
65
+ }
66
+ quadKey(q) {
67
+ return `${q.subject.id}|${q.predicate.id}|${q.object.id}|${q.graph.id}`;
68
+ }
69
+ }
70
+ export class ABoxChainer {
71
+ constructor(reasoningStore) {
72
+ this.reasoningStore = reasoningStore;
73
+ }
74
+ chain(modelUri, tboxIndex, readModelUris, deltaPlus, deltaMinus) {
75
+ const scope = this.resolveScope(modelUri, readModelUris);
76
+ const store = this.reasoningStore.getStore();
77
+ const index = this.buildIndex(scope.facts);
78
+ const plusFacts = deltaPlus.map((q) => this.asFact(q));
79
+ const minusFacts = deltaMinus.map((q) => this.asFact(q));
80
+ const fullRecompute = plusFacts.length === 0 && minusFacts.length === 0;
81
+ let iterations = 0;
82
+ let newQuadsCount = 0;
83
+ if (fullRecompute) {
84
+ for (const key of [...scope.ownEntKeys]) {
85
+ const fact = scope.facts.get(key);
86
+ if (fact) {
87
+ this.removeOwnEntailedFact(scope, index, store, fact);
88
+ }
89
+ }
90
+ }
91
+ const over = fullRecompute ? [] : this.overdelete(scope, index, tboxIndex, minusFacts, store);
92
+ const seed = fullRecompute ? scope.ownBaseFacts : [...plusFacts, ...over];
93
+ const result = this.materializeAdd(scope, index, tboxIndex, seed, store);
94
+ iterations += result.iterations;
95
+ newQuadsCount += result.newQuads;
96
+ return {
97
+ complete: true,
98
+ iterations,
99
+ newQuadsCount,
100
+ validationWarnings: this.collectValidationWarnings(index, tboxIndex),
101
+ };
102
+ }
103
+ overdelete(scope, index, tbox, minusFacts, store) {
104
+ const queue = [...minusFacts];
105
+ const overByKey = new Map();
106
+ while (queue.length > 0) {
107
+ const current = queue.shift();
108
+ if (!current) {
109
+ continue;
110
+ }
111
+ for (const head of this.reverseAnchoredHeads(current, index, tbox)) {
112
+ const key = this.factKey(head);
113
+ if (!scope.ownEntKeys.has(key)) {
114
+ continue;
115
+ }
116
+ this.removeOwnEntailedFact(scope, index, store, head);
117
+ overByKey.set(key, head);
118
+ queue.push(head);
119
+ }
120
+ }
121
+ return [...overByKey.values()];
122
+ }
123
+ materializeAdd(scope, index, tbox, seedFacts, store) {
124
+ const queue = [];
125
+ const queued = new Set();
126
+ let iterations = 0;
127
+ let newQuads = 0;
128
+ const enqueue = (fact) => {
129
+ const key = this.factKey(fact);
130
+ if (queued.has(key)) {
131
+ return;
132
+ }
133
+ queue.push(fact);
134
+ queued.add(key);
135
+ };
136
+ for (const seed of seedFacts) {
137
+ const key = this.factKey(seed);
138
+ if (scope.baseKeys.has(key)) {
139
+ enqueue(seed);
140
+ continue;
141
+ }
142
+ if (!this.canInsertEntailedFact(scope, seed) || !this.hasSupport(seed, index, tbox)) {
143
+ continue;
144
+ }
145
+ this.insertOwnEntailedFact(scope, index, store, seed);
146
+ newQuads += 1;
147
+ enqueue(seed);
148
+ }
149
+ while (queue.length > 0) {
150
+ const fact = queue.shift();
151
+ if (!fact) {
152
+ continue;
153
+ }
154
+ iterations += 1;
155
+ for (const head of this.forwardRules(fact, index, tbox)) {
156
+ if (!this.canInsertEntailedFact(scope, head) || !this.hasSupport(head, index, tbox)) {
157
+ continue;
158
+ }
159
+ this.insertOwnEntailedFact(scope, index, store, head);
160
+ newQuads += 1;
161
+ enqueue(head);
162
+ }
163
+ }
164
+ return { iterations, newQuads };
165
+ }
166
+ forwardRules(fact, index, tbox) {
167
+ const heads = [];
168
+ if (this.isTypeFact(fact)) {
169
+ for (const superClass of this.getSuperClasses(tbox, fact.object.value)) {
170
+ if (superClass !== fact.object.value) {
171
+ heads.push(this.typeFact(fact.subject, superClass));
172
+ }
173
+ }
174
+ }
175
+ const p = fact.predicate.value;
176
+ const x = fact.subject;
177
+ const y = fact.object;
178
+ for (const q of this.getSuperProperties(tbox, p)) {
179
+ if (q !== p) {
180
+ heads.push(this.edgeFact(x, q, y));
181
+ }
182
+ }
183
+ for (const d of this.getDomains(tbox, p)) {
184
+ heads.push(this.typeFact(x, d));
185
+ }
186
+ if (y.termType !== 'Literal') {
187
+ for (const c of this.getObjectRanges(tbox, p)) {
188
+ heads.push(this.typeFact(y, c));
189
+ }
190
+ for (const inverse of this.getInverses(tbox, p)) {
191
+ heads.push(this.edgeFact(y, inverse, x));
192
+ }
193
+ if (this.isSymmetricProperty(tbox, p)) {
194
+ heads.push(this.edgeFact(y, p, x));
195
+ }
196
+ if (this.isTransitiveProperty(tbox, p)) {
197
+ for (const next of this.getEdgeFacts(index, y, p)) {
198
+ heads.push(this.edgeFact(x, p, next.object));
199
+ }
200
+ for (const prev of this.getIncomingEdgesByProperty(index, x, p)) {
201
+ heads.push(this.edgeFact(prev.subject, p, y));
202
+ }
203
+ }
204
+ }
205
+ heads.push(...this.applyForwardRulesTriggeredByFact(fact, index, tbox));
206
+ return this.uniqueFacts(heads);
207
+ }
208
+ reverseAnchoredHeads(fact, index, tbox) {
209
+ return this.forwardRules(fact, index, tbox);
210
+ }
211
+ hasSupport(fact, index, tbox) {
212
+ if (index.facts.has(this.factKey(fact))) {
213
+ return true;
214
+ }
215
+ if (this.isTypeFact(fact)) {
216
+ const types = this.getTypes(index, fact.subject);
217
+ for (const type of types) {
218
+ if (type === fact.object.value || this.getSuperClasses(tbox, type).includes(fact.object.value)) {
219
+ return true;
220
+ }
221
+ }
222
+ for (const edge of this.getOutgoingEdges(index, fact.subject)) {
223
+ if (this.getDomains(tbox, edge.predicate.value).includes(fact.object.value)) {
224
+ return true;
225
+ }
226
+ }
227
+ for (const edge of this.getIncomingEdges(index, fact.subject)) {
228
+ if (edge.object.termType !== 'Literal' && this.getObjectRanges(tbox, edge.predicate.value).includes(fact.object.value)) {
229
+ return true;
230
+ }
231
+ }
232
+ if (this.hasForwardRuleSupport(fact, index, tbox)) {
233
+ return true;
234
+ }
235
+ return false;
236
+ }
237
+ const x = fact.subject;
238
+ const p = fact.predicate.value;
239
+ const y = fact.object;
240
+ for (const edge of this.getOutgoingEdges(index, x)) {
241
+ if (edge.object.id === y.id && this.getSuperProperties(tbox, edge.predicate.value).includes(p)) {
242
+ return true;
243
+ }
244
+ }
245
+ if (y.termType !== 'Literal') {
246
+ for (const edge of this.getOutgoingEdges(index, y)) {
247
+ if (edge.object.id === x.id && this.getInverses(tbox, edge.predicate.value).includes(p)) {
248
+ return true;
249
+ }
250
+ if (edge.object.id === x.id && edge.predicate.value === p && this.isSymmetricProperty(tbox, p)) {
251
+ return true;
252
+ }
253
+ }
254
+ if (this.isTransitiveProperty(tbox, p) && this.hasTransitiveSupport(index, x, p, y)) {
255
+ return true;
256
+ }
257
+ }
258
+ if (this.hasForwardRuleSupport(fact, index, tbox)) {
259
+ return true;
260
+ }
261
+ return false;
262
+ }
263
+ hasTransitiveSupport(index, subject, property, object) {
264
+ for (const left of this.getEdgeFacts(index, subject, property)) {
265
+ if (left.object.id === object.id || left.object.termType === 'Literal') {
266
+ continue;
267
+ }
268
+ for (const right of this.getEdgeFacts(index, left.object, property)) {
269
+ if (right.object.id === object.id) {
270
+ return true;
271
+ }
272
+ }
273
+ }
274
+ return false;
275
+ }
276
+ applyForwardRulesTriggeredByFact(fact, index, tbox) {
277
+ const heads = [];
278
+ for (const rule of tbox.forwardRules) {
279
+ rule.body.forEach((atom, anchorIndex) => {
280
+ const bindings = this.matchAtomToFact(atom, fact, new Map());
281
+ if (!bindings) {
282
+ return;
283
+ }
284
+ for (const resolved of this.resolveRuleBody(rule.body, index, bindings, anchorIndex)) {
285
+ for (const head of rule.head) {
286
+ const inferred = this.instantiateRuleAtom(head, resolved);
287
+ if (inferred) {
288
+ heads.push(inferred);
289
+ }
290
+ }
291
+ }
292
+ });
293
+ }
294
+ return this.uniqueFacts(heads);
295
+ }
296
+ hasForwardRuleSupport(fact, index, tbox) {
297
+ for (const rule of tbox.forwardRules) {
298
+ for (const head of rule.head) {
299
+ const bindings = this.matchAtomToFact(head, fact, new Map());
300
+ if (!bindings) {
301
+ continue;
302
+ }
303
+ const resolved = this.resolveRuleBody(rule.body, index, bindings, -1);
304
+ if (resolved.length > 0) {
305
+ return true;
306
+ }
307
+ }
308
+ }
309
+ return false;
310
+ }
311
+ resolveRuleBody(body, index, bindings, satisfiedIndex) {
312
+ const pending = body.filter((_atom, index) => index !== satisfiedIndex);
313
+ return this.resolvePendingAtoms(pending, index, bindings);
314
+ }
315
+ resolvePendingAtoms(pending, index, bindings) {
316
+ if (pending.length === 0) {
317
+ return [bindings];
318
+ }
319
+ const [current, ...rest] = pending;
320
+ const matches = this.findMatchesForAtom(current, index, bindings);
321
+ const resolved = [];
322
+ for (const nextBindings of matches) {
323
+ resolved.push(...this.resolvePendingAtoms(rest, index, nextBindings));
324
+ }
325
+ return resolved;
326
+ }
327
+ findMatchesForAtom(atom, index, bindings) {
328
+ const matches = [];
329
+ for (const fact of this.candidateFacts(atom, index, bindings)) {
330
+ const nextBindings = this.matchAtomToFact(atom, fact, bindings);
331
+ if (nextBindings) {
332
+ matches.push(nextBindings);
333
+ }
334
+ }
335
+ return matches;
336
+ }
337
+ candidateFacts(atom, index, bindings) {
338
+ if (atom.kind === 'class') {
339
+ const bound = this.resolvePatternTerm(atom.argument, bindings);
340
+ if (bound) {
341
+ return [...this.getTypes(index, bound)].map((classIri) => this.typeFact(bound, classIri));
342
+ }
343
+ const subjects = index.subjectsByType.get(atom.classIri) ?? new Set();
344
+ return [...subjects]
345
+ .map((subjectKey) => index.termByKey.get(subjectKey))
346
+ .filter((term) => Boolean(term))
347
+ .map((subject) => this.typeFact(subject, atom.classIri));
348
+ }
349
+ const left = this.resolvePatternTerm(atom.argument1, bindings);
350
+ const right = this.resolvePatternTerm(atom.argument2, bindings);
351
+ if (left) {
352
+ return this.getEdgeFacts(index, left, atom.propertyIri);
353
+ }
354
+ if (right) {
355
+ return this.getIncomingEdgesByProperty(index, right, atom.propertyIri);
356
+ }
357
+ return index.edgeFactsByProperty.get(atom.propertyIri) ?? [];
358
+ }
359
+ matchAtomToFact(atom, fact, bindings) {
360
+ if (atom.kind === 'class') {
361
+ if (!this.isTypeFact(fact) || fact.object.value !== atom.classIri) {
362
+ return undefined;
363
+ }
364
+ return this.matchPattern(atom.argument, fact.subject, bindings);
365
+ }
366
+ if (fact.predicate.value !== atom.propertyIri) {
367
+ return undefined;
368
+ }
369
+ const afterLeft = this.matchPattern(atom.argument1, fact.subject, bindings);
370
+ if (!afterLeft) {
371
+ return undefined;
372
+ }
373
+ return this.matchPattern(atom.argument2, fact.object, afterLeft);
374
+ }
375
+ matchPattern(pattern, term, bindings) {
376
+ if (pattern.kind === 'variable') {
377
+ const existing = bindings.get(pattern.name);
378
+ if (existing) {
379
+ return this.sameTerm(existing, term) ? bindings : undefined;
380
+ }
381
+ const next = new Map(bindings);
382
+ next.set(pattern.name, term);
383
+ return next;
384
+ }
385
+ if (pattern.kind === 'named') {
386
+ return term.termType === 'NamedNode' && term.value === pattern.iri ? bindings : undefined;
387
+ }
388
+ if (term.termType !== 'Literal') {
389
+ return undefined;
390
+ }
391
+ return term.value === pattern.value
392
+ && term.datatype.value === pattern.datatype
393
+ && term.language === pattern.language
394
+ ? bindings
395
+ : undefined;
396
+ }
397
+ resolvePatternTerm(pattern, bindings) {
398
+ if (pattern.kind === 'variable') {
399
+ return bindings.get(pattern.name);
400
+ }
401
+ if (pattern.kind === 'named') {
402
+ return namedNode(pattern.iri);
403
+ }
404
+ return DataFactory.literal(pattern.value, pattern.language || namedNode(pattern.datatype));
405
+ }
406
+ instantiateRuleAtom(atom, bindings) {
407
+ if (atom.kind === 'class') {
408
+ const subject = this.resolvePatternTerm(atom.argument, bindings);
409
+ if (!subject || subject.termType === 'Literal') {
410
+ return undefined;
411
+ }
412
+ return this.typeFact(subject, atom.classIri);
413
+ }
414
+ const subject = this.resolvePatternTerm(atom.argument1, bindings);
415
+ const object = this.resolvePatternTerm(atom.argument2, bindings);
416
+ if (!subject || !object || subject.termType === 'Literal') {
417
+ return undefined;
418
+ }
419
+ return this.edgeFact(subject, atom.propertyIri, object);
420
+ }
421
+ sameTerm(left, right) {
422
+ return left.termType === right.termType
423
+ && left.value === right.value
424
+ && (left.termType !== 'Literal'
425
+ || (right.termType === 'Literal'
426
+ && left.datatype.value === right.datatype.value
427
+ && left.language === right.language));
428
+ }
429
+ resolveScope(modelUri, readModelUris) {
430
+ const store = this.reasoningStore.getStore();
431
+ const facts = new Map();
432
+ const baseKeys = new Set();
433
+ const importEntKeys = new Set();
434
+ const ownEntKeys = new Set();
435
+ const ownBaseFacts = [];
436
+ const ownGraphs = this.reasoningStore.graphs(modelUri);
437
+ for (const uri of readModelUris) {
438
+ let graphs;
439
+ try {
440
+ graphs = this.reasoningStore.graphs(uri);
441
+ }
442
+ catch {
443
+ continue;
444
+ }
445
+ for (const q of store.getQuads(null, null, null, graphs.own)) {
446
+ const fact = this.asFact(q);
447
+ const key = this.factKey(fact);
448
+ facts.set(key, fact);
449
+ baseKeys.add(key);
450
+ if (uri === modelUri) {
451
+ ownBaseFacts.push(fact);
452
+ }
453
+ }
454
+ for (const q of store.getQuads(null, null, null, graphs.entailments)) {
455
+ const fact = this.asFact(q);
456
+ const key = this.factKey(fact);
457
+ facts.set(key, fact);
458
+ if (uri === modelUri) {
459
+ ownEntKeys.add(key);
460
+ }
461
+ else {
462
+ importEntKeys.add(key);
463
+ }
464
+ }
465
+ }
466
+ return {
467
+ ownEntailmentGraph: ownGraphs.entailments,
468
+ ownBaseFacts: this.uniqueFacts(ownBaseFacts),
469
+ baseKeys,
470
+ importEntKeys,
471
+ ownEntKeys,
472
+ facts,
473
+ };
474
+ }
475
+ buildIndex(facts) {
476
+ const typesBySubject = new Map();
477
+ const subjectsByType = new Map();
478
+ const edgeFactsBySubjectProperty = new Map();
479
+ const edgeFactsByProperty = new Map();
480
+ const subjectsByPropertyObject = new Map();
481
+ const termByKey = new Map();
482
+ for (const fact of facts.values()) {
483
+ const sKey = fact.subject.id;
484
+ const oKey = fact.object.id;
485
+ termByKey.set(sKey, fact.subject);
486
+ termByKey.set(oKey, fact.object);
487
+ if (fact.predicate.value === RDF_TYPE.value && fact.object.termType === 'NamedNode') {
488
+ const values = typesBySubject.get(sKey) ?? new Set();
489
+ values.add(fact.object.value);
490
+ typesBySubject.set(sKey, values);
491
+ const subjects = subjectsByType.get(fact.object.value) ?? new Set();
492
+ subjects.add(sKey);
493
+ subjectsByType.set(fact.object.value, subjects);
494
+ continue;
495
+ }
496
+ const spKey = `${sKey}|${fact.predicate.value}`;
497
+ const bySp = edgeFactsBySubjectProperty.get(spKey) ?? [];
498
+ bySp.push(fact);
499
+ edgeFactsBySubjectProperty.set(spKey, bySp);
500
+ const byProperty = edgeFactsByProperty.get(fact.predicate.value) ?? [];
501
+ byProperty.push(fact);
502
+ edgeFactsByProperty.set(fact.predicate.value, byProperty);
503
+ const poKey = `${fact.predicate.value}|${oKey}`;
504
+ const subjects = subjectsByPropertyObject.get(poKey) ?? new Set();
505
+ subjects.add(sKey);
506
+ subjectsByPropertyObject.set(poKey, subjects);
507
+ }
508
+ return {
509
+ facts,
510
+ typesBySubject,
511
+ subjectsByType,
512
+ edgeFactsBySubjectProperty,
513
+ edgeFactsByProperty,
514
+ subjectsByPropertyObject,
515
+ termByKey,
516
+ };
517
+ }
518
+ insertOwnEntailedFact(scope, index, store, fact) {
519
+ const key = this.factKey(fact);
520
+ if (scope.ownEntKeys.has(key)) {
521
+ return;
522
+ }
523
+ scope.ownEntKeys.add(key);
524
+ scope.facts.set(key, fact);
525
+ index.facts.set(key, fact);
526
+ this.indexAdd(index, fact);
527
+ store.addQuad(quad(this.asQuadSubject(fact.subject), fact.predicate, this.asQuadObject(fact.object), scope.ownEntailmentGraph));
528
+ }
529
+ removeOwnEntailedFact(scope, index, store, fact) {
530
+ const key = this.factKey(fact);
531
+ if (!scope.ownEntKeys.has(key)) {
532
+ return;
533
+ }
534
+ scope.ownEntKeys.delete(key);
535
+ scope.facts.delete(key);
536
+ index.facts.delete(key);
537
+ this.indexRemove(index, fact);
538
+ store.removeQuad(quad(this.asQuadSubject(fact.subject), fact.predicate, this.asQuadObject(fact.object), scope.ownEntailmentGraph));
539
+ }
540
+ canInsertEntailedFact(scope, fact) {
541
+ const key = this.factKey(fact);
542
+ return !scope.baseKeys.has(key) && !scope.importEntKeys.has(key) && !scope.ownEntKeys.has(key);
543
+ }
544
+ getTypes(index, subject) {
545
+ return index.typesBySubject.get(subject.id) ?? new Set();
546
+ }
547
+ getEdgeFacts(index, subject, property) {
548
+ return index.edgeFactsBySubjectProperty.get(`${subject.id}|${property}`) ?? [];
549
+ }
550
+ getOutgoingEdges(index, subject) {
551
+ const edges = [];
552
+ const prefix = `${subject.id}|`;
553
+ for (const [key, facts] of index.edgeFactsBySubjectProperty.entries()) {
554
+ if (key.startsWith(prefix)) {
555
+ edges.push(...facts);
556
+ }
557
+ }
558
+ return edges;
559
+ }
560
+ getIncomingEdges(index, object) {
561
+ const edges = [];
562
+ const suffix = `|${object.id}`;
563
+ for (const [key, subjects] of index.subjectsByPropertyObject.entries()) {
564
+ if (!key.endsWith(suffix)) {
565
+ continue;
566
+ }
567
+ const property = key.slice(0, key.length - suffix.length);
568
+ for (const subjectKey of subjects) {
569
+ const subject = index.termByKey.get(subjectKey);
570
+ if (subject) {
571
+ edges.push(...this.getEdgeFacts(index, subject, property));
572
+ }
573
+ }
574
+ }
575
+ return edges;
576
+ }
577
+ getIncomingEdgesByProperty(index, object, property) {
578
+ const subjects = index.subjectsByPropertyObject.get(`${property}|${object.id}`) ?? new Set();
579
+ const edges = [];
580
+ for (const subjectKey of subjects) {
581
+ const subject = index.termByKey.get(subjectKey);
582
+ if (subject) {
583
+ edges.push(...this.getEdgeFacts(index, subject, property));
584
+ }
585
+ }
586
+ return edges;
587
+ }
588
+ getSuperClasses(tbox, clazz) {
589
+ return tbox.superClasses.get(clazz) ?? [];
590
+ }
591
+ getSuperProperties(tbox, property) {
592
+ return tbox.subProperties.get(property) ?? [property];
593
+ }
594
+ getDomains(tbox, property) {
595
+ return tbox.domain.get(property) ?? [];
596
+ }
597
+ getObjectRanges(tbox, property) {
598
+ return tbox.objectRange.get(property) ?? [];
599
+ }
600
+ getInverses(tbox, property) {
601
+ return tbox.inverseRoles.get(property) ?? [];
602
+ }
603
+ isSymmetricProperty(tbox, property) {
604
+ return tbox.symmetricProperties.has(property);
605
+ }
606
+ isTransitiveProperty(tbox, property) {
607
+ return tbox.transitiveProperties.has(property);
608
+ }
609
+ typeFact(subject, classIri) {
610
+ return { subject, predicate: RDF_TYPE, object: namedNode(classIri) };
611
+ }
612
+ edgeFact(subject, propertyIri, object) {
613
+ return { subject, predicate: namedNode(propertyIri), object };
614
+ }
615
+ isTypeFact(fact) {
616
+ return fact.predicate.value === RDF_TYPE.value && fact.object.termType === 'NamedNode';
617
+ }
618
+ asFact(q) {
619
+ return {
620
+ subject: q.subject,
621
+ predicate: q.predicate,
622
+ object: q.object,
623
+ };
624
+ }
625
+ asQuadSubject(term) {
626
+ if (term.termType === 'NamedNode' || term.termType === 'BlankNode' || term.termType === 'Variable') {
627
+ return term;
628
+ }
629
+ throw new Error(`Invalid inferred subject term '${term.termType}'.`);
630
+ }
631
+ asQuadObject(term) {
632
+ if (term.termType === 'NamedNode'
633
+ || term.termType === 'BlankNode'
634
+ || term.termType === 'Variable'
635
+ || term.termType === 'Literal') {
636
+ return term;
637
+ }
638
+ throw new Error(`Invalid inferred object term '${term.termType}'.`);
639
+ }
640
+ factKey(fact) {
641
+ return `${fact.subject.id}|${fact.predicate.id}|${fact.object.id}`;
642
+ }
643
+ uniqueFacts(facts) {
644
+ const byKey = new Map();
645
+ for (const fact of facts) {
646
+ byKey.set(this.factKey(fact), fact);
647
+ }
648
+ return [...byKey.values()];
649
+ }
650
+ indexAdd(index, fact) {
651
+ index.termByKey.set(fact.subject.id, fact.subject);
652
+ index.termByKey.set(fact.object.id, fact.object);
653
+ if (fact.predicate.value === RDF_TYPE.value && fact.object.termType === 'NamedNode') {
654
+ const values = index.typesBySubject.get(fact.subject.id) ?? new Set();
655
+ values.add(fact.object.value);
656
+ index.typesBySubject.set(fact.subject.id, values);
657
+ const subjects = index.subjectsByType.get(fact.object.value) ?? new Set();
658
+ subjects.add(fact.subject.id);
659
+ index.subjectsByType.set(fact.object.value, subjects);
660
+ return;
661
+ }
662
+ const spKey = `${fact.subject.id}|${fact.predicate.value}`;
663
+ const bySp = index.edgeFactsBySubjectProperty.get(spKey) ?? [];
664
+ bySp.push(fact);
665
+ index.edgeFactsBySubjectProperty.set(spKey, bySp);
666
+ const byProperty = index.edgeFactsByProperty.get(fact.predicate.value) ?? [];
667
+ byProperty.push(fact);
668
+ index.edgeFactsByProperty.set(fact.predicate.value, byProperty);
669
+ const poKey = `${fact.predicate.value}|${fact.object.id}`;
670
+ const subjects = index.subjectsByPropertyObject.get(poKey) ?? new Set();
671
+ subjects.add(fact.subject.id);
672
+ index.subjectsByPropertyObject.set(poKey, subjects);
673
+ }
674
+ indexRemove(index, fact) {
675
+ if (fact.predicate.value === RDF_TYPE.value && fact.object.termType === 'NamedNode') {
676
+ const values = index.typesBySubject.get(fact.subject.id);
677
+ if (!values) {
678
+ return;
679
+ }
680
+ values.delete(fact.object.value);
681
+ if (values.size === 0) {
682
+ index.typesBySubject.delete(fact.subject.id);
683
+ }
684
+ const subjects = index.subjectsByType.get(fact.object.value);
685
+ if (subjects) {
686
+ subjects.delete(fact.subject.id);
687
+ if (subjects.size === 0) {
688
+ index.subjectsByType.delete(fact.object.value);
689
+ }
690
+ }
691
+ return;
692
+ }
693
+ const spKey = `${fact.subject.id}|${fact.predicate.value}`;
694
+ const bySp = index.edgeFactsBySubjectProperty.get(spKey) ?? [];
695
+ const nextBySp = bySp.filter((entry) => this.factKey(entry) !== this.factKey(fact));
696
+ if (nextBySp.length === 0) {
697
+ index.edgeFactsBySubjectProperty.delete(spKey);
698
+ }
699
+ else {
700
+ index.edgeFactsBySubjectProperty.set(spKey, nextBySp);
701
+ }
702
+ const byProperty = index.edgeFactsByProperty.get(fact.predicate.value) ?? [];
703
+ const nextByProperty = byProperty.filter((entry) => this.factKey(entry) !== this.factKey(fact));
704
+ if (nextByProperty.length === 0) {
705
+ index.edgeFactsByProperty.delete(fact.predicate.value);
706
+ }
707
+ else {
708
+ index.edgeFactsByProperty.set(fact.predicate.value, nextByProperty);
709
+ }
710
+ const poKey = `${fact.predicate.value}|${fact.object.id}`;
711
+ const subjects = index.subjectsByPropertyObject.get(poKey);
712
+ if (!subjects) {
713
+ return;
714
+ }
715
+ const stillHas = nextBySp.some((entry) => entry.object.id === fact.object.id);
716
+ if (!stillHas) {
717
+ subjects.delete(fact.subject.id);
718
+ }
719
+ if (subjects.size === 0) {
720
+ index.subjectsByPropertyObject.delete(poKey);
721
+ }
722
+ }
723
+ collectValidationWarnings(index, tbox) {
724
+ const warnings = [];
725
+ for (const fact of index.facts.values()) {
726
+ if (fact.predicate.value === RDF_TYPE.value) {
727
+ continue;
728
+ }
729
+ const ranges = tbox.datatypeRange.get(fact.predicate.value) ?? [];
730
+ if (ranges.length === 0) {
731
+ continue;
732
+ }
733
+ if (fact.object.termType !== 'Literal') {
734
+ warnings.push(`Datatype range violation on ${fact.predicate.value}: expected literal object.`);
735
+ continue;
736
+ }
737
+ if (!ranges.includes(fact.object.datatype.value)) {
738
+ warnings.push(`Datatype range violation on ${fact.predicate.value}: expected ${ranges.join(', ')}, got ${fact.object.datatype.value}.`);
739
+ }
740
+ }
741
+ for (const [subjectProperty, facts] of index.edgeFactsBySubjectProperty.entries()) {
742
+ const [subjectId, property] = subjectProperty.split('|', 2);
743
+ if (subjectId.length === 0 || !tbox.functionalProperties.has(property)) {
744
+ continue;
745
+ }
746
+ const objectIds = [...new Set(facts.map((fact) => fact.object.id))];
747
+ if (objectIds.length > 1) {
748
+ warnings.push(`Functional property violation on ${property}: ${facts[0]?.subject.value ?? subjectId} has ${objectIds.length} distinct values.`);
749
+ }
750
+ }
751
+ for (const [propertyObject, subjectIds] of index.subjectsByPropertyObject.entries()) {
752
+ const split = propertyObject.indexOf('|');
753
+ const property = split >= 0 ? propertyObject.slice(0, split) : propertyObject;
754
+ const objectId = split >= 0 ? propertyObject.slice(split + 1) : '';
755
+ if (!tbox.inverseFunctionalProperties.has(property) || subjectIds.size <= 1) {
756
+ continue;
757
+ }
758
+ const object = index.termByKey.get(objectId);
759
+ const objectLabel = object?.value ?? objectId;
760
+ warnings.push(`Inverse-functional property violation on ${property}: ${objectLabel} has ${subjectIds.size} distinct sources.`);
761
+ }
762
+ return [...new Set(warnings)];
763
+ }
764
+ }
765
+ //# sourceMappingURL=owl-abox.js.map