hirn-graph 0.1.0

Property graph, spreading activation, and Hebbian learning for hirn
Documentation
# hirn-graph

> **⚠️ Experimental:** This project is under active development. APIs, on-disk formats, and behaviour may change without notice. Not recommended for production use.

In-memory property graph engine for hirn — spreading activation, Hebbian learning, lateral inhibition, and personalized PageRank.

## Architecture

**Two-tier graph:**

- **Hot tier**`PropertyGraph` (petgraph `StableDiGraph`), all activation and traversal in-memory (~0.5ms)
- **Cold tier** — Lance `graph_nodes` + `graph_edges` datasets, write-through from hot tier

## Core Components

### PropertyGraph

Directed graph with typed edges and node metadata:

```rust
let mut graph = PropertyGraph::new();
let a = graph.add_node(node_a);
let b = graph.add_node(node_b);
graph.add_edge(a, b, EdgeRelation::RelatedTo, 0.8)?;
```

- **MAX_EDGES_PER_NODE** = 512 (lowest-weight eviction)
- **max_node_count** = 500,000 (least-accessed eviction via `access_count`)
- Bidirectional edges auto-reversed: `RelatedTo`, `SimilarTo`, `Contradicts`

### Spreading Activation

Constrained spreading activation over the property graph:

```rust
let results = spread_activation(&graph, &seed_nodes, &config)?;
```

Configurable: initial activation, decay factor, firing threshold, max iterations.

### Personalized PageRank (PPR)

Topic-biased PageRank for relevance scoring:

```rust
let scores = personalized_pagerank(&graph, &seed_nodes, damping, iterations)?;
```

### Hebbian Learning

"Neurons that fire together wire together" — co-retrieval strengthens edges:

```rust
let buffer = HebbianBuffer::new(config);
buffer.record_co_retrieval(id_a, id_b);
buffer.flush(&mut graph); // Updates edge weights
```

Lock-free `crossbeam::SegQueue` for concurrent co-retrieval recording.

### SYNAPSE Lateral Inhibition

Topical dissimilarity-based inhibition:

```
strength = μ × (1 - Jaccard_similarity(neighbors_j, neighbors_k))
```

Related nodes (similar neighborhoods) → weak inhibition. Competing nodes (different neighborhoods) → strong inhibition.

## Rich Causal Edges

`CausalEdge` with strength, confidence, evidence count, confounders, provenance, mechanism:

```rust
relevance_score = strength × confidence × ln(1 + evidence_count)
```

## Performance

- Zero-alloc iterators: `outgoing_weighted_iter()` yields `(NodeIndex, f32, &EdgeRelation)`
- Batch retrieval: `edges_for_nodes()` returns `HashMap<MemoryId, Vec<&GraphEdge>>`
- All operations sub-millisecond on hot tier