use rust_rule_engine::engine::engine::RustRuleEngine;
use rust_rule_engine::engine::knowledge_base::KnowledgeBase;
use rust_rule_engine::parser::grl::GRLParser;
use rust_rule_engine::rete::{GrlReteLoader, IncrementalEngine, TypedFacts};
use rust_rule_engine::{Facts, Value};
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("\n🧮 Expression Evaluation Demo - CLIPS-style");
println!("============================================\n");
let grl_content = std::fs::read_to_string("examples/rules/01-basic/expression_demo.grl")?;
let rules = GRLParser::parse_rules(&grl_content)?;
let kb = KnowledgeBase::new("expression_demo");
for rule in &rules {
kb.add_rule(rule.clone())?;
}
let mut engine = RustRuleEngine::new(kb);
println!("📋 Example 1: Calculate Order Total");
println!("------------------------------------");
let facts = Facts::new();
facts.set("Order.quantity", Value::Integer(10));
facts.set("Order.price", Value::Integer(100));
println!("Before execution:");
println!(" Order.quantity: {:?}", facts.get("Order.quantity"));
println!(" Order.price: {:?}", facts.get("Order.price"));
engine.execute(&facts)?;
println!("\nAfter execution:");
println!(" Order.total (10 * 100): {:?}", facts.get("Order.total"));
println!(
" Order.discount (1000 * 0.1): {:?}",
facts.get("Order.discount")
);
println!(" Order.final (1000 - 100): {:?}", facts.get("Order.final"));
println!(" Order.tax (900 * 0.08): {:?}", facts.get("Order.tax"));
println!(
" Order.grandTotal (900 + 72): {:?}",
facts.get("Order.grandTotal")
);
println!(
" Order.bulkSavings (1000 * 0.15): {:?}",
facts.get("Order.bulkSavings")
);
println!("\n📋 Example 2: Small Order (No Bulk Discount)");
println!("---------------------------------------------");
let kb2 = KnowledgeBase::new("expression_demo");
for rule in &rules {
kb2.add_rule(rule.clone())?;
}
let mut engine2 = RustRuleEngine::new(kb2);
let facts2 = Facts::new();
facts2.set("Order.quantity", Value::Integer(5));
facts2.set("Order.price", Value::Integer(50));
println!("Before execution:");
println!(" Order.quantity: {:?}", facts2.get("Order.quantity"));
println!(" Order.price: {:?}", facts2.get("Order.price"));
engine2.execute(&facts2)?;
println!("\nAfter execution:");
println!(" Order.total (5 * 50): {:?}", facts2.get("Order.total"));
println!(
" Order.discount (250 * 0.1): {:?}",
facts2.get("Order.discount")
);
println!(" Order.final (250 - 25): {:?}", facts2.get("Order.final"));
println!(" Order.tax (225 * 0.08): {:?}", facts2.get("Order.tax"));
println!(
" Order.grandTotal (225 + 18): {:?}",
facts2.get("Order.grandTotal")
);
println!(" Order.bulkSavings: {:?}", facts2.get("Order.bulkSavings"));
println!("\n📋 Example 3: RETE Engine Test");
println!("--------------------------------");
let mut rete = IncrementalEngine::new();
let count = GrlReteLoader::load_from_string(&grl_content, &mut rete)?;
println!("Loaded {} rules into RETE\n", count);
let mut order = TypedFacts::new();
order.set("quantity", 15i64);
order.set("price", 80i64);
println!("Before (RETE):");
println!(
" quantity: {:?}, price: {:?}",
order.get("quantity"),
order.get("price")
);
let handle = rete.insert("Order".to_string(), order);
let fired = rete.fire_all();
println!("\nFired {} rules", fired.len());
if let Some(fact) = rete.working_memory().get(&handle) {
println!("\nAfter (RETE):");
println!(" total: {:?}", fact.data.get("total"));
println!(" discount: {:?}", fact.data.get("discount"));
println!(" final: {:?}", fact.data.get("final"));
println!(" tax: {:?}", fact.data.get("tax"));
println!(" grandTotal: {:?}", fact.data.get("grandTotal"));
}
println!("\n✨ Expression Evaluation Summary");
println!("===============================");
println!("✅ Arithmetic operators: +, -, *, /, %");
println!("✅ Field references: Order.quantity, Order.price");
println!("✅ Runtime evaluation: Expressions evaluated when rule fires");
println!("✅ Type preservation: Integer * Integer = Integer");
println!("✅ Float operations: Integer * 0.1 = Float");
println!("✅ Chained expressions: Order.total * 0.1 works perfectly");
println!("✅ Works with both RustRuleEngine and RETE!");
println!("\n📖 Similar to Drools DRL:");
println!(" Drools: $o.total = $o.quantity * $o.price");
println!(" Rust Rule Engine: Order.total = Order.quantity * Order.price");
Ok(())
}