use mathcompile::final_tagless::{
ASTEval, ASTMathExpr, ASTRepr, DirectEval, ExpressionBuilder, clear_global_registry,
register_variable,
};
fn main() {
println!("=== Variable Indexing Efficiency Demo ===\n");
clear_global_registry();
println!("1. Efficient Variable Indexing (Vector lookup):");
let efficient_expr = ASTRepr::Add(
Box::new(ASTRepr::Mul(
Box::new(ASTRepr::Variable(0)), Box::new(ASTRepr::Constant(2.0)),
)),
Box::new(ASTRepr::Variable(1)), );
let variables = [3.0, 4.0]; let result1 = DirectEval::eval_with_vars(&efficient_expr, &variables);
println!(" Expression: 2*x + y where x=3, y=4");
println!(" Result: {result1}");
println!(" Expected: 2*3 + 4 = 10");
assert_eq!(result1, 10.0);
println!(" ✓ Correct!");
println!("\n2. Named Variables (using global registry):");
let x_index = register_variable("x");
let y_index = register_variable("y");
let named_expr = ASTRepr::Add(
Box::new(ASTRepr::Mul(
Box::new(ASTRepr::Variable(x_index)),
Box::new(ASTRepr::Constant(2.0)),
)),
Box::new(ASTRepr::Variable(y_index)),
);
let result2 = DirectEval::eval_with_vars(&named_expr, &variables);
println!(" Expression: 2*x + y where x=3, y=4");
println!(" Result: {result2}");
println!(" Expected: 2*3 + 4 = 10");
assert_eq!(result2, 10.0);
println!(" ✓ Correct!");
println!("\n3. Using ASTEval convenient methods:");
let api_expr = ASTEval::add(
ASTEval::mul(ASTEval::var(0), ASTEval::constant(2.0)), ASTEval::var_by_name("y"), );
let result3 = DirectEval::eval_with_vars(&api_expr, &variables);
println!(" Mixed: ASTEval::var(0) * 2 + ASTEval::var_by_name(\"y\")");
println!(" Result: {result3}");
println!(" Expected: 2*3 + 4 = 10");
assert_eq!(result3, 10.0);
println!(" ✓ Correct!");
println!("\n4. Named Variable Evaluation (convenient):");
let mut builder = ExpressionBuilder::new();
let api_expr = ASTRepr::Add(Box::new(builder.var("x")), Box::new(builder.var("y")));
let named_vars = vec![("x".to_string(), 3.0), ("y".to_string(), 4.0)];
let result4 = builder.eval_with_named_vars(&api_expr, &named_vars);
println!(" Result: {result4}");
println!("\n5. Multi-variable expression:");
let multi_var_expr = ASTEval::add(
ASTEval::add(
ASTEval::mul(ASTEval::var(0), ASTEval::constant(2.0)), ASTEval::mul(ASTEval::var(1), ASTEval::constant(3.0)), ),
ASTEval::add(
ASTEval::mul(ASTEval::var(2), ASTEval::constant(4.0)), ASTEval::var(3), ),
);
let multi_vars = [1.0, 2.0, 3.0, 4.0]; let result5 = DirectEval::eval_with_vars(&multi_var_expr, &multi_vars);
println!(" Expression: 2*x + 3*y + 4*z + w where x=1, y=2, z=3, w=4");
println!(" Result: {result5}");
println!(" Expected: 2*1 + 3*2 + 4*3 + 4 = 2 + 6 + 12 + 4 = 24");
assert_eq!(result5, 24.0);
println!(" ✓ Correct!");
println!("\n=== Summary ===");
println!("✓ Variable(usize) - Most efficient, uses vector indexing O(1)");
println!("✓ Named variables via global registry - User-friendly with good performance");
println!("✓ Both types work seamlessly with DirectEval::eval_with_vars");
println!("✓ eval_with_named_vars_f64 provides convenient named variable evaluation");
println!("✓ Can mix indexed and named variables in the same expression");
println!("\n🚀 DirectEval can now use vector lookups for optimal performance!");
println!("📈 For performance-critical code, use Variable(index) instead of named variables");
}