viva_glyph/association

Association - Hebbian learning for glyph-context mapping

VIVA learns which glyphs to “speak” in which situations through Hebbian association: “neurons that fire together wire together”

Theory

Based on Hebbian learning (Hebb, 1949) with Oja’s rule (Oja, 1982):

Oja’s Rule (DeepSeek R1 validated)

Δw = η × (x × y - w × y²)

This provides:

References

Types

Association between context and glyph

pub type Association {
  Association(
    context: Int,
    glyph: glyph.Glyph,
    strength: Float,
    fire_count: Int,
  )
}

Constructors

  • Association(
      context: Int,
      glyph: glyph.Glyph,
      strength: Float,
      fire_count: Int,
    )

    Arguments

    context

    Context identifier

    glyph

    Associated glyph

    strength

    Connection strength [0.0, 1.0]

    fire_count

    Number of times this association fired

Collection of learned associations

pub type AssociationMemory {
  AssociationMemory(
    associations: List(Association),
    learning_rate: Float,
    decay_rate: Float,
    prune_threshold: Float,
    learning_rule: LearningRule,
  )
}

Constructors

  • AssociationMemory(
      associations: List(Association),
      learning_rate: Float,
      decay_rate: Float,
      prune_threshold: Float,
      learning_rule: LearningRule,
    )

    Arguments

    associations

    All learned associations

    learning_rate

    Learning rate for strengthening

    decay_rate

    Decay rate per tick

    prune_threshold

    Minimum strength before pruning

    learning_rule

    Learning rule (Classic or Oja)

Learning rule selection

pub type LearningRule {
  ClassicHebbian
  OjaRule
}

Constructors

  • ClassicHebbian

    Classic Hebbian: Δw = η × (1 - w)

  • OjaRule

    Oja’s rule: Δw = η × (x × y - w × y²) - more stable

Values

pub fn contexts_for_glyph(
  memory: AssociationMemory,
  glyph: glyph.Glyph,
) -> List(Association)

Get associations for specific glyph (reverse lookup)

pub fn decay(assoc: Association, rate: Float) -> Association

Weaken an association (decay)

pub fn learn(
  memory: AssociationMemory,
  context: Int,
  glyph: glyph.Glyph,
) -> AssociationMemory

Learn: reinforce context-glyph association using configured rule

pub fn memory_with_config(
  learning_rate: Float,
  decay_rate: Float,
  prune_threshold: Float,
) -> AssociationMemory

Create association memory with custom config

pub fn memory_with_rule(
  learning_rate: Float,
  decay_rate: Float,
  prune_threshold: Float,
  rule: LearningRule,
) -> AssociationMemory

Create memory with specific learning rule

pub fn new_association(
  context: Int,
  glyph: glyph.Glyph,
) -> Association

Create new association

pub fn new_memory() -> AssociationMemory

Create empty association memory with default config (Oja’s rule)

pub fn recall(
  memory: AssociationMemory,
  context: Int,
) -> option.Option(glyph.Glyph)

Find best glyph for context (winner-takes-all)

pub fn recall_all(
  memory: AssociationMemory,
  context: Int,
) -> List(Association)

Find all glyphs for context, sorted by strength

pub fn size(memory: AssociationMemory) -> Int

Get total number of associations

pub fn strengthen(assoc: Association, rate: Float) -> Association

Strengthen an association (Classic Hebbian) Δw = η × (1 - w) - asymptotes to 1.0

pub fn strengthen_oja(
  assoc: Association,
  rate: Float,
) -> Association

Strengthen using Oja’s rule (more stable) Δw = η × (x × y - w × y²) For binary activation (x=1, y=1): Δw = η × (1 - w) This provides automatic normalization and competitive learning

pub fn strongest(
  memory: AssociationMemory,
  n: Int,
) -> List(Association)

Get strongest associations across all contexts

pub fn tick(memory: AssociationMemory) -> AssociationMemory

Tick: apply decay to all associations and prune weak ones

Search Document