A prototype adaptive cognitive reinforcement system. The system builds a personal knowledge graph of a patient's autobiographical memories i.e family, places, life events and uses that graph to decide what to reinforce and when.
ReMind treats memory as a network, not a list. People, places, and events are connected — remembering your daughter activates your memory of home, which activates the wedding anniversary. That structure matters for what to reinforce and in what order.
Every patient has a PatientMemoryGraph — an in-memory knowledge graph where nodes are autobiographical memory items:
Node types: person | place | event | fact
Example nodes:
"Wife Margaret" (person, strength=0.92)
"Family Home" (place, strength=0.80)
"Wedding Anniversary" (event, strength=0.70)
"Penicillin Allergy" (fact, strength=0.30)
Edges encode relationships with a semantic weight:
Wife Margaret --lives_at--> Family Home (weight=0.9)
Wife Margaret --celebrated--> Wedding Anniversary (weight=0.85)
Daughter Sarah --attended--> Wedding Anniversary (weight=0.7)
Each node has a strength (0–1) and stability value. Strength decays over time using the Ebbinghaus forgetting curve:
R(t) = exp( -t / (stability × 24h) )
On correct recall, stability doubles (the memory consolidates, needs review less often). On incorrect recall, stability halves (needs more frequent reinforcement).
This is the same math behind Anki/SuperMemo, applied to autobiographical memories instead of flashcards.
The interesting part: when you recall a node correctly, neighboring nodes get a small strength boost (20% × edge weight). When you fail, neighbors get a small decay (30% × edge weight).
So successfully remembering "Wife Margaret" also slightly reinforces "Family Home", "Wedding Anniversary", and "Daughter Sarah". The whole connected subgraph moves together, which is closer to how human associative memory actually works.
Before each question, every candidate node gets scored:
score = forgetting_prob × recency_penalty × engagement_factor × graph_centrality
- forgetting_prob —
1 - strength. How much has this faded? - recency_penalty — avoids re-asking something shown 10 minutes ago
- engagement_factor — uses patient's historical engagement, adjusted by whether the node's complexity matches the current difficulty level
- graph_centrality — high-degree nodes (like "Wife Margaret") score higher because reinforcing them ripples through more of the graph
No neural network, no training. Just a scoring formula the system uses every time it needs to pick the next task.
Difficulty runs on a 1–5 scale. After every session, the system looks at the last 3 sessions' accuracy:
- Mean accuracy > 75% → level goes up
- Mean accuracy < 45% → level goes down
Each level controls max hints, time limits, and minimum node strength thresholds.
Hints are not just a fallback — they're proactively enabled when:
hint_dependency = (1 - node.strength) + (fatigue × 0.5) > 0.6
If the patient is tired and the memory is weak, hints fire before the first attempt rather than after failure. Three hint levels escalate from vague to concrete:
"This is a person in your life""Their name starts with 'M'""Think about 'Family Home' — they live there"
The system never penalizes wrong answers. Failure just lowers the node's stability so it gets reviewed sooner.
python3 -m remind.simulationThe demo builds a patient called Robert (74, mild dementia) with 12 autobiographical memory nodes that have been artificially decayed to simulate 0.5–7 days of elapsed time. It then runs 5 therapy sessions.
What you'll see:
- Sessions 1–2: heavy hint usage, low accuracy (memories have decayed significantly)
- Session 3 onward: accuracy climbs, hints drop off, difficulty begins to adapt
- Final graph state: stability scores show which memories have consolidated
The FakePatientResponder simulates recall probability as:
P(correct) = node.strength × (1 - fatigue × 0.4) + noiseTo see internal scoring details (forgetting probabilities, centrality values per node), change the logging level in simulation.py:
logging.basicConfig(level=logging.DEBUG, ...)remind/
models.py dataclasses: MemoryNode, MemoryEdge, GameSession, PatientState
graph.py PatientMemoryGraph — adjacency list, decay/boost propagation
forgetting.py EbbinghausModel, DecayScheduler
scoring.py TaskScorer — the 4-factor selection formula
difficulty.py DifficultyManager — sliding window over session accuracy
hints.py HintStrategy — dependency scoring + 3-level hint generation
engine.py SessionEngine — ties everything together
simulation.py Demo loop + FakePatientResponder + build_demo_graph()
The system sits at the intersection of three things:
- Spaced repetition (Ebbinghaus, SM-2) — schedule reviews before forgetting happens
- Knowledge graphs — model autobiographical memory as a structured network, not a flat list
- Reinforcement learning — frame task selection as an optimization problem over patient state
Most spaced repetition systems treat items as independent. Most RL systems optimize for generic recall. This system optimizes for autobiographical identity preservation