FactHelper

Struct FactHelper 

Source
pub struct FactHelper;
Expand description

Helper functions for working with fact objects

Implementations§

Source§

impl FactHelper

Source

pub fn create_object(pairs: Vec<(&str, Value)>) -> Value

Create a generic object with key-value pairs

Examples found in repository?
examples/debug_conditions.rs (lines 40-45)
9fn test_simple_conditions() -> std::result::Result<(), Box<dyn Error>> {
10    println!("=== Testing Simple Conditions ===");
11
12    // Create Knowledge Base
13    let kb = KnowledgeBase::new("TestConditions");
14
15    // Test compound condition with &&
16    let compound_rule = r#"rule "CompoundRule" { when TestCar.speedUp == true && TestCar.speed < TestCar.maxSpeed then TestCar.result = "compound_fired"; }"#;
17
18    println!("Testing rule: {}", compound_rule);
19
20    // Parse and add rule
21    let rules = GRLParser::parse_rules(compound_rule)?;
22    let rule = rules.into_iter().next().unwrap();
23    println!("Parsed rule: {:?}", rule);
24
25    let _ = kb.add_rule(rule);
26
27    // Create engine with debug mode
28    let config = EngineConfig {
29        max_cycles: 10,
30        timeout: None,
31        enable_stats: true,
32        debug_mode: true,
33    };
34    let engine = RustRuleEngine::with_config(kb, config);
35
36    // Create facts
37    let facts = Facts::new();
38
39    // Create simple TestCar object with all needed properties
40    let test_car = FactHelper::create_object(vec![
41        ("speedUp", Value::Boolean(true)),
42        ("speed", Value::Number(30.0)),
43        ("maxSpeed", Value::Number(100.0)),
44        ("result", Value::String("not_fired".to_string())),
45    ]);
46
47    facts.add_value("TestCar", test_car)?;
48
49    println!("\n🏁 Before execution:");
50    if let Some(car) = facts.get("TestCar") {
51        println!("   TestCar.speedUp = {:?}", car.get_property("speedUp"));
52        println!("   TestCar.speed = {:?}", car.get_property("speed"));
53        println!("   TestCar.maxSpeed = {:?}", car.get_property("maxSpeed"));
54        println!("   TestCar.result = {:?}", car.get_property("result"));
55    }
56
57    // Execute rules
58    println!("\n🚀 Executing rule...");
59    let result = engine.execute(&facts)?;
60
61    println!("Rules fired: {}", result.rules_fired);
62
63    println!("\n🏁 After execution:");
64    if let Some(car) = facts.get("TestCar") {
65        println!("   TestCar.speedUp = {:?}", car.get_property("speedUp"));
66        println!("   TestCar.result = {:?}", car.get_property("result"));
67    }
68
69    Ok(())
70}
Source

pub fn create_user( name: &str, age: i64, email: &str, country: &str, is_vip: bool, ) -> Value

Create a User fact from common fields

Source

pub fn create_product( name: &str, price: f64, category: &str, in_stock: bool, stock_count: i64, ) -> Value

Create a Product fact

Source

pub fn create_order( id: &str, user_id: &str, total: f64, item_count: i64, status: &str, ) -> Value

Create an Order fact

Source

pub fn create_test_car( speed_up: bool, speed: f64, max_speed: f64, speed_increment: f64, ) -> Value

Create a TestCar object for method call demo

Examples found in repository?
examples/advanced_method_calls.rs (lines 39-44)
9fn demo_method_calls() -> std::result::Result<(), Box<dyn Error>> {
10    println!("=== Demo: Advanced Method Calls ===");
11
12    // Create Knowledge Base
13    let kb = KnowledgeBase::new("MethodCallsDemo");
14
15    // Define rule with simpler condition first
16    let speedup_rule = r#"rule "SpeedUp" salience 10 { 
17        when TestCar.speedUp == true 
18        then TestCar.Speed = 70; 
19    }"#;
20
21    // Parse and add rule
22    let rules = GRLParser::parse_rules(speedup_rule)?;
23    let rule = rules.into_iter().next().unwrap();
24    let _ = kb.add_rule(rule);
25
26    // Create engine with debug mode
27    let config = EngineConfig {
28        max_cycles: 10,
29        timeout: None,
30        enable_stats: true,
31        debug_mode: true,
32    };
33    let engine = RustRuleEngine::with_config(kb, config);
34
35    // Create facts
36    let facts = Facts::new();
37
38    // Create TestCar object using helper
39    let test_car = FactHelper::create_test_car(
40        true,  // speedUp
41        50.0,  // speed
42        100.0, // maxSpeed
43        10.0,  // speedIncrement
44    );
45
46    // Create DistanceRecord object using helper
47    let distance_record = FactHelper::create_distance_record(0.0);
48
49    // Add facts
50    facts.add_value("TestCar", test_car)?;
51    facts.add_value("DistanceRecord", distance_record)?;
52
53    println!("\n🏁 Initial state:");
54    if let Some(car) = facts.get("TestCar") {
55        if let Some(speed) = car.get_property("Speed") {
56            println!("   TestCar.Speed = {:?}", speed);
57        }
58        if let Some(speed_up) = car.get_property("speedUp") {
59            println!("   TestCar.speedUp = {:?}", speed_up);
60        }
61    }
62
63    // Execute rules multiple cycles to see progression
64    println!("\n🚀 Executing SpeedUp rule multiple times...");
65    for i in 1..=3 {
66        println!("\n--- Cycle {} ---", i);
67        let result = engine.execute(&facts)?;
68
69        println!("Rules fired: {}", result.rules_fired);
70
71        if let Some(car) = facts.get("TestCar") {
72            if let Some(speed) = car.get_property("Speed") {
73                println!("TestCar.Speed after cycle {}: {:?}", i, speed);
74            }
75        }
76
77        // Check if we reached max speed
78        if let Some(car) = facts.get("TestCar") {
79            if let Some(speed) = car.get_property("speed") {
80                if let Some(max_speed) = car.get_property("maxSpeed") {
81                    if speed.to_number() >= max_speed.to_number() {
82                        println!("🏁 Max speed reached!");
83                        break;
84                    }
85                }
86            }
87        }
88    }
89
90    println!("\n📊 Final Results:");
91    if let Some(car) = facts.get("TestCar") {
92        if let Some(speed) = car.get_property("Speed") {
93            println!("   Final TestCar.Speed = {:?}", speed);
94        }
95    }
96
97    Ok(())
98}
More examples
Hide additional examples
examples/complete_speedup_demo.rs (lines 50-55)
9fn demo_complete_speedup_rule() -> std::result::Result<(), Box<dyn Error>> {
10    println!("=== Demo: Complete SpeedUp Rule with Method Calls ===");
11    println!("Implementing the exact rule from the requirement:");
12    println!("rule \"SpeedUp\" salience 10");
13    println!("when");
14    println!("    $TestCar : TestCarClass( speedUp == true && speed < maxSpeed )");
15    println!("    $DistanceRecord : DistanceRecordClass()");
16    println!("then");
17    println!("    $TestCar.setSpeed($TestCar.Speed + $TestCar.SpeedIncrement);");
18    println!("    update($TestCar);");
19    println!("    $DistanceRecord.setTotalDistance($DistanceRecord.getTotalDistance() + $TestCar.Speed);");
20    println!("    update($DistanceRecord);");
21    println!("end\n");
22
23    // Create Knowledge Base
24    let kb = KnowledgeBase::new("SpeedUpDemo");
25
26    // For now, we'll use a simplified version that works with our current parser
27    let speedup_rule = r#"rule "SpeedUp" salience 10 { 
28        when TestCar.speedUp == true && TestCar.speed < TestCar.maxSpeed 
29        then $TestCar.setSpeed($TestCar.Speed + $TestCar.SpeedIncrement); update($TestCar); $DistanceRecord.setTotalDistance($DistanceRecord.getTotalDistance() + $TestCar.Speed); update($DistanceRecord); 
30    }"#;
31
32    // Parse and add rule
33    let rules = GRLParser::parse_rules(speedup_rule)?;
34    let rule = rules.into_iter().next().unwrap();
35    let _ = kb.add_rule(rule);
36
37    // Create engine with debug mode
38    let config = EngineConfig {
39        max_cycles: 10,
40        timeout: None,
41        enable_stats: true,
42        debug_mode: true,
43    };
44    let engine = RustRuleEngine::with_config(kb, config);
45
46    // Create facts
47    let facts = Facts::new();
48
49    // Create TestCar object - initial speed less than max
50    let test_car = FactHelper::create_test_car(
51        true,  // speedUp
52        30.0,  // speed (less than maxSpeed)
53        100.0, // maxSpeed
54        15.0,  // speedIncrement
55    );
56
57    // Create DistanceRecord object
58    let distance_record = FactHelper::create_distance_record(0.0);
59
60    // Add facts
61    facts.add_value("TestCar", test_car)?;
62    facts.add_value("DistanceRecord", distance_record)?;
63
64    println!("🏁 Initial state:");
65    if let Some(car) = facts.get("TestCar") {
66        println!(
67            "   TestCar.speed = {:?}",
68            car.get_property("speed").unwrap_or(Value::Null)
69        );
70        println!(
71            "   TestCar.Speed = {:?}",
72            car.get_property("Speed").unwrap_or(Value::Null)
73        );
74        println!(
75            "   TestCar.maxSpeed = {:?}",
76            car.get_property("maxSpeed").unwrap_or(Value::Null)
77        );
78        println!(
79            "   TestCar.speedUp = {:?}",
80            car.get_property("speedUp").unwrap_or(Value::Null)
81        );
82        println!(
83            "   TestCar.SpeedIncrement = {:?}",
84            car.get_property("SpeedIncrement").unwrap_or(Value::Null)
85        );
86    }
87    if let Some(record) = facts.get("DistanceRecord") {
88        println!(
89            "   DistanceRecord.TotalDistance = {:?}",
90            record.get_property("TotalDistance").unwrap_or(Value::Null)
91        );
92    }
93
94    // Execute rules multiple cycles
95    println!("\n🚀 Executing SpeedUp rule...");
96    for i in 1..=5 {
97        println!("\n--- Cycle {} ---", i);
98        let result = engine.execute(&facts)?;
99
100        println!("Rules fired: {}", result.rules_fired);
101
102        if let Some(car) = facts.get("TestCar") {
103            println!(
104                "TestCar.Speed = {:?}",
105                car.get_property("Speed").unwrap_or(Value::Null)
106            );
107            println!(
108                "TestCar.speed = {:?}",
109                car.get_property("speed").unwrap_or(Value::Null)
110            );
111        }
112        if let Some(record) = facts.get("DistanceRecord") {
113            println!(
114                "DistanceRecord.TotalDistance = {:?}",
115                record.get_property("TotalDistance").unwrap_or(Value::Null)
116            );
117        }
118
119        // Check if we reached max speed
120        if let Some(car) = facts.get("TestCar") {
121            if let Some(speed) = car.get_property("speed") {
122                if let Some(max_speed) = car.get_property("maxSpeed") {
123                    if speed.to_number() >= max_speed.to_number() {
124                        println!("🏁 Max speed reached! Rule will no longer fire.");
125                        break;
126                    }
127                }
128            }
129        }
130
131        if result.rules_fired == 0 {
132            println!("ℹ️ No rules fired this cycle.");
133            break;
134        }
135    }
136
137    println!("\n📊 Final Summary:");
138    println!("✅ Successfully demonstrated method calls in GRL:");
139    println!("   • Method calls: $Object.method(args)");
140    println!("   • Property access: $Object.Property");
141    println!("   • Arithmetic expressions: $A.prop + $B.prop");
142    println!("   • update() function calls");
143    println!("   • Complex conditions with && operator");
144
145    Ok(())
146}
Source

