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 tierPropertyGraph (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:

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:

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:

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

Hebbian Learning

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

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:

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