#!/usr/bin/env cargo run --example symbolic_optimization_demo --features optimization
use mathcompile::final_tagless::{ASTEval, ASTMathExpr, ASTRepr};
use mathcompile::symbolic::{OptimizationConfig, SymbolicOptimizer};
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("🧮 MathCompile Symbolic Optimization Demo");
println!("{}", "=".repeat(50));
println!();
let mut optimizer = SymbolicOptimizer::new()?;
println!("📋 Testing Basic Arithmetic Identities");
println!("{}", "-".repeat(40));
demo_optimization(
&mut optimizer,
"x + 0",
&ASTEval::add(ASTEval::var_by_name("x"), ASTEval::constant(0.0)),
"x",
)?;
demo_optimization(
&mut optimizer,
"x * 1",
&ASTEval::mul(ASTEval::var_by_name("x"), ASTEval::constant(1.0)),
"x",
)?;
demo_optimization(
&mut optimizer,
"x * 0",
&ASTEval::mul(ASTEval::var_by_name("x"), ASTEval::constant(0.0)),
"0",
)?;
demo_optimization(
&mut optimizer,
"x - x",
&ASTEval::sub(ASTEval::var_by_name("x"), ASTEval::var_by_name("x")),
"0",
)?;
println!();
println!("🔢 Testing Constant Folding");
println!("{}", "-".repeat(40));
demo_optimization(
&mut optimizer,
"2 + 3",
&ASTEval::add(ASTEval::constant(2.0), ASTEval::constant(3.0)),
"5",
)?;
demo_optimization(
&mut optimizer,
"4 * 5",
&ASTEval::mul(ASTEval::constant(4.0), ASTEval::constant(5.0)),
"20",
)?;
demo_optimization(
&mut optimizer,
"10 / 2",
&ASTEval::div(ASTEval::constant(10.0), ASTEval::constant(2.0)),
"5",
)?;
demo_optimization(
&mut optimizer,
"2^3",
&ASTEval::pow(ASTEval::constant(2.0), ASTEval::constant(3.0)),
"8",
)?;
println!();
println!("⚡ Testing Power Optimizations");
println!("{}", "-".repeat(40));
demo_optimization(
&mut optimizer,
"x^0",
&ASTEval::pow(ASTEval::var_by_name("x"), ASTEval::constant(0.0)),
"1",
)?;
demo_optimization(
&mut optimizer,
"x^1",
&ASTEval::pow(ASTEval::var_by_name("x"), ASTEval::constant(1.0)),
"x",
)?;
demo_optimization(
&mut optimizer,
"1^x",
&ASTEval::pow(ASTEval::constant(1.0), ASTEval::var_by_name("x")),
"1",
)?;
println!();
println!("📈 Testing Transcendental Function Optimizations");
println!("{}", "-".repeat(40));
demo_optimization(
&mut optimizer,
"ln(1)",
&ASTEval::ln(ASTEval::constant(1.0)),
"0",
)?;
demo_optimization(
&mut optimizer,
"exp(0)",
&ASTEval::exp(ASTEval::constant(0.0)),
"1",
)?;
demo_optimization(
&mut optimizer,
"sin(0)",
&ASTEval::sin(ASTEval::constant(0.0)),
"0",
)?;
demo_optimization(
&mut optimizer,
"cos(0)",
&ASTEval::cos(ASTEval::constant(0.0)),
"1",
)?;
println!();
println!("🔗 Testing Complex Expression Optimization");
println!("{}", "-".repeat(40));
let complex_expr = ASTEval::add(
ASTEval::mul(
ASTEval::add(ASTEval::var_by_name("x"), ASTEval::constant(0.0)),
ASTEval::constant(1.0),
),
ASTEval::constant(0.0),
);
demo_optimization(&mut optimizer, "(x + 0) * 1 + 0", &complex_expr, "x")?;
let arithmetic_expr = ASTEval::add(
ASTEval::mul(ASTEval::constant(2.0), ASTEval::constant(3.0)),
ASTEval::mul(ASTEval::constant(4.0), ASTEval::constant(5.0)),
);
demo_optimization(&mut optimizer, "2 * 3 + 4 * 5", &arithmetic_expr, "26")?;
let mixed_expr = ASTEval::add(
ASTEval::pow(ASTEval::var_by_name("x"), ASTEval::constant(1.0)),
ASTEval::mul(
ASTEval::ln(ASTEval::constant(1.0)),
ASTEval::var_by_name("y"),
),
);
demo_optimization(&mut optimizer, "x^1 + ln(1) * y", &mixed_expr, "x")?;
println!();
println!("⚙️ Testing Custom Optimization Configuration");
println!("{}", "-".repeat(40));
let config = OptimizationConfig {
max_iterations: 5,
aggressive: false,
constant_folding: false,
cse: true,
egglog_optimization: false,
};
let mut conservative_optimizer = SymbolicOptimizer::with_config(config)?;
println!("🔧 With constant folding disabled:");
let expr = ASTEval::add(ASTEval::constant(2.0), ASTEval::constant(3.0));
let _optimized = conservative_optimizer.optimize(&expr)?;
println!(" Original: 2 + 3");
println!(" Optimized: 2 + 3 (should remain as 2 + 3)");
println!();
println!("🎯 Optimization Benefits");
println!("{}", "-".repeat(40));
println!("✅ Reduced expression complexity");
println!("✅ Eliminated redundant operations");
println!("✅ Pre-computed constant expressions");
println!("✅ Applied mathematical identities");
println!("✅ Prepared expressions for efficient JIT compilation");
println!();
println!("🚀 Next Steps: Integration with JIT Compilation");
println!("{}", "-".repeat(40));
println!("The optimized expressions can now be passed to the JIT compiler");
println!("for even better performance through native code generation!");
Ok(())
}
fn demo_optimization(
optimizer: &mut SymbolicOptimizer,
description: &str,
expr: &ASTRepr<f64>,
_expected: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let _optimized = optimizer.optimize(expr)?;
println!(" {description} → optimized ✓");
Ok(())
}