@oml/owl 0.14.14 → 0.14.16
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/out/index.d.ts +1 -0
- package/out/index.js +1 -0
- package/out/index.js.map +1 -1
- package/out/owl/owl-closure.d.ts +33 -0
- package/out/owl/owl-closure.js +537 -0
- package/out/owl/owl-closure.js.map +1 -0
- package/out/owl/owl-service.d.ts +4 -1
- package/out/owl/owl-service.js +56 -1
- package/out/owl/owl-service.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +1 -0
- package/src/owl/owl-closure.ts +624 -0
- package/src/owl/owl-service.ts +60 -2
package/src/owl/owl-service.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
2
|
|
|
3
3
|
import { DocumentState, URI, type LangiumDocument } from 'langium';
|
|
4
|
-
import type
|
|
4
|
+
import { DataFactory, type NamedNode, type Quad } from 'n3';
|
|
5
5
|
import { OmlIndex, getOntologyModelIndex, isDescription, isDescriptionBundle, isOntology, isVocabulary, isVocabularyBundle, type Import, type OmlServices, type Ontology } from '@oml/language';
|
|
6
6
|
import { Oml2OwlMapper } from './owl-mapper.js';
|
|
7
|
+
import { VocabularyBundleClosureBuilder } from './owl-closure.js';
|
|
7
8
|
import { ReasoningStore } from './owl-store.js';
|
|
8
9
|
import { ABoxChainer, ABoxEntailmentCache, type ChainingResult } from './owl-abox.js';
|
|
9
10
|
import { ImportGraph } from './owl-imports.js';
|
|
@@ -73,7 +74,7 @@ export class ReasoningService {
|
|
|
73
74
|
const importedModelUris = this.extractImportedModelUris(ontology as Ontology);
|
|
74
75
|
this.importGraph.update(modelUri, importedModelUris);
|
|
75
76
|
|
|
76
|
-
const quads = this.
|
|
77
|
+
const quads = this.mapOntologyToQuads(ontology as Ontology);
|
|
77
78
|
const diff = this.reasoningStore.diffModel(modelUri, quads);
|
|
78
79
|
if (diff.isEmpty) {
|
|
79
80
|
return;
|
|
@@ -91,6 +92,7 @@ export class ReasoningService {
|
|
|
91
92
|
const tboxIndex = this.tboxIndexBuilder.buildOwn(modelUri, ontology);
|
|
92
93
|
this.tboxIndexCache.setOwn(modelUri, tboxIndex);
|
|
93
94
|
const dependents = this.importGraph.dependentsOf(modelUri);
|
|
95
|
+
this.refreshDependentVocabularyBundleModels(dependents);
|
|
94
96
|
this.tboxIndexCache.invalidateMergedAll(dependents);
|
|
95
97
|
this.aboxEntailmentCache.markDirtyAll(dependents);
|
|
96
98
|
for (const dependent of dependents) {
|
|
@@ -659,6 +661,62 @@ export class ReasoningService {
|
|
|
659
661
|
listener(unique);
|
|
660
662
|
}
|
|
661
663
|
}
|
|
664
|
+
|
|
665
|
+
private mapOntologyToQuads(ontology: Ontology): Quad[] {
|
|
666
|
+
const mapped = this.mapper.toQuads(ontology);
|
|
667
|
+
if (!isVocabularyBundle(ontology)) {
|
|
668
|
+
return mapped;
|
|
669
|
+
}
|
|
670
|
+
const builder = this.createVocabularyBundleClosureBuilder();
|
|
671
|
+
const closure = builder.buildClosureQuads(ontology)
|
|
672
|
+
.map((quad) => DataFactory.quad(quad.subject, quad.predicate, quad.object));
|
|
673
|
+
return [...mapped, ...closure];
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
private createVocabularyBundleClosureBuilder(): VocabularyBundleClosureBuilder {
|
|
677
|
+
const ontologyByNamespace = new Map<string, Ontology>();
|
|
678
|
+
const documents = this.services.shared.workspace.LangiumDocuments;
|
|
679
|
+
const all = documents.all ?? [];
|
|
680
|
+
const iterable: LangiumDocument[] = Array.isArray(all)
|
|
681
|
+
? all
|
|
682
|
+
: (typeof (all as any)?.toArray === 'function'
|
|
683
|
+
? (all as any).toArray()
|
|
684
|
+
: Array.from(all as Iterable<LangiumDocument>));
|
|
685
|
+
|
|
686
|
+
for (const document of iterable) {
|
|
687
|
+
const root = document?.parseResult?.value;
|
|
688
|
+
if (!isOntology(root)) {
|
|
689
|
+
continue;
|
|
690
|
+
}
|
|
691
|
+
const ontology = root as Ontology;
|
|
692
|
+
const namespace = this.normalizeNamespace((ontology as any).namespace ?? '').replace(/[\/#]+$/, '');
|
|
693
|
+
if (!namespace) {
|
|
694
|
+
continue;
|
|
695
|
+
}
|
|
696
|
+
ontologyByNamespace.set(namespace, ontology);
|
|
697
|
+
}
|
|
698
|
+
return new VocabularyBundleClosureBuilder(ontologyByNamespace);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
private refreshDependentVocabularyBundleModels(modelUris: ReadonlyArray<string>): void {
|
|
702
|
+
for (const modelUri of modelUris) {
|
|
703
|
+
const document = this.services.shared.workspace.LangiumDocuments.getDocument(URI.parse(modelUri));
|
|
704
|
+
if (!document) {
|
|
705
|
+
continue;
|
|
706
|
+
}
|
|
707
|
+
const ontology = document.parseResult?.value;
|
|
708
|
+
if (!isVocabularyBundle(ontology)) {
|
|
709
|
+
continue;
|
|
710
|
+
}
|
|
711
|
+
const quads = this.mapOntologyToQuads(ontology);
|
|
712
|
+
const diff = this.reasoningStore.diffModel(modelUri, quads);
|
|
713
|
+
if (diff.isEmpty) {
|
|
714
|
+
continue;
|
|
715
|
+
}
|
|
716
|
+
this.reasoningStore.retractModel(modelUri);
|
|
717
|
+
this.reasoningStore.loadModel(modelUri, quads);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
662
720
|
}
|
|
663
721
|
|
|
664
722
|
export interface PreparedReasonedModel {
|