fitts 0.0.2

A Fitts‑based memory model integrated with the Free Spaced Repetition Scheduler (FSRS) for smarter review scheduling.
Documentation
# 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.