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(petgraphStableDiGraph), all activation and traversal in-memory (~0.5ms) - Cold tier — Lance
graph_nodes+graph_edgesdatasets, write-through from hot tier
Core Components
PropertyGraph
Directed graph with typed edges and node metadata:
let mut graph = new;
let a = graph.add_node;
let b = graph.add_node;
graph.add_edge?;
- 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:
let results = spread_activation?;
Configurable: initial activation, decay factor, firing threshold, max iterations.
Personalized PageRank (PPR)
Topic-biased PageRank for relevance scoring:
let scores = personalized_pagerank?;
Hebbian Learning
"Neurons that fire together wire together" — co-retrieval strengthens edges:
let buffer = new;
buffer.record_co_retrieval;
buffer.flush; // 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:
relevance_score = strength × confidence × ln
Performance
- Zero-alloc iterators:
outgoing_weighted_iter()yields(NodeIndex, f32, &EdgeRelation) - Batch retrieval:
edges_for_nodes()returnsHashMap<MemoryId, Vec<&GraphEdge>> - All operations sub-millisecond on hot tier