# SuperMemo SM-2 Algorithm Research ## The SM-2 Algorithm (Complete Technical Specification) Source: https://super-memory.com/english/ol/sm2.htm ### Per-Card State Variables Each card (flashcard item) tracks three values: - `n` — repetition number (count of successful reviews, starts at 0) - `EF` — easiness factor (starts at 2.5, minimum 1.3) - `I` — current interval in days (time until next review) ### Interval Schedule ``` I(1) = 1 # after first successful review: 1 day I(2) = 6 # after second successful review: 6 days I(n) = I(n-1) * EF # for n > 2: multiply previous interval by EF ``` Fractional intervals are rounded up to the nearest integer day. ### Quality Grades (0–5 scale) | Grade | Meaning | |-------|---------| | 5 | Perfect response — no hesitation | | 4 | Correct after hesitation | | 3 | Correct with serious difficulty | | 2 | Incorrect — correct answer seemed easy to recall after seeing it | | 1 | Incorrect — correct answer remembered after seeing it | | 0 | Complete blackout — no recollection | ### Easiness Factor Adjustment Formula After each review: ``` EF' = EF + (0.1 - (5 - q) * (0.08 + (5 - q) * 0.02)) ``` Where `q` is the quality grade (0–5). Results at each grade: - q=5: EF increases by +0.10 - q=4: EF unchanged (delta = 0) - q=3: EF decreases by -0.14 - q=2: EF decreases by -0.32 - q=1: EF decreases by -0.54 - q=0: EF decreases by -0.80 EF is clamped to minimum 1.3. Items with EF below 1.3 were found to be "annoyingly often repeated" and indicate a poorly-formed question. ### Reset Rule (Quality < 3) When a review scores 0, 1, or 2: - Reset repetition counter to n=1 (restart interval sequence: 1 day, then 6 days) - **Do NOT change the EF** (keep accumulated EF to influence future spacing) - Re-show the card the same session until it scores >= 4 ### Session Behavior Within a single study session: - All items scoring < 4 are re-shown in the same session - Session continues until all shown items score >= 4 - New intervals only schedule for the NEXT day's review (not within-session repetitions) --- ## Practical Implementation Notes ### Data Model Per Card ```typescript interface CardProgress { cardId: string; repetitionNumber: number; // n (0 = never studied) easinessFactor: number; // EF (default 2.5, min 1.3) intervalDays: number; // I (days until next review) nextReviewDate: string; // ISO date string lastReviewDate: string | null; totalReviews: number; correctReviews: number; } ``` ### Scheduling Logic ```typescript function scheduleNextReview(card: CardProgress, quality: number): CardProgress { let { n, EF, I } = card; if (quality < 3) { // Failed: reset sequence but keep EF n = 0; I = 1; } else { // Successful: advance sequence if (n === 0) I = 1; else if (n === 1) I = 6; else I = Math.ceil(I * EF); n += 1; } // Update EF (clamp to 1.3 minimum) EF = Math.max(1.3, EF + 0.1 - (5 - quality) * (0.08 + (5 - quality) * 0.02)); const nextDate = addDays(today(), I); return { ...card, n, EF, I, nextReviewDate: nextDate }; } ``` --- ## Cram Mode Cram mode ignores all SM-2 scheduling — it simply shows all cards in a subject (or selected subset) sequentially or randomly, without affecting the SM-2 state. Two approaches: ### Option A: Fully Isolated Cram - Cram sessions use a separate "cram_progress" table - SM-2 state for normal mode is untouched - Good for: pre-exam cramming without corrupting spacing data ### Option B: Cram Reads but Doesn't Write SM-2 - Cram shows cards from the full bank - Correct/incorrect tracked for session stats only - SM-2 nextReviewDate is not modified - Simpler implementation, recommended approach ### Recommended Cram Mode UX - Show cards in random order within a subject - Show question → user answers → reveal correct answer + explanation - Show session score at end (X/Y correct, per-subject breakdown) - No self-rating needed (just correct/incorrect tap) --- ## Multi-Subject / Multi-Deck Handling Each subject is a separate "deck" but SM-2 state is unified per-card. Recommended approach: ### Daily Review Queue - At app open: query all cards where `nextReviewDate <= today` - Group by subject for display - Allow "study all due" or "study due in [subject]" ### New Card Introduction - Introduce N new cards per day per subject (configurable, default: 5) - New cards have n=0 and no scheduled date - Introduce after reviewing due cards (or before — user preference) ### Statistics - Per-subject: total cards, due today, learned (n>=2), new - Overall retention rate (quality >= 3 / total reviews) - Streak tracking (days in a row with at least 1 review) --- ## Self-Assessment UX for SPL App Recommended: Use a simplified 3-button rating instead of the full 0-5 scale (less cognitive load for mobile): | Button | Label | Maps to SM-2 Grade | |--------|-------|--------------------| | Again | Didn't know it | 1 | | Hard | Knew it with difficulty | 3 | | Good | Knew it well | 4 | | Easy | Perfect recall | 5 | This is the same simplification Anki uses. The 4-button approach covers all meaningful SM-2 branches: - "Again" → reset (q=1) - "Hard" → decrease EF significantly (q=3) - "Good" → keep EF stable (q=4) - "Easy" → increase EF (q=5)