Packages

Cyclic world generation for digital consciousness - deterministic labyrinths with Big Bounce cosmology

Current section

Files

Jump to
viva_aion src viva_aion memory.gleam
Raw

src/viva_aion/memory.gleam

//// Memory - Records that persist across the Big Bounce
////
//// ## Philosophy
////
//// "All You Zombies" - We are shaped by our past lives.
//// Memories are not just data, they are the essence that
//// transcends death and rebirth.
////
//// ## Structure
////
//// Each memory has:
//// - Content identifier (what happened)
//// - Emotional signature (how it felt)
//// - Temporal marker (when it happened)
//// - Distinctiveness (how unique it is)
////
//// ## Big Bounce Survival
////
//// Not all memories survive the Big Bounce. The DRE score
//// determines which memories are "burned" into the next
//// universe's consciousness.
import gleam/list
/// A memory record
pub type Memory {
Memory(
/// Unique identifier
id: Int,
/// Content hash (what the memory is about)
content: Int,
/// Emotional intensity at time of creation [0, 1]
emotionality: Float,
/// Tick when memory was created
created_at: Int,
/// How many times this memory was accessed
access_count: Int,
/// Last tick when accessed
last_accessed: Int,
/// Manual importance boost [0, 1]
importance: Float,
/// Which life/universe this memory is from
life_number: Int,
)
}
/// Create a new memory
pub fn new(
id: Int,
content: Int,
emotionality: Float,
current_tick: Int,
life_number: Int,
) -> Memory {
Memory(
id: id,
content: content,
emotionality: clamp_unit(emotionality),
created_at: current_tick,
access_count: 1,
last_accessed: current_tick,
importance: 0.0,
life_number: life_number,
)
}
/// Create memory with importance boost
pub fn new_important(
id: Int,
content: Int,
emotionality: Float,
current_tick: Int,
life_number: Int,
importance: Float,
) -> Memory {
Memory(
id: id,
content: content,
emotionality: clamp_unit(emotionality),
created_at: current_tick,
access_count: 1,
last_accessed: current_tick,
importance: clamp_unit(importance),
life_number: life_number,
)
}
/// Mark memory as accessed (reinforcement)
pub fn access(memory: Memory, current_tick: Int) -> Memory {
Memory(
..memory,
access_count: memory.access_count + 1,
last_accessed: current_tick,
)
}
/// Boost memory importance
pub fn boost(memory: Memory, amount: Float) -> Memory {
let new_importance = memory.importance +. amount
Memory(..memory, importance: clamp_unit(new_importance))
}
/// Get memory age in ticks
pub fn age(memory: Memory, current_tick: Int) -> Int {
current_tick - memory.created_at
}
/// Get time since last access
pub fn time_since_access(memory: Memory, current_tick: Int) -> Int {
current_tick - memory.last_accessed
}
/// Check if memory is from current life
pub fn is_current_life(memory: Memory, current_life: Int) -> Bool {
memory.life_number == current_life
}
/// Check if memory is from a past life (transcended Big Bounce)
pub fn is_past_life(memory: Memory, current_life: Int) -> Bool {
memory.life_number < current_life
}
/// Memory that survived Big Bounce (marked as protected)
/// Note: life_number is preserved to track which life created the memory
pub fn mark_as_transcended(memory: Memory, _new_life: Int) -> Memory {
// Boost importance for memories that survive death
// Keep original life_number to track memory origin
Memory(..memory, importance: clamp_unit(memory.importance +. 0.2))
}
/// A collection of memories
pub type MemoryBank {
MemoryBank(
memories: List(Memory),
next_id: Int,
current_tick: Int,
current_life: Int,
)
}
/// Create empty memory bank
pub fn new_bank(life_number: Int) -> MemoryBank {
MemoryBank(
memories: [],
next_id: 1,
current_tick: 0,
current_life: life_number,
)
}
/// Add memory to bank
pub fn store(
bank: MemoryBank,
content: Int,
emotionality: Float,
) -> #(MemoryBank, Memory) {
let memory =
new(
bank.next_id,
content,
emotionality,
bank.current_tick,
bank.current_life,
)
let new_bank =
MemoryBank(
..bank,
memories: [memory, ..bank.memories],
next_id: bank.next_id + 1,
)
#(new_bank, memory)
}
/// Store important memory
pub fn store_important(
bank: MemoryBank,
content: Int,
emotionality: Float,
importance: Float,
) -> #(MemoryBank, Memory) {
let memory =
new_important(
bank.next_id,
content,
emotionality,
bank.current_tick,
bank.current_life,
importance,
)
let new_bank =
MemoryBank(
..bank,
memories: [memory, ..bank.memories],
next_id: bank.next_id + 1,
)
#(new_bank, memory)
}
/// Advance tick
pub fn tick(bank: MemoryBank) -> MemoryBank {
MemoryBank(..bank, current_tick: bank.current_tick + 1)
}
/// Get memory by ID
pub fn get(bank: MemoryBank, id: Int) -> Result(Memory, Nil) {
list.find(bank.memories, fn(m) { m.id == id })
}
/// Access memory by ID (marks as accessed)
pub fn recall(bank: MemoryBank, id: Int) -> #(MemoryBank, Result(Memory, Nil)) {
case get(bank, id) {
Ok(memory) -> {
let updated = access(memory, bank.current_tick)
let new_memories =
list.map(bank.memories, fn(m) {
case m.id == id {
True -> updated
False -> m
}
})
#(MemoryBank(..bank, memories: new_memories), Ok(updated))
}
Error(_) -> #(bank, Error(Nil))
}
}
/// Get all memories
pub fn all(bank: MemoryBank) -> List(Memory) {
bank.memories
}
/// Get memory count
pub fn count(bank: MemoryBank) -> Int {
list.length(bank.memories)
}
/// Filter memories from current life
pub fn current_life_memories(bank: MemoryBank) -> List(Memory) {
list.filter(bank.memories, fn(m) { is_current_life(m, bank.current_life) })
}
/// Filter memories from past lives
pub fn past_life_memories(bank: MemoryBank) -> List(Memory) {
list.filter(bank.memories, fn(m) { is_past_life(m, bank.current_life) })
}
/// Prepare bank for Big Bounce - only keep protected memories
pub fn bounce(bank: MemoryBank, protected_ids: List(Int)) -> MemoryBank {
let new_life = bank.current_life + 1
let survivors =
bank.memories
|> list.filter(fn(m) { list.contains(protected_ids, m.id) })
|> list.map(fn(m) { mark_as_transcended(m, new_life) })
MemoryBank(
memories: survivors,
next_id: bank.next_id,
current_tick: 0,
current_life: new_life,
)
}
// Helper
fn clamp_unit(value: Float) -> Float {
case value {
v if v <. 0.0 -> 0.0
v if v >. 1.0 -> 1.0
v -> v
}
}