method_calls_demo/
method_calls_demo.rs

1use rust_rule_engine::engine::facts::Facts;
2use rust_rule_engine::engine::knowledge_base::KnowledgeBase;
3use rust_rule_engine::engine::{EngineConfig, RustRuleEngine};
4use rust_rule_engine::parser::grl_parser::GRLParser;
5use rust_rule_engine::types::Value;
6use std::collections::HashMap;
7use std::fs;
8
9fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
10    println!("šŸŽÆ Method Calls Demo with Rule File");
11    println!("===================================\n");
12
13    // Read rules from file
14    let rule_file_path = "examples/rules/method_calls.grl";
15    println!("šŸ“„ Reading rules from file: {}", rule_file_path);
16
17    let rule_content = fs::read_to_string(rule_file_path)
18        .map_err(|e| format!("Failed to read rule file: {}", e))?;
19
20    println!("šŸ“‹ Rule file content:");
21    println!("---");
22    println!("{}", rule_content);
23    println!("---\n");
24
25    // Create facts
26    let facts = Facts::new();
27
28    // TestCar data
29    let mut test_car_props = HashMap::new();
30    test_car_props.insert("Speed".to_string(), Value::Number(30.0));
31    test_car_props.insert("MaxSpeed".to_string(), Value::Number(100.0));
32    test_car_props.insert("SpeedIncrement".to_string(), Value::Number(10.0));
33    test_car_props.insert("SpeedUp".to_string(), Value::Boolean(true));
34
35    facts.add_value("TestCar", Value::Object(test_car_props))?;
36
37    println!("šŸ Initial state:");
38    if let Some(car) = facts.get("TestCar") {
39        println!("   TestCar = {car:?}");
40    }
41    println!();
42
43    // Create knowledge base and add rules from GRL file
44    let kb = KnowledgeBase::new("MethodCallsDemo");
45
46    // Parse rules from GRL file
47    println!("šŸ”§ Parsing GRL file content...");
48    let rules = GRLParser::parse_rules(&rule_content)
49        .map_err(|e| format!("Failed to parse GRL file: {:?}", e))?;
50
51    println!("āœ… Successfully parsed {} rules from file", rules.len());
52    for rule in &rules {
53        println!("   šŸ“‹ Rule: {} (salience: {})", rule.name, rule.salience);
54        let _ = kb.add_rule(rule.clone());
55    }
56    println!();
57
58    // Create engine
59    let config = EngineConfig {
60        debug_mode: true,
61        max_cycles: 5,
62        ..Default::default()
63    };
64    let mut engine = RustRuleEngine::with_config(kb, config);
65
66    // Register custom functions for speed control
67    engine.register_function("increaseSpeed", |_args, facts| {
68        if let Some(car) = facts.get("TestCar") {
69            if let Value::Object(obj) = car {
70                let current_speed = obj.get("Speed").cloned().unwrap_or(Value::Number(0.0));
71                let increment = obj
72                    .get("SpeedIncrement")
73                    .cloned()
74                    .unwrap_or(Value::Number(10.0));
75
76                if let (Value::Number(speed), Value::Number(inc)) = (current_speed, increment) {
77                    let new_speed = speed + inc;
78                    println!("šŸš— Increasing speed: {} -> {}", speed, new_speed);
79                    // In real implementation, this would update the fact
80                    return Ok(Value::Number(new_speed));
81                }
82            }
83        }
84        Ok(Value::String("Speed increase attempted".to_string()))
85    });
86
87    engine.register_function("decreaseSpeed", |_args, facts| {
88        if let Some(car) = facts.get("TestCar") {
89            if let Value::Object(obj) = car {
90                let current_speed = obj.get("Speed").cloned().unwrap_or(Value::Number(0.0));
91                let increment = obj
92                    .get("SpeedIncrement")
93                    .cloned()
94                    .unwrap_or(Value::Number(10.0));
95
96                if let (Value::Number(speed), Value::Number(inc)) = (current_speed, increment) {
97                    let new_speed = (speed - inc).max(0.0);
98                    println!("šŸš— Decreasing speed: {} -> {}", speed, new_speed);
99                    // In real implementation, this would update the fact
100                    return Ok(Value::Number(new_speed));
101                }
102            }
103        }
104        Ok(Value::String("Speed decrease attempted".to_string()))
105    });
106
107    // Execute rules
108    println!("šŸš€ Executing method calls rules from file...");
109    let result = engine.execute(&facts)?;
110
111    println!("\nšŸ“Š Method Calls Execution Results:");
112    println!("   Cycles: {}", result.cycle_count);
113    println!("   Rules evaluated: {}", result.rules_evaluated);
114    println!("   Rules fired: {}", result.rules_fired);
115    println!("   Execution time: {:?}", result.execution_time);
116
117    println!("\nšŸ Final state:");
118    if let Some(car) = facts.get("TestCar") {
119        println!("   TestCar = {car:?}");
120    }
121
122    println!("\nšŸŽÆ Method Calls from Rule File Demonstrated:");
123    println!("   šŸ“„ Rules defined in external .grl file");
124    println!("   šŸ”§ Method calls: setSpeed(), setSpeedUp()");
125    println!("   šŸ“ž Custom functions: increaseSpeed(), decreaseSpeed()");
126    println!("   šŸš— Speed control simulation");
127    println!("   ⚔ Salience-based rule execution order");
128
129    Ok(())
130}