# Fitts Memory Scheduler
A sophisticated memory card review scheduler that applies **Fitts' Law** to optimize spaced repetition learning. This library provides an intelligent card ordering system based on user response patterns and cognitive difficulty prediction.
## What is Fitts Memory Scheduler?
This library implements a **memory card review scheduler** that uses Fitts' Law principles to:
1. **Predict Response Times**: Estimates cognitive difficulty based on memory strength and accessibility
2. **Classify Card Difficulty**: Automatically categorizes cards from VeryEasy to VeryHard
3. **Optimize Review Order**: Prioritizes cards based on user response patterns and revlog data
4. **Track Learning Progress**: Maintains detailed analytics for continuous optimization
## Fitts' Law Applied to Memory
**Traditional Fitts' Law (Motor Tasks):**
```text
Movement Time = a + b × log₂(Distance/Target_Width + 1)
```
**Our Memory Adaptation:**
```text
Response Time = a + b × log₂(Memory_Distance/Memory_Accessibility + 1)
```
Where:
- **Memory Distance** = function of time since last review and card difficulty
- **Memory Accessibility** = function of memory stability and ease factor
- **Response Time** = predicted cognitive recall time (crescimento exponencial sem limite superior)
## Key Features
- **🧠 Intelligent Difficulty Classification**: Cards automatically classified into 5 difficulty levels
- **⏱️ Crescimento Exponencial**: Response times crescem exponencialmente sem limite superior rígido
- **📊 Revlog-Driven Ordering**: Card order based entirely on user response patterns
- **🎯 Priority-Based Scheduling**: Smart review order based on urgency × difficulty × error rate
- **📈 Learning Analytics**: Detailed performance tracking and optimization recommendations
- **🔄 FSRS Integration**: Seamless integration with state-of-the-art spaced repetition algorithms
## Core Components
### FittsMemoryScheduler
The main scheduler class that handles:
- **Card Management**: Add, track, and organize memory cards across multiple decks
- **Difficulty Classification**: Automatically categorize cards based on predicted response times
- **Review Scheduling**: Generate optimal review order based on user response history
- **Session Management**: Conduct review sessions with real-time adaptation
- **Analytics**: Track performance metrics and generate optimization recommendations
### Difficulty Levels
Cards are automatically classified based on predicted cognitive response time (exponential growth):
````rust
pub enum DifficultyLevel {
VeryEasy = 1, // < 2.0 seconds
Easy = 2, // 2.0s - 4.0s
Medium = 3, // 4.0s - 8.0s
Hard = 4, // 8.0s - 20.0s
VeryHard = 5, // ≥ 20.0s (sem limite superior)
}
```## Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
fitts = "0.1.0"
````
## Quick Start
```rust
use fitts::scheduler::{FittsMemoryScheduler, SchedulerConfig};
use fitts::{CardState, Rating};
fn main() -> Result<(), String> {
// Create scheduler with optimized configuration
let mut scheduler = FittsMemoryScheduler::new(SchedulerConfig {
max_cards_per_session: 15,
max_session_duration_minutes: 20,
prioritize_error_prone: true, // Key: prioritize problem cards
balance_difficulty_levels: false, // Let user responses drive order
urgency_multiplier: 1.5,
new_cards_limit: 8,
})?;
// Add a card
let card_state = CardState {
memory_state: None,
review_count: 0,
lapse_count: 0,
stability: 1.0,
ease: 2.5,
interval_days: 1.0,
last_review: None,
};
scheduler.add_card("my_deck".to_string(), "card_1".to_string(), card_state);
// Generate review schedule (order based on priority)
let schedule = scheduler.generate_review_schedule("user_id", "my_deck")?;
// Process user response (this updates future card ordering)
let result = scheduler.review_card(
"user_id".to_string(),
"my_deck".to_string(),
"card_1".to_string(),
Rating::Hard, // User found it difficult
8.5 // Slow response time
)?;
// Next time, this card will have higher priority due to poor performance
let updated_schedule = scheduler.generate_review_schedule("user_id", "my_deck")?;
Ok(())
}
```
## How It Works: Response-Driven Ordering
The scheduler uses user response patterns to optimize card ordering:
1. **Initial State**: All cards start with similar priority
2. **User Reviews Cards**: Response time and rating are recorded in revlog
3. **Priority Recalculation**: Cards with poor performance get higher priority:
- Slow response times → Higher priority
- Poor ratings (Again/Hard) → Higher priority
- High prediction error → Higher priority
4. **Reordering**: Next session prioritizes problem cards first
### Example Priority Calculation
```text
Priority = urgency_factor × difficulty_factor × error_factor × frequency_factor
Where:
- urgency_factor = 1.0 + (days_overdue × urgency_multiplier)
- difficulty_factor = difficulty_level.priority_multiplier()
- error_factor = 1.0 + error_rate (if prioritize_error_prone = true)
- frequency_factor = 1.0 / (reviews_since_update + 1.0)
```
## Examples
See the `examples/` directory for complete demonstrations:
- `memory_simulation_simple.rs` - Basic scheduler usage
- `response_driven_ordering.rs` - How user responses affect card ordering
- `comprehensive_scheduler_demo.rs` - Full feature demonstration
## Advanced Features
### Analytics and Optimization
```rust
// Get user performance statistics
if let Some(stats) = scheduler.get_user_stats("user_id") {
println!("Total reviews: {}", stats.total_reviews);
println!("Average response time: {:.2}s", stats.avg_response_time);
println!("Accuracy rate: {:.1}%", stats.accuracy_rate * 100.0);
}
// Generate deck optimization recommendations
let optimization = scheduler.generate_deck_optimization("deck_id")?;
println!("Total cards: {}", optimization.total_cards);
```
### Revlog Analysis
```rust
// Export complete review history for analysis
let revlog_json = scheduler.export_revlog();
// Each review creates a detailed revlog entry with:
// - Actual vs predicted response time
// - Rating and difficulty classification
// - Prediction error calculation
// - Context and metadata
```
## Configuration Options
```rust
pub struct SchedulerConfig {
pub max_cards_per_session: usize, // Limit cards per session
pub max_session_duration_minutes: usize, // Time limit per session
pub prioritize_error_prone: bool, // Boost priority for problem cards
pub balance_difficulty_levels: bool, // Balance vs pure response-driven
pub urgency_multiplier: f64, // How much to weight overdue cards
pub new_cards_limit: usize, // Max new cards per session
}
```
## Performance
The scheduler is optimized for real-time use:
- **Fast Priority Calculation**: O(n) complexity for card ordering
- **Efficient Revlog**: Minimal memory overhead per review
- **Batch Processing**: Optimized for multiple card reviews
- **Response Time Growth**: All predictions follow exponential progression without artificial caps
## Integration with FSRS
The scheduler seamlessly integrates with FSRS (Free Spaced Repetition Scheduler):
- Uses FSRS parameters for memory modeling
- Applies Fitts' Law for cognitive difficulty prediction
- Combines both systems for optimal review timing
- Maintains compatibility with FSRS card states
## License
This project is licensed under the MIT OR Apache-2.0 license.
## Contributing
Contributions are welcome! Please see the `examples/` directory for usage patterns and feel free to submit issues or pull requests.