# BMSSP API Integration Strategy
## ๐ Integration Architecture
### Current Sublinear Solver Architecture
```
src/
โโโ core/
โ โโโ solver.ts # SublinearSolver class
โ โโโ matrix.ts # MatrixOperations
โ โโโ types.ts # Core interfaces
โ โโโ utils.ts # VectorOperations, utilities
โโโ mcp/tools/
โ โโโ solver.ts # MCP solver tools
โ โโโ graph.ts # GraphTools for PageRank/centrality
โ โโโ matrix.ts # Matrix analysis tools
โโโ index.ts # Main exports
```
### BMSSP Integration Points
```typescript
// @ruvnet/bmssp exports
import {
WasmGraph, // Basic graph pathfinding
WasmNeuralBMSSP, // Neural/semantic pathfinding
InitOutput // WASM initialization
} from '@ruvnet/bmssp';
```
## ๐ Core Integration Strategy
### 1. BMSSP Wrapper Class
**File**: `src/core/bmssp-wrapper.ts`
```typescript
import { WasmGraph, WasmNeuralBMSSP } from '@ruvnet/bmssp';
import { Matrix, Vector, SolverError, ErrorCodes } from './types.js';
export class BMSSPWrapper {
private wasmGraph?: WasmGraph;
private neuralBMSSP?: WasmNeuralBMSSP;
private isInitialized = false;
constructor(
private vertices: number,
private enableNeural = false,
private embeddingDim = 128
) {}
async initialize(): Promise<void> {
try {
// Initialize basic graph
this.wasmGraph = new WasmGraph(this.vertices, true);
// Initialize neural BMSSP if enabled
if (this.enableNeural) {
this.neuralBMSSP = new WasmNeuralBMSSP(this.vertices, this.embeddingDim);
}
this.isInitialized = true;
} catch (error) {
throw new SolverError(
`Failed to initialize BMSSP: ${error}`,
ErrorCodes.INVALID_PARAMETERS
);
}
}
addEdge(from: number, to: number, weight: number): boolean {
this.ensureInitialized();
return this.wasmGraph!.add_edge(from, to, weight);
}
computeShortestPaths(source: number): Float64Array {
this.ensureInitialized();
return this.wasmGraph!.compute_shortest_paths(source);
}
// Neural methods
setEmbedding(node: number, embedding: Float64Array): boolean {
if (!this.neuralBMSSP) {
throw new SolverError('Neural BMSSP not initialized', ErrorCodes.INVALID_PARAMETERS);
}
return this.neuralBMSSP.set_embedding(node, embedding);
}
addSemanticEdge(from: number, to: number, alpha: number): void {
if (!this.neuralBMSSP) {
throw new SolverError('Neural BMSSP not initialized', ErrorCodes.INVALID_PARAMETERS);
}
this.neuralBMSSP.add_semantic_edge(from, to, alpha);
}
computeNeuralPaths(source: number): Float64Array {
if (!this.neuralBMSSP) {
throw new SolverError('Neural BMSSP not initialized', ErrorCodes.INVALID_PARAMETERS);
}
return this.neuralBMSSP.compute_neural_paths(source);
}
semanticDistance(node1: number, node2: number): number {
if (!this.neuralBMSSP) {
throw new SolverError('Neural BMSSP not initialized', ErrorCodes.INVALID_PARAMETERS);
}
return this.neuralBMSSP.semantic_distance(node1, node2);
}
updateEmbeddings(gradients: Float64Array, learningRate: number): boolean {
if (!this.neuralBMSSP) {
throw new SolverError('Neural BMSSP not initialized', ErrorCodes.INVALID_PARAMETERS);
}
return this.neuralBMSSP.update_embeddings(
gradients,
learningRate,
this.embeddingDim
);
}
cleanup(): void {
if (this.wasmGraph) {
this.wasmGraph.free();
this.wasmGraph = undefined;
}
if (this.neuralBMSSP) {
this.neuralBMSSP.free();
this.neuralBMSSP = undefined;
}
this.isInitialized = false;
}
get vertexCount(): number {
return this.wasmGraph?.vertex_count ?? 0;
}
get edgeCount(): number {
return this.wasmGraph?.edge_count ?? 0;
}
private ensureInitialized(): void {
if (!this.isInitialized || !this.wasmGraph) {
throw new SolverError('BMSSP not initialized', ErrorCodes.INVALID_PARAMETERS);
}
}
}
```
### 2. Matrix to Graph Bridge
**File**: `src/core/bmssp-bridge.ts`
```typescript
import { Matrix, Vector } from './types.js';
import { MatrixOperations } from './matrix.js';
import { BMSSPWrapper } from './bmssp-wrapper.js';
export class BMSSPBridge {
/**
* Convert adjacency matrix to BMSSP graph
*/
static async createGraphFromMatrix(
adjacency: Matrix,
enableNeural = false,
embeddingDim = 128
): Promise<BMSSPWrapper> {
MatrixOperations.validateMatrix(adjacency);
if (adjacency.rows !== adjacency.cols) {
throw new Error('Adjacency matrix must be square');
}
const graph = new BMSSPWrapper(adjacency.rows, enableNeural, embeddingDim);
await graph.initialize();
// Add edges from matrix
for (let i = 0; i < adjacency.rows; i++) {
for (let j = 0; j < adjacency.cols; j++) {
const weight = MatrixOperations.getEntry(adjacency, i, j);
if (weight !== 0) {
graph.addEdge(i, j, weight);
}
}
}
return graph;
}
/**
* Convert Laplacian matrix to graph (for effective resistance)
*/
static async createGraphFromLaplacian(laplacian: Matrix): Promise<BMSSPWrapper> {
// Convert Laplacian to adjacency: A = D - L
const adjacency = this.laplacianToAdjacency(laplacian);
return this.createGraphFromMatrix(adjacency);
}
/**
* Extract adjacency matrix from Laplacian
*/
private static laplacianToAdjacency(laplacian: Matrix): Matrix {
const n = laplacian.rows;
if (laplacian.format === 'dense') {
const data: number[][] = Array(n).fill(null).map(() => Array(n).fill(0));
for (let i = 0; i < n; i++) {
const diagonal = MatrixOperations.getEntry(laplacian, i, i);
for (let j = 0; j < n; j++) {
if (i !== j) {
data[i][j] = -MatrixOperations.getEntry(laplacian, i, j);
}
}
}
return { rows: n, cols: n, data, format: 'dense' };
} else {
// Handle sparse format
const values: number[] = [];
const rowIndices: number[] = [];
const colIndices: number[] = [];
const sparse = laplacian as any;
for (let k = 0; k < sparse.values.length; k++) {
const i = sparse.rowIndices[k];
const j = sparse.colIndices[k];
if (i !== j) {
values.push(-sparse.values[k]);
rowIndices.push(i);
colIndices.push(j);
}
}
return {
rows: n,
cols: n,
values,
rowIndices,
colIndices,
format: 'coo'
};
}
}
/**
* Set node embeddings for neural pathfinding
*/
static async setNodeEmbeddings(
graph: BMSSPWrapper,
embeddings: Float64Array[],
embeddingDim: number
): Promise<void> {
for (let i = 0; i < embeddings.length; i++) {
if (embeddings[i].length !== embeddingDim) {
throw new Error(`Embedding ${i} has wrong dimension: ${embeddings[i].length} vs ${embeddingDim}`);
}
graph.setEmbedding(i, embeddings[i]);
}
}
/**
* Convert BMSSP distances back to vector format
*/
static distancesToVector(distances: Float64Array): Vector {
return Array.from(distances);
}
}
```
### 3. Hybrid Solver Integration
**File**: `src/core/hybrid-solver.ts`
```typescript
import { SublinearSolver } from './solver.js';
import { BMSSPWrapper } from './bmssp-wrapper.js';
import { BMSSPBridge } from './bmssp-bridge.js';
import {
Matrix,
Vector,
SolverConfig,
SolverResult,
PageRankConfig,
SolverError,
ErrorCodes
} from './types.js';
interface HybridConfig extends SolverConfig {
useBMSSP?: boolean;
bmsspThreshold?: {
minGraphSize: number;
minSparsity: number;
multiSourceMin: number;
};
enableNeural?: boolean;
}
export class HybridSolver extends SublinearSolver {
private bmsspGraph?: BMSSPWrapper;
constructor(private hybridConfig: HybridConfig) {
super(hybridConfig);
}
/**
* Enhanced PageRank using BMSSP when beneficial
*/
async computePageRank(adjacency: Matrix, config: PageRankConfig): Promise<Vector> {
const shouldUseBMSSP = this.shouldUseBMSSP(adjacency, 'pagerank');
if (shouldUseBMSSP) {
return this.computePageRankBMSSP(adjacency, config);
} else {
return super.computePageRank(adjacency, config);
}
}
/**
* Multi-source shortest paths using BMSSP
*/
async multiSourceShortestPaths(
adjacency: Matrix,
sources: number[],
targets?: number[]
): Promise<{
distances: Map<number, Vector>;
paths: Map<number, number[][]>;
computeTime: number;
}> {
const startTime = performance.now();
this.bmsspGraph = await BMSSPBridge.createGraphFromMatrix(adjacency);
const distances = new Map<number, Vector>();
const paths = new Map<number, number[][]>();
try {
for (const source of sources) {
const sourceDistances = this.bmsspGraph.computeShortestPaths(source);
distances.set(source, BMSSPBridge.distancesToVector(sourceDistances));
// Reconstruct paths (simplified - BMSSP focuses on distances)
const sourcePaths: number[][] = [];
if (targets) {
for (const target of targets) {
sourcePaths.push(this.reconstructPath(adjacency, source, target, sourceDistances));
}
}
paths.set(source, sourcePaths);
}
return {
distances,
paths,
computeTime: performance.now() - startTime
};
} finally {
this.bmsspGraph.cleanup();
this.bmsspGraph = undefined;
}
}
/**
* Semantic pathfinding using Neural BMSSP
*/
async semanticPathfinding(
adjacency: Matrix,
embeddings: Float64Array[],
source: number,
target: number,
alpha: number = 0.5
): Promise<{
distance: number;
semanticDistance: number;
path: number[];
computeTime: number;
}> {
const startTime = performance.now();
this.bmsspGraph = await BMSSPBridge.createGraphFromMatrix(
adjacency,
true, // Enable neural
embeddings[0].length
);
try {
// Set embeddings
await BMSSPBridge.setNodeEmbeddings(
this.bmsspGraph,
embeddings,
embeddings[0].length
);
// Add semantic edges
for (let i = 0; i < adjacency.rows; i++) {
for (let j = 0; j < adjacency.cols; j++) {
if (i !== j) {
this.bmsspGraph.addSemanticEdge(i, j, alpha);
}
}
}
// Compute neural paths
const neuralDistances = this.bmsspGraph.computeNeuralPaths(source);
const semanticDist = this.bmsspGraph.semanticDistance(source, target);
// Reconstruct semantic path (simplified)
const path = this.reconstructSemanticPath(source, target, neuralDistances);
return {
distance: neuralDistances[target],
semanticDistance: semanticDist,
path,
computeTime: performance.now() - startTime
};
} finally {
this.bmsspGraph.cleanup();
this.bmsspGraph = undefined;
}
}
/**
* Decide whether to use BMSSP based on problem characteristics
*/
private shouldUseBMSSP(matrix: Matrix, operation: string): boolean {
if (!this.hybridConfig.useBMSSP) return false;
const threshold = this.hybridConfig.bmsspThreshold || {
minGraphSize: 1000,
minSparsity: 0.9,
multiSourceMin: 2
};
const size = matrix.rows;
const sparsity = this.calculateSparsity(matrix);
// Size threshold
if (size < threshold.minGraphSize) return false;
// Sparsity threshold (BMSSP excels with sparse graphs)
if (sparsity < threshold.minSparsity) return false;
// Operation-specific logic
switch (operation) {
case 'pagerank':
return size > 5000; // BMSSP beneficial for large PageRank
case 'shortest-path':
return true; // BMSSP always good for shortest paths
case 'multi-source':
return true; // BMSSP designed for multi-source
default:
return false;
}
}
private calculateSparsity(matrix: Matrix): number {
let nonZeros = 0;
const total = matrix.rows * matrix.cols;
if (matrix.format === 'dense') {
const dense = matrix as any;
for (let i = 0; i < matrix.rows; i++) {
for (let j = 0; j < matrix.cols; j++) {
if (dense.data[i][j] !== 0) nonZeros++;
}
}
} else {
const sparse = matrix as any;
nonZeros = sparse.values.length;
}
return 1 - (nonZeros / total);
}
private async computePageRankBMSSP(adjacency: Matrix, config: PageRankConfig): Promise<Vector> {
// Convert PageRank to shortest path problem for BMSSP
// This is a simplified approach - full implementation would be more complex
this.bmsspGraph = await BMSSPBridge.createGraphFromMatrix(adjacency);
try {
const n = adjacency.rows;
const pagerank = new Array(n).fill(0);
// Compute influence from each node (simplified)
for (let i = 0; i < n; i++) {
const distances = this.bmsspGraph.computeShortestPaths(i);
const influence = this.computeInfluence(distances, config.damping);
pagerank[i] = influence;
}
// Normalize
const sum = pagerank.reduce((a, b) => a + b, 0);
return pagerank.map(p => p / sum);
} finally {
this.bmsspGraph.cleanup();
this.bmsspGraph = undefined;
}
}
private computeInfluence(distances: Float64Array, damping: number): number {
// Convert distances to influence scores
let influence = 0;
for (let i = 0; i < distances.length; i++) {
if (distances[i] < Infinity) {
influence += damping / (1 + distances[i]);
}
}
return influence;
}
private reconstructPath(
adjacency: Matrix,
source: number,
target: number,
distances: Float64Array
): number[] {
// Simple path reconstruction (breadth-first approach)
const path: number[] = [];
let current = target;
while (current !== source) {
path.unshift(current);
// Find predecessor with minimum distance
let minDist = Infinity;
let predecessor = -1;
for (let i = 0; i < adjacency.rows; i++) {
if (MatrixOperations.getEntry(adjacency, i, current) > 0) {
if (distances[i] < minDist) {
minDist = distances[i];
predecessor = i;
}
}
}
if (predecessor === -1) break;
current = predecessor;
}
path.unshift(source);
return path;
}
private reconstructSemanticPath(
source: number,
target: number,
neuralDistances: Float64Array
): number[] {
// Simplified semantic path reconstruction
// In practice, would use more sophisticated neural pathfinding
const path: number[] = [source];
let current = source;
const visited = new Set([source]);
while (current !== target && path.length < neuralDistances.length) {
let nextNode = -1;
let minDist = Infinity;
for (let i = 0; i < neuralDistances.length; i++) {
if (!visited.has(i) && neuralDistances[i] < minDist) {
minDist = neuralDistances[i];
nextNode = i;
}
}
if (nextNode === -1) break;
path.push(nextNode);
visited.add(nextNode);
current = nextNode;
}
return path;
}
override async cleanup(): Promise<void> {
if (this.bmsspGraph) {
this.bmsspGraph.cleanup();
this.bmsspGraph = undefined;
}
}
}
```
## ๐ง MCP Tools Integration
### Enhanced Graph Tools
**File**: `src/mcp/tools/bmssp-tools.ts`
```typescript
import { HybridSolver } from '../../core/hybrid-solver.js';
import { BMSSPBridge } from '../../core/bmssp-bridge.js';
import { Matrix, Vector, SolverError, ErrorCodes } from '../../core/types.js';
export class BMSSPTools {
/**
* Ultra-fast shortest path using BMSSP WASM
*/
static async shortestPath(params: {
adjacency: Matrix;
source: number;
target: number;
method?: 'bmssp' | 'hybrid';
}) {
const graph = await BMSSPBridge.createGraphFromMatrix(params.adjacency);
try {
const distances = graph.computeShortestPaths(params.source);
const distance = distances[params.target];
return {
distance,
source: params.source,
target: params.target,
algorithm: 'bmssp-wasm',
performance: {
vertices: graph.vertexCount,
edges: graph.edgeCount,
complexity: 'O(mยทlog^(2/3) n)'
}
};
} finally {
graph.cleanup();
}
}
/**
* Multi-source PageRank using BMSSP
*/
static async multiSourcePageRank(params: {
adjacency: Matrix;
sources: number[];
damping?: number;
epsilon?: number;
maxIterations?: number;
}) {
const config = {
method: 'neumann' as const,
epsilon: params.epsilon || 1e-6,
maxIterations: params.maxIterations || 1000,
useBMSSP: true,
bmsspThreshold: {
minGraphSize: 100,
minSparsity: 0.7,
multiSourceMin: 2
}
};
const solver = new HybridSolver(config);
const pageRankConfig = {
damping: params.damping || 0.85,
epsilon: params.epsilon || 1e-6,
maxIterations: params.maxIterations || 1000
};
try {
const result = await solver.multiSourceShortestPaths(
params.adjacency,
params.sources
);
return {
sources: params.sources,
distances: Object.fromEntries(result.distances),
computeTime: result.computeTime,
algorithm: 'bmssp-multi-source',
statistics: {
totalSources: params.sources.length,
averageDistance: this.calculateAverageDistance(result.distances),
performance: result.computeTime
}
};
} finally {
await solver.cleanup();
}
}
/**
* Semantic pathfinding with neural BMSSP
*/
static async semanticPathfinding(params: {
adjacency: Matrix;
embeddings: Float64Array[];
source: number;
target: number;
alpha?: number;
embeddingDim?: number;
}) {
const config = {
method: 'neumann' as const,
epsilon: 1e-6,
maxIterations: 1000,
useBMSSP: true,
enableNeural: true
};
const solver = new HybridSolver(config);
try {
const result = await solver.semanticPathfinding(
params.adjacency,
params.embeddings,
params.source,
params.target,
params.alpha || 0.5
);
return {
...result,
algorithm: 'neural-bmssp',
semantics: {
embeddingDim: params.embeddings[0].length,
alpha: params.alpha || 0.5,
semanticSimilarity: 1 / (1 + result.semanticDistance)
}
};
} finally {
await solver.cleanup();
}
}
/**
* Batch shortest paths computation
*/
static async batchShortestPaths(params: {
adjacency: Matrix;
queries: Array<{ source: number; target: number }>;
}) {
const graph = await BMSSPBridge.createGraphFromMatrix(params.adjacency);
const results: Array<{
source: number;
target: number;
distance: number;
}> = [];
try {
// Group queries by source for efficiency
const sourceGroups = new Map<number, number[]>();
for (const query of params.queries) {
if (!sourceGroups.has(query.source)) {
sourceGroups.set(query.source, []);
}
sourceGroups.get(query.source)!.push(query.target);
}
// Compute distances for each source group
for (const [source, targets] of sourceGroups) {
const distances = graph.computeShortestPaths(source);
for (const target of targets) {
results.push({
source,
target,
distance: distances[target]
});
}
}
return {
results,
statistics: {
totalQueries: params.queries.length,
uniqueSources: sourceGroups.size,
algorithm: 'bmssp-batch',
performance: {
vertices: graph.vertexCount,
edges: graph.edgeCount
}
}
};
} finally {
graph.cleanup();
}
}
private static calculateAverageDistance(distances: Map<number, Vector>): number {
let total = 0;
let count = 0;
for (const distanceVector of distances.values()) {
for (const distance of distanceVector) {
if (distance < Infinity) {
total += distance;
count++;
}
}
}
return count > 0 ? total / count : 0;
}
}
```
## ๐ Performance Monitoring
**File**: `src/core/bmssp-benchmarks.ts`
```typescript
export class BMSSPBenchmarks {
static async comparePerformance(
adjacency: Matrix,
testCases: Array<{
method: 'traditional' | 'bmssp' | 'hybrid';
operation: 'shortest-path' | 'pagerank' | 'multi-source';
params: any;
}>
) {
const results = [];
for (const testCase of testCases) {
const startTime = performance.now();
const startMemory = process.memoryUsage().heapUsed;
let result;
switch (testCase.method) {
case 'traditional':
result = await this.runTraditional(adjacency, testCase);
break;
case 'bmssp':
result = await this.runBMSSP(adjacency, testCase);
break;
case 'hybrid':
result = await this.runHybrid(adjacency, testCase);
break;
}
const endTime = performance.now();
const endMemory = process.memoryUsage().heapUsed;
results.push({
method: testCase.method,
operation: testCase.operation,
executionTime: endTime - startTime,
memoryUsed: endMemory - startMemory,
result
});
}
return this.analyzeResults(results);
}
private static analyzeResults(results: any[]) {
// Group by operation and compare methods
const analysis = {
performanceGains: {},
memoryEfficiency: {},
recommendations: []
};
// Implementation details...
return analysis;
}
}
```
This API integration strategy provides a comprehensive approach to incorporating BMSSP's high-performance graph algorithms while maintaining compatibility with existing sublinear solver functionality.