# Reverse Evaluation System

## Overview

The reverse evaluation system enables constraint propagation through Hamelin expressions, supporting incremental materialization and query optimization. Given an expression and constraints on its output, the system determines what constraints must hold on the input variables.

## Core Concept

**Forward Evaluation:** `f(x) = y` (given x, compute y)
**Reverse Evaluation:** `f(x) = y` with constraint on y, determine constraint on x

### Example
```hamelin
# Expression: epoch_col @ day
# Output constraint: equals '2024-01-15 00:00:00 UTC'
# Reverse evaluation result: epoch_col ∈ [1705276800, 1705363200)
```

## Architecture

The function dispatches to type-specific handlers based on the expression kind:
- **Literals** → `Constraint::Empty` (constants can't be constrained)
- **Column References** → Direct constraint assignment
- **Function Calls** → Use `FunctionDef.with_reverse()` for constraint transformation (single variable parameter only)
- **Operators** → Use `FunctionDef.with_reverse()` for constraint transformation (single variable parameter only)
- **TsTrunc** → Specialized reverse evaluation logic using `reverse_eval_ts_trunc()`

## Supported Operations

### How to Check What's Supported

Functions and operators that support reverse evaluation have a `.with_reverse()` method defined in their `FunctionDef`. To see what's currently supported:

**Check the function registry** (`hamelin_lib/src/func/registry.rs`):
```rust
// Look for functions with .with_reverse() calls
FunctionDef::of("function_name")
    .with_parameter(...)
    .with_reverse(|output_constraint, params| {
        // Reverse evaluation logic here
    })
```

**Special case - Timestamp Truncation:**
The `@` operator (timestamp truncation) has specialized logic implemented directly in `reverse_eval_ts_trunc()` rather than using the function registry pattern.

## Implementation Notes

### Extensibility

The system is designed for easy extension:

1. **Function Integration:** Add `.with_reverse()` to `FunctionDef`
2. **Constraint Types:** Extend `Constraint<V>` enum for new constraint types
3. **Value Types:** Support new `Value` variants in constraint operations

### Current Limitations

- **Single Variable Per Expression:** Only one parameter in a function/operator can contain variables
- **No Variable Duplication:** Variables cannot appear multiple times in the same expression
- **Limited Operator Support:** Only basic arithmetic and timestamp operations implemented

## Edge Cases and Considerations

- **Timezone Handling:** Currently assumes UTC; timezone-aware support planned for eval system
- **Precision:** Floating point precision handled carefully in timestamp conversions
- **Boundary Conditions:** Proper handling of inclusive/exclusive ranges
- **Type Coercion:** Automatic conversion between numeric types in arithmetic