pub fn create_distance_record(total_distance: f64) -> Value

Create a DistanceRecord object for method call demo

Examples found in repository?
examples/advanced_method_calls.rs (line 47)
9fn demo_method_calls() -> std::result::Result<(), Box<dyn Error>> {
10    println!("=== Demo: Advanced Method Calls ===");
11
12    // Create Knowledge Base
13    let kb = KnowledgeBase::new("MethodCallsDemo");
14
15    // Define rule with simpler condition first
16    let speedup_rule = r#"rule "SpeedUp" salience 10 { 
17        when TestCar.speedUp == true 
18        then TestCar.Speed = 70; 
19    }"#;
20
21    // Parse and add rule
22    let rules = GRLParser::parse_rules(speedup_rule)?;
23    let rule = rules.into_iter().next().unwrap();
24    let _ = kb.add_rule(rule);
25
26    // Create engine with debug mode
27    let config = EngineConfig {
28        max_cycles: 10,
29        timeout: None,
30        enable_stats: true,
31        debug_mode: true,
32    };
33    let engine = RustRuleEngine::with_config(kb, config);
34
35    // Create facts
36    let facts = Facts::new();
37
38    // Create TestCar object using helper
39    let test_car = FactHelper::create_test_car(
40        true,  // speedUp
41        50.0,  // speed
42        100.0, // maxSpeed
43        10.0,  // speedIncrement
44    );
45
46    // Create DistanceRecord object using helper
47    let distance_record = FactHelper::create_distance_record(0.0);
48
49    // Add facts
50    facts.add_value("TestCar", test_car)?;
51    facts.add_value("DistanceRecord", distance_record)?;
52
53    println!("\n🏁 Initial state:");
54    if let Some(car) = facts.get("TestCar") {
55        if let Some(speed) = car.get_property("Speed") {
56            println!("   TestCar.Speed = {:?}", speed);
57        }
58        if let Some(speed_up) = car.get_property("speedUp") {
59            println!("   TestCar.speedUp = {:?}", speed_up);
60        }
61    }
62
63    // Execute rules multiple cycles to see progression
64    println!("\n🚀 Executing SpeedUp rule multiple times...");
65    for i in 1..=3 {
66        println!("\n--- Cycle {} ---", i);
67        let result = engine.execute(&facts)?;
68
69        println!("Rules fired: {}", result.rules_fired);
70
71        if let Some(car) = facts.get("TestCar") {
72            if let Some(speed) = car.get_property("Speed") {
73                println!("TestCar.Speed after cycle {}: {:?}", i, speed);
74            }
75        }
76
77        // Check if we reached max speed
78        if let Some(car) = facts.get("TestCar") {
79            if let Some(speed) = car.get_property("speed") {
80                if let Some(max_speed) = car.get_property("maxSpeed") {
81                    if speed.to_number() >= max_speed.to_number() {
82                        println!("🏁 Max speed reached!");
83                        break;
84                    }
85                }
86            }
87        }
88    }
89
90    println!("\n📊 Final Results:");
91    if let Some(car) = facts.get("TestCar") {
92        if let Some(speed) = car.get_property("Speed") {
93            println!("   Final TestCar.Speed = {:?}", speed);
94        }
95    }
96
97    Ok(())
98}
More examples
Hide additional examples
examples/complete_speedup_demo.rs (line 58)
9fn demo_complete_speedup_rule() -> std::result::Result<(), Box<dyn Error>> {
10    println!("=== Demo: Complete SpeedUp Rule with Method Calls ===");
11    println!("Implementing the exact rule from the requirement:");
12    println!("rule \"SpeedUp\" salience 10");
13    println!("when");
14    println!("    $TestCar : TestCarClass( speedUp == true && speed < maxSpeed )");
15    println!("    $DistanceRecord : DistanceRecordClass()");
16    println!("then");
17    println!("    $TestCar.setSpeed($TestCar.Speed + $TestCar.SpeedIncrement);");
18    println!("    update($TestCar);");
19    println!("    $DistanceRecord.setTotalDistance($DistanceRecord.getTotalDistance() + $TestCar.Speed);");
20    println!("    update($DistanceRecord);");
21    println!("end\n");
22
23    // Create Knowledge Base
24    let kb = KnowledgeBase::new("SpeedUpDemo");
25
26    // For now, we'll use a simplified version that works with our current parser
27    let speedup_rule = r#"rule "SpeedUp" salience 10 { 
28        when TestCar.speedUp == true && TestCar.speed < TestCar.maxSpeed 
29        then $TestCar.setSpeed($TestCar.Speed + $TestCar.SpeedIncrement); update($TestCar); $DistanceRecord.setTotalDistance($DistanceRecord.getTotalDistance() + $TestCar.Speed); update($DistanceRecord); 
30    }"#;
31
32    // Parse and add rule
33    let rules = GRLParser::parse_rules(speedup_rule)?;
34    let rule = rules.into_iter().next().unwrap();
35    let _ = kb.add_rule(rule);
36
37    // Create engine with debug mode
38    let config = EngineConfig {
39        max_cycles: 10,
40        timeout: None,
41        enable_stats: true,
42        debug_mode: true,
43    };
44    let engine = RustRuleEngine::with_config(kb, config);
45
46    // Create facts
47    let facts = Facts::new();
48
49    // Create TestCar object - initial speed less than max
50    let test_car = FactHelper::create_test_car(
51        true,  // speedUp
52        30.0,  // speed (less than maxSpeed)
53        100.0, // maxSpeed
54        15.0,  // speedIncrement
55    );
56
57    // Create DistanceRecord object
58    let distance_record = FactHelper::create_distance_record(0.0);
59
60    // Add facts
61    facts.add_value("TestCar", test_car)?;
62    facts.add_value("DistanceRecord", distance_record)?;
63
64    println!("🏁 Initial state:");
65    if let Some(car) = facts.get("TestCar") {
66        println!(
67            "   TestCar.speed = {:?}",
68            car.get_property("speed").unwrap_or(Value::Null)
69        );
70        println!(
71            "   TestCar.Speed = {:?}",
72            car.get_property("Speed").unwrap_or(Value::Null)
73        );
74        println!(
75            "   TestCar.maxSpeed = {:?}",
76            car.get_property("maxSpeed").unwrap_or(Value::Null)
77        );
78        println!(
79            "   TestCar.speedUp = {:?}",
80            car.get_property("speedUp").unwrap_or(Value::Null)
81        );
82        println!(
83            "   TestCar.SpeedIncrement = {:?}",
84            car.get_property("SpeedIncrement").unwrap_or(Value::Null)
85        );
86    }
87    if let Some(record) = facts.get("DistanceRecord") {
88        println!(
89            "   DistanceRecord.TotalDistance = {:?}",
90            record.get_property("TotalDistance").unwrap_or(Value::Null)
91        );
92    }
93
94    // Execute rules multiple cycles
95    println!("\n🚀 Executing SpeedUp rule...");
96    for i in 1..=5 {
97        println!("\n--- Cycle {} ---", i);
98        let result = engine.execute(&facts)?;
99
100        println!("Rules fired: {}", result.rules_fired);
101
102        if let Some(car) = facts.get("TestCar") {
103            println!(
104                "TestCar.Speed = {:?}",
105                car.get_property("Speed").unwrap_or(Value::Null)
106            );
107            println!(
108                "TestCar.speed = {:?}",
109                car.get_property("speed").unwrap_or(Value::Null)
110            );
111        }
112        if let Some(record) = facts.get("DistanceRecord") {
113            println!(
114                "DistanceRecord.TotalDistance = {:?}",
115                record.get_property("TotalDistance").unwrap_or(Value::Null)
116            );
117        }
118
119        // Check if we reached max speed
120        if let Some(car) = facts.get("TestCar") {
121            if let Some(speed) = car.get_property("speed") {
122                if let Some(max_speed) = car.get_property("maxSpeed") {
123                    if speed.to_number() >= max_speed.to_number() {
124                        println!("🏁 Max speed reached! Rule will no longer fire.");
125                        break;
126                    }
127                }
128            }
129        }
130
131        if result.rules_fired == 0 {
132            println!("ℹ️ No rules fired this cycle.");
133            break;
134        }
135    }
136
137    println!("\n📊 Final Summary:");
138    println!("✅ Successfully demonstrated method calls in GRL:");
139    println!("   • Method calls: $Object.method(args)");
140    println!("   • Property access: $Object.Property");
141    println!("   • Arithmetic expressions: $A.prop + $B.prop");
142    println!("   • update() function calls");
143    println!("   • Complex conditions with && operator");
144
145    Ok(())
146}
Source

pub fn create_transaction( id: &str, amount: f64, location: &str, timestamp: i64, user_id: &str, ) -> Value

Create a Transaction fact for fraud detection

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.