@nahisaho/musubix-ontology-mcp 1.0.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 (45) hide show
  1. package/dist/index.d.ts +12 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +17 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/inference/index.d.ts +6 -0
  6. package/dist/inference/index.d.ts.map +1 -0
  7. package/dist/inference/index.js +6 -0
  8. package/dist/inference/index.js.map +1 -0
  9. package/dist/inference/rule-engine.d.ts +149 -0
  10. package/dist/inference/rule-engine.d.ts.map +1 -0
  11. package/dist/inference/rule-engine.js +478 -0
  12. package/dist/inference/rule-engine.js.map +1 -0
  13. package/dist/integration/index.d.ts +6 -0
  14. package/dist/integration/index.d.ts.map +1 -0
  15. package/dist/integration/index.js +6 -0
  16. package/dist/integration/index.js.map +1 -0
  17. package/dist/integration/pattern-bridge.d.ts +146 -0
  18. package/dist/integration/pattern-bridge.d.ts.map +1 -0
  19. package/dist/integration/pattern-bridge.js +517 -0
  20. package/dist/integration/pattern-bridge.js.map +1 -0
  21. package/dist/privacy/index.d.ts +6 -0
  22. package/dist/privacy/index.d.ts.map +1 -0
  23. package/dist/privacy/index.js +6 -0
  24. package/dist/privacy/index.js.map +1 -0
  25. package/dist/privacy/privacy-guard.d.ts +43 -0
  26. package/dist/privacy/privacy-guard.d.ts.map +1 -0
  27. package/dist/privacy/privacy-guard.js +59 -0
  28. package/dist/privacy/privacy-guard.js.map +1 -0
  29. package/dist/store/index.d.ts +7 -0
  30. package/dist/store/index.d.ts.map +1 -0
  31. package/dist/store/index.js +7 -0
  32. package/dist/store/index.js.map +1 -0
  33. package/dist/store/n3-store.d.ts +115 -0
  34. package/dist/store/n3-store.d.ts.map +1 -0
  35. package/dist/store/n3-store.js +344 -0
  36. package/dist/store/n3-store.js.map +1 -0
  37. package/dist/store/ontology-store.d.ts +59 -0
  38. package/dist/store/ontology-store.d.ts.map +1 -0
  39. package/dist/store/ontology-store.js +135 -0
  40. package/dist/store/ontology-store.js.map +1 -0
  41. package/dist/types.d.ts +81 -0
  42. package/dist/types.d.ts.map +1 -0
  43. package/dist/types.js +6 -0
  44. package/dist/types.js.map +1 -0
  45. package/package.json +50 -0
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @fileoverview MUSUBIX Ontology Reasoning MCP
3
+ * @module @nahisaho/musubix-ontology-mcp
4
+ * @version 1.0.0
5
+ * @traceability REQ-ONTO-001
6
+ */
7
+ export * from './types.js';
8
+ export * from './store/index.js';
9
+ export * from './privacy/index.js';
10
+ export * from './inference/index.js';
11
+ export * from './integration/index.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,YAAY,CAAC;AAG3B,cAAc,kBAAkB,CAAC;AAGjC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,sBAAsB,CAAC;AAGrC,cAAc,wBAAwB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @fileoverview MUSUBIX Ontology Reasoning MCP
3
+ * @module @nahisaho/musubix-ontology-mcp
4
+ * @version 1.0.0
5
+ * @traceability REQ-ONTO-001
6
+ */
7
+ // Types
8
+ export * from './types.js';
9
+ // Ontology Store (TSK-ONTO-001)
10
+ export * from './store/index.js';
11
+ // Privacy Protection (TSK-ONTO-008)
12
+ export * from './privacy/index.js';
13
+ // Inference Engine (TSK-ONTO-002)
14
+ export * from './inference/index.js';
15
+ // Pattern Integration (TSK-INT-001)
16
+ export * from './integration/index.js';
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,QAAQ;AACR,cAAc,YAAY,CAAC;AAE3B,gCAAgC;AAChC,cAAc,kBAAkB,CAAC;AAEjC,oCAAoC;AACpC,cAAc,oBAAoB,CAAC;AAEnC,kCAAkC;AAClC,cAAc,sBAAsB,CAAC;AAErC,oCAAoC;AACpC,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @fileoverview Inference module exports
3
+ * @traceability TSK-ONTO-002
4
+ */
5
+ export { RuleEngine, type InferenceRuleDefinition, type RuleCondition, type RuleAction, type Bindings, type RuleMatch, type InferenceStats, } from './rule-engine.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/inference/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,UAAU,EACV,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,cAAc,GACpB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @fileoverview Inference module exports
3
+ * @traceability TSK-ONTO-002
4
+ */
5
+ export { RuleEngine, } from './rule-engine.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/inference/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,UAAU,GAOX,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * @fileoverview Inference Rule Engine for Ontology Store
3
+ * @traceability TSK-ONTO-002, REQ-ONTO-001
4
+ */
5
+ import type { Triple } from '../types.js';
6
+ /**
7
+ * Rule condition types
8
+ */
9
+ export type RuleCondition = {
10
+ type: 'triple-pattern';
11
+ subject?: string | {
12
+ variable: string;
13
+ };
14
+ predicate?: string | {
15
+ variable: string;
16
+ };
17
+ object?: string | {
18
+ variable: string;
19
+ };
20
+ } | {
21
+ type: 'transitive';
22
+ predicate: string;
23
+ } | {
24
+ type: 'symmetric';
25
+ predicate: string;
26
+ } | {
27
+ type: 'inverse';
28
+ predicate1: string;
29
+ predicate2: string;
30
+ };
31
+ /**
32
+ * Rule action types
33
+ */
34
+ export type RuleAction = {
35
+ type: 'add-triple';
36
+ subject: string | {
37
+ variable: string;
38
+ };
39
+ predicate: string;
40
+ object: string | {
41
+ variable: string;
42
+ };
43
+ };
44
+ /**
45
+ * Inference rule definition
46
+ */
47
+ export interface InferenceRuleDefinition {
48
+ id: string;
49
+ name: string;
50
+ description?: string;
51
+ priority: number;
52
+ conditions: RuleCondition[];
53
+ actions: RuleAction[];
54
+ }
55
+ /**
56
+ * Binding map for variables
57
+ */
58
+ export type Bindings = Record<string, string>;
59
+ /**
60
+ * Rule match result
61
+ */
62
+ export interface RuleMatch {
63
+ ruleId: string;
64
+ bindings: Bindings;
65
+ inferredTriples: Triple[];
66
+ }
67
+ /**
68
+ * Inference statistics
69
+ */
70
+ export interface InferenceStats {
71
+ rulesApplied: number;
72
+ triplesInferred: number;
73
+ iterationsUsed: number;
74
+ timeMs: number;
75
+ }
76
+ /**
77
+ * Rule Engine for applying inference rules
78
+ */
79
+ export declare class RuleEngine {
80
+ private rules;
81
+ private maxIterations;
82
+ constructor(options?: {
83
+ maxIterations?: number;
84
+ });
85
+ /**
86
+ * Load built-in RDFS/OWL inference rules
87
+ */
88
+ private loadBuiltinRules;
89
+ /**
90
+ * Add a rule to the engine
91
+ */
92
+ addRule(rule: InferenceRuleDefinition): void;
93
+ /**
94
+ * Remove a rule
95
+ */
96
+ removeRule(ruleId: string): boolean;
97
+ /**
98
+ * Get all rules
99
+ */
100
+ getRules(): InferenceRuleDefinition[];
101
+ /**
102
+ * Apply all rules to triples until fixpoint
103
+ */
104
+ applyRules(triples: Triple[]): {
105
+ triples: Triple[];
106
+ stats: InferenceStats;
107
+ };
108
+ /**
109
+ * Apply transitive closure for a predicate
110
+ */
111
+ private applyTransitiveClosure;
112
+ /**
113
+ * Apply symmetry for a predicate
114
+ */
115
+ private applySymmetry;
116
+ /**
117
+ * Apply inverse property rule
118
+ */
119
+ private applyInverse;
120
+ /**
121
+ * Get symmetric properties from triples
122
+ */
123
+ private getSymmetricProperties;
124
+ /**
125
+ * Get inverse property pairs from triples
126
+ */
127
+ private getInverseProperties;
128
+ /**
129
+ * Match a rule against triples
130
+ */
131
+ private matchRule;
132
+ /**
133
+ * Match a pattern against a triple
134
+ */
135
+ private matchPattern;
136
+ /**
137
+ * Check if two binding sets are compatible
138
+ */
139
+ private compatibleBindings;
140
+ /**
141
+ * Apply actions with bindings
142
+ */
143
+ private applyActions;
144
+ /**
145
+ * Create unique key for triple
146
+ */
147
+ private tripleKey;
148
+ }
149
+ //# sourceMappingURL=rule-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule-engine.d.ts","sourceRoot":"","sources":["../../src/inference/rule-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,478 @@
1
+ /**
2
+ * @fileoverview Inference Rule Engine for Ontology Store
3
+ * @traceability TSK-ONTO-002, REQ-ONTO-001
4
+ */
5
+ /**
6
+ * RDFS namespace constants
7
+ */
8
+ const RDFS = {
9
+ subClassOf: 'http://www.w3.org/2000/01/rdf-schema#subClassOf',
10
+ subPropertyOf: 'http://www.w3.org/2000/01/rdf-schema#subPropertyOf',
11
+ domain: 'http://www.w3.org/2000/01/rdf-schema#domain',
12
+ range: 'http://www.w3.org/2000/01/rdf-schema#range',
13
+ };
14
+ const RDF = {
15
+ type: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type',
16
+ };
17
+ const OWL = {
18
+ TransitiveProperty: 'http://www.w3.org/2002/07/owl#TransitiveProperty',
19
+ SymmetricProperty: 'http://www.w3.org/2002/07/owl#SymmetricProperty',
20
+ InverseFunctionalProperty: 'http://www.w3.org/2002/07/owl#InverseFunctionalProperty',
21
+ inverseOf: 'http://www.w3.org/2002/07/owl#inverseOf',
22
+ sameAs: 'http://www.w3.org/2002/07/owl#sameAs',
23
+ };
24
+ /**
25
+ * Rule Engine for applying inference rules
26
+ */
27
+ export class RuleEngine {
28
+ rules = new Map();
29
+ maxIterations;
30
+ constructor(options) {
31
+ this.maxIterations = options?.maxIterations ?? 10;
32
+ this.loadBuiltinRules();
33
+ }
34
+ /**
35
+ * Load built-in RDFS/OWL inference rules
36
+ */
37
+ loadBuiltinRules() {
38
+ // RDFS9: subClassOf transitivity
39
+ this.addRule({
40
+ id: 'rdfs9',
41
+ name: 'RDFS SubClass Transitivity',
42
+ description: 'If X subClassOf Y and Y subClassOf Z, then X subClassOf Z',
43
+ priority: 100,
44
+ conditions: [
45
+ { type: 'transitive', predicate: RDFS.subClassOf },
46
+ ],
47
+ actions: [],
48
+ });
49
+ // RDFS7: subPropertyOf transitivity
50
+ this.addRule({
51
+ id: 'rdfs7',
52
+ name: 'RDFS SubProperty Transitivity',
53
+ description: 'If P subPropertyOf Q and Q subPropertyOf R, then P subPropertyOf R',
54
+ priority: 100,
55
+ conditions: [
56
+ { type: 'transitive', predicate: RDFS.subPropertyOf },
57
+ ],
58
+ actions: [],
59
+ });
60
+ // RDFS11: type inheritance through subClassOf
61
+ this.addRule({
62
+ id: 'rdfs11',
63
+ name: 'RDFS Type Inheritance',
64
+ description: 'If X type C and C subClassOf D, then X type D',
65
+ priority: 90,
66
+ conditions: [
67
+ {
68
+ type: 'triple-pattern',
69
+ subject: { variable: 'x' },
70
+ predicate: RDF.type,
71
+ object: { variable: 'c' },
72
+ },
73
+ {
74
+ type: 'triple-pattern',
75
+ subject: { variable: 'c' },
76
+ predicate: RDFS.subClassOf,
77
+ object: { variable: 'd' },
78
+ },
79
+ ],
80
+ actions: [
81
+ {
82
+ type: 'add-triple',
83
+ subject: { variable: 'x' },
84
+ predicate: RDF.type,
85
+ object: { variable: 'd' },
86
+ },
87
+ ],
88
+ });
89
+ // OWL symmetric property
90
+ this.addRule({
91
+ id: 'owl-symmetric',
92
+ name: 'OWL Symmetric Property',
93
+ description: 'If P is symmetric and X P Y, then Y P X',
94
+ priority: 80,
95
+ conditions: [
96
+ { type: 'symmetric', predicate: '' }, // Placeholder, matched dynamically
97
+ ],
98
+ actions: [],
99
+ });
100
+ // OWL inverse property
101
+ this.addRule({
102
+ id: 'owl-inverse',
103
+ name: 'OWL Inverse Property',
104
+ description: 'If P inverseOf Q and X P Y, then Y Q X',
105
+ priority: 80,
106
+ conditions: [
107
+ { type: 'inverse', predicate1: '', predicate2: '' },
108
+ ],
109
+ actions: [],
110
+ });
111
+ // OWL sameAs transitivity
112
+ this.addRule({
113
+ id: 'owl-sameas-trans',
114
+ name: 'OWL SameAs Transitivity',
115
+ description: 'If X sameAs Y and Y sameAs Z, then X sameAs Z',
116
+ priority: 70,
117
+ conditions: [
118
+ { type: 'transitive', predicate: OWL.sameAs },
119
+ ],
120
+ actions: [],
121
+ });
122
+ // OWL sameAs symmetry
123
+ this.addRule({
124
+ id: 'owl-sameas-sym',
125
+ name: 'OWL SameAs Symmetry',
126
+ description: 'If X sameAs Y, then Y sameAs X',
127
+ priority: 70,
128
+ conditions: [
129
+ { type: 'symmetric', predicate: OWL.sameAs },
130
+ ],
131
+ actions: [],
132
+ });
133
+ }
134
+ /**
135
+ * Add a rule to the engine
136
+ */
137
+ addRule(rule) {
138
+ this.rules.set(rule.id, rule);
139
+ }
140
+ /**
141
+ * Remove a rule
142
+ */
143
+ removeRule(ruleId) {
144
+ return this.rules.delete(ruleId);
145
+ }
146
+ /**
147
+ * Get all rules
148
+ */
149
+ getRules() {
150
+ return Array.from(this.rules.values())
151
+ .sort((a, b) => b.priority - a.priority);
152
+ }
153
+ /**
154
+ * Apply all rules to triples until fixpoint
155
+ */
156
+ applyRules(triples) {
157
+ const startTime = Date.now();
158
+ const tripleSet = new Set(triples.map(t => this.tripleKey(t)));
159
+ const allTriples = [...triples];
160
+ let rulesApplied = 0;
161
+ let triplesInferred = 0;
162
+ // Get symmetric and inverse properties
163
+ const symmetricProps = this.getSymmetricProperties(allTriples);
164
+ const inverseProps = this.getInverseProperties(allTriples);
165
+ for (let iteration = 0; iteration < this.maxIterations; iteration++) {
166
+ const newTriples = [];
167
+ // Apply transitive closure rules
168
+ for (const rule of this.getRules()) {
169
+ for (const condition of rule.conditions) {
170
+ if (condition.type === 'transitive') {
171
+ const inferred = this.applyTransitiveClosure(allTriples, condition.predicate, tripleSet);
172
+ newTriples.push(...inferred);
173
+ if (inferred.length > 0)
174
+ rulesApplied++;
175
+ }
176
+ if (condition.type === 'symmetric') {
177
+ const predicate = condition.predicate || '';
178
+ const predicates = predicate ? [predicate] : symmetricProps;
179
+ for (const p of predicates) {
180
+ const inferred = this.applySymmetry(allTriples, p, tripleSet);
181
+ newTriples.push(...inferred);
182
+ if (inferred.length > 0)
183
+ rulesApplied++;
184
+ }
185
+ }
186
+ if (condition.type === 'inverse') {
187
+ for (const [p1, p2] of inverseProps) {
188
+ const inferred = this.applyInverse(allTriples, p1, p2, tripleSet);
189
+ newTriples.push(...inferred);
190
+ if (inferred.length > 0)
191
+ rulesApplied++;
192
+ }
193
+ }
194
+ }
195
+ }
196
+ // Apply pattern-based rules
197
+ for (const rule of this.getRules()) {
198
+ const matches = this.matchRule(rule, allTriples);
199
+ for (const match of matches) {
200
+ for (const triple of match.inferredTriples) {
201
+ const key = this.tripleKey(triple);
202
+ if (!tripleSet.has(key)) {
203
+ tripleSet.add(key);
204
+ newTriples.push(triple);
205
+ rulesApplied++;
206
+ }
207
+ }
208
+ }
209
+ }
210
+ if (newTriples.length === 0) {
211
+ // Fixpoint reached
212
+ return {
213
+ triples: allTriples,
214
+ stats: {
215
+ rulesApplied,
216
+ triplesInferred,
217
+ iterationsUsed: iteration + 1,
218
+ timeMs: Date.now() - startTime,
219
+ },
220
+ };
221
+ }
222
+ triplesInferred += newTriples.length;
223
+ allTriples.push(...newTriples);
224
+ }
225
+ return {
226
+ triples: allTriples,
227
+ stats: {
228
+ rulesApplied,
229
+ triplesInferred,
230
+ iterationsUsed: this.maxIterations,
231
+ timeMs: Date.now() - startTime,
232
+ },
233
+ };
234
+ }
235
+ /**
236
+ * Apply transitive closure for a predicate
237
+ */
238
+ applyTransitiveClosure(triples, predicate, existingKeys) {
239
+ const inferred = [];
240
+ const edges = triples.filter(t => t.predicate === predicate);
241
+ // Build adjacency map
242
+ const adjacency = new Map();
243
+ for (const edge of edges) {
244
+ if (!adjacency.has(edge.subject)) {
245
+ adjacency.set(edge.subject, new Set());
246
+ }
247
+ adjacency.get(edge.subject).add(edge.object);
248
+ }
249
+ // Compute transitive closure using Warshall-like algorithm
250
+ for (const [start, directTargets] of adjacency) {
251
+ const visited = new Set();
252
+ const queue = [...directTargets];
253
+ while (queue.length > 0) {
254
+ const current = queue.shift();
255
+ if (visited.has(current))
256
+ continue;
257
+ visited.add(current);
258
+ const nextTargets = adjacency.get(current);
259
+ if (nextTargets) {
260
+ for (const next of nextTargets) {
261
+ if (!visited.has(next)) {
262
+ const newTriple = {
263
+ subject: start,
264
+ predicate,
265
+ object: next,
266
+ };
267
+ const key = this.tripleKey(newTriple);
268
+ if (!existingKeys.has(key)) {
269
+ existingKeys.add(key);
270
+ inferred.push(newTriple);
271
+ }
272
+ queue.push(next);
273
+ }
274
+ }
275
+ }
276
+ }
277
+ }
278
+ return inferred;
279
+ }
280
+ /**
281
+ * Apply symmetry for a predicate
282
+ */
283
+ applySymmetry(triples, predicate, existingKeys) {
284
+ const inferred = [];
285
+ const edges = triples.filter(t => t.predicate === predicate);
286
+ for (const edge of edges) {
287
+ const inverse = {
288
+ subject: edge.object,
289
+ predicate: edge.predicate,
290
+ object: edge.subject,
291
+ };
292
+ const key = this.tripleKey(inverse);
293
+ if (!existingKeys.has(key)) {
294
+ existingKeys.add(key);
295
+ inferred.push(inverse);
296
+ }
297
+ }
298
+ return inferred;
299
+ }
300
+ /**
301
+ * Apply inverse property rule
302
+ */
303
+ applyInverse(triples, predicate1, predicate2, existingKeys) {
304
+ const inferred = [];
305
+ // P1(X, Y) => P2(Y, X)
306
+ for (const t of triples.filter(t => t.predicate === predicate1)) {
307
+ const inverse = {
308
+ subject: t.object,
309
+ predicate: predicate2,
310
+ object: t.subject,
311
+ };
312
+ const key = this.tripleKey(inverse);
313
+ if (!existingKeys.has(key)) {
314
+ existingKeys.add(key);
315
+ inferred.push(inverse);
316
+ }
317
+ }
318
+ // P2(X, Y) => P1(Y, X)
319
+ for (const t of triples.filter(t => t.predicate === predicate2)) {
320
+ const inverse = {
321
+ subject: t.object,
322
+ predicate: predicate1,
323
+ object: t.subject,
324
+ };
325
+ const key = this.tripleKey(inverse);
326
+ if (!existingKeys.has(key)) {
327
+ existingKeys.add(key);
328
+ inferred.push(inverse);
329
+ }
330
+ }
331
+ return inferred;
332
+ }
333
+ /**
334
+ * Get symmetric properties from triples
335
+ */
336
+ getSymmetricProperties(triples) {
337
+ return triples
338
+ .filter(t => t.predicate === RDF.type &&
339
+ t.object === OWL.SymmetricProperty)
340
+ .map(t => t.subject);
341
+ }
342
+ /**
343
+ * Get inverse property pairs from triples
344
+ */
345
+ getInverseProperties(triples) {
346
+ return triples
347
+ .filter(t => t.predicate === OWL.inverseOf)
348
+ .map(t => [t.subject, t.object]);
349
+ }
350
+ /**
351
+ * Match a rule against triples
352
+ */
353
+ matchRule(rule, triples) {
354
+ const matches = [];
355
+ // Only handle pattern-based rules here
356
+ const patternConditions = rule.conditions.filter(c => c.type === 'triple-pattern');
357
+ if (patternConditions.length === 0 || rule.actions.length === 0) {
358
+ return matches;
359
+ }
360
+ // For simplicity, handle single and dual pattern rules
361
+ if (patternConditions.length === 1) {
362
+ const pattern = patternConditions[0];
363
+ for (const triple of triples) {
364
+ const bindings = this.matchPattern(pattern, triple);
365
+ if (bindings) {
366
+ const inferredTriples = this.applyActions(rule.actions, bindings);
367
+ if (inferredTriples.length > 0) {
368
+ matches.push({
369
+ ruleId: rule.id,
370
+ bindings,
371
+ inferredTriples,
372
+ });
373
+ }
374
+ }
375
+ }
376
+ }
377
+ else if (patternConditions.length === 2) {
378
+ // Join two patterns
379
+ const [pattern1, pattern2] = patternConditions;
380
+ for (const t1 of triples) {
381
+ const bindings1 = this.matchPattern(pattern1, t1);
382
+ if (bindings1) {
383
+ for (const t2 of triples) {
384
+ const bindings2 = this.matchPattern(pattern2, t2);
385
+ if (bindings2 && this.compatibleBindings(bindings1, bindings2)) {
386
+ const merged = { ...bindings1, ...bindings2 };
387
+ const inferredTriples = this.applyActions(rule.actions, merged);
388
+ if (inferredTriples.length > 0) {
389
+ matches.push({
390
+ ruleId: rule.id,
391
+ bindings: merged,
392
+ inferredTriples,
393
+ });
394
+ }
395
+ }
396
+ }
397
+ }
398
+ }
399
+ }
400
+ return matches;
401
+ }
402
+ /**
403
+ * Match a pattern against a triple
404
+ */
405
+ matchPattern(pattern, triple) {
406
+ const bindings = {};
407
+ // Match subject
408
+ if (pattern.subject) {
409
+ if (typeof pattern.subject === 'string') {
410
+ if (pattern.subject !== triple.subject)
411
+ return null;
412
+ }
413
+ else {
414
+ bindings[pattern.subject.variable] = triple.subject;
415
+ }
416
+ }
417
+ // Match predicate
418
+ if (pattern.predicate) {
419
+ if (typeof pattern.predicate === 'string') {
420
+ if (pattern.predicate !== triple.predicate)
421
+ return null;
422
+ }
423
+ else {
424
+ bindings[pattern.predicate.variable] = triple.predicate;
425
+ }
426
+ }
427
+ // Match object
428
+ if (pattern.object) {
429
+ if (typeof pattern.object === 'string') {
430
+ if (pattern.object !== triple.object)
431
+ return null;
432
+ }
433
+ else {
434
+ bindings[pattern.object.variable] = triple.object;
435
+ }
436
+ }
437
+ return bindings;
438
+ }
439
+ /**
440
+ * Check if two binding sets are compatible
441
+ */
442
+ compatibleBindings(b1, b2) {
443
+ for (const key of Object.keys(b1)) {
444
+ if (key in b2 && b1[key] !== b2[key]) {
445
+ return false;
446
+ }
447
+ }
448
+ return true;
449
+ }
450
+ /**
451
+ * Apply actions with bindings
452
+ */
453
+ applyActions(actions, bindings) {
454
+ const result = [];
455
+ for (const action of actions) {
456
+ if (action.type === 'add-triple') {
457
+ const subject = typeof action.subject === 'string'
458
+ ? action.subject
459
+ : bindings[action.subject.variable];
460
+ const predicate = action.predicate;
461
+ const object = typeof action.object === 'string'
462
+ ? action.object
463
+ : bindings[action.object.variable];
464
+ if (subject && predicate && object) {
465
+ result.push({ subject, predicate, object });
466
+ }
467
+ }
468
+ }
469
+ return result;
470
+ }
471
+ /**
472
+ * Create unique key for triple
473
+ */
474
+ tripleKey(triple) {
475
+ return `${triple.subject}|${triple.predicate}|${triple.object}`;
476
+ }
477
+ }
478
+ //# sourceMappingURL=rule-engine.js.map