SlideShare uma empresa Scribd logo
1 de 35
Baixar para ler offline
RuleBox => Modern & Natural Rule Engine!
WHO AM I?
• Luis Majano
• Computer Engineer
• Born in El Salvador ->Texas
• CEO of Ortus Solutions
• Sandals -> ESRI -> Ortus
@lmajano
@ortussolutions
What is RuleBox
Why RuleBox was created
The Problem
What is a Rule Engine
Why use a Rule Engine
Implementation of RuleBox
What is RuleBox
• A modern and natural language rule engine
• Inspired by RuleBook (Java Project)
• Rules are written in the RuleBox Domain Specific Language (DSL)
• Modeled after Given-When-Then
• Dynamic and Expressive
https://forgebox.io/view/rulebox
Reference: https://github.com/rulebook-rules/rulebook
install rulebox
Why Create RuleBox
• Thanks to RevAgency for inspiration:
• Real world problem to handle cruise promotions
• Legacy app plagued with nested if-then-else
• Logic and data mixed
• Much more…
• Did my research:
• Majority of rule engines are complex and convoluted
• Nothing in ColdFusion (CFML) Landscape
• Found RuleBook articles inspiring
• Lots of caffeine, and RuleBox was born!
The
Problem
The Problem
• Ever nesting of if-then-else logic
• Imperative algorithms showing how instead of what?
• No Logic and Data Separation
• Logic is not easily followed
• Maintenance pain
• How testable is that code? Has it really been tested?
• The Domino Effect:
Single if statement can rule them all
What is a rule engine?
• Alternative computational model to traditional imperative programming
• Imperative: Sequence of commands with conditionals, loops and data
• Set of rules that have a condition and an action based on data=>facts
• The engine evaluates rules in the appropriate order and make sense of it
• You focus on the conditions and actions and not the how you do it.
Advantages
• Functional and Declarative Programming
• Speed and Scalability of development
• Understandable and Named Rules
• Increase Maintenance
• Increase Encapsulation of Logic
• Logic and Data Separation
When?
When…
• Remember the problem
• Logic and data intermixed
• Maintenance is painful
• Logic is brittle
• The logic changes often
• 500 lines of if-else statements
How?
How does it work?
How does it work?
Chain of Responsibility
• RuleBox Models CoR
• A RuleBook defines rules and chains them
together to provider order
• Facts flow to each rule (data-binding)
• RuleBooks control results
• Each Rule has a condition, an exception
and one or more actions
https://sourcemaking.com/design_patterns/chain_of_responsibility
RuleBox Flow
install rulebox
Create RuleBooks
Define Rules: when/then
Run Rules with Given Facts
Process Results
WireBox Mappings
• Rule@rulebox - A transient rule object
• RuleBook@rulebox - A transient rule book object
• Builder@rulebox - A static class that can be used to build a-la-carte rules
and rulebooks.
• Result@rulebox - RuleBooks produce results and this is the object that
models such results. Similar to Java Optionals
RuleBox DSL
• Given( name, value ) - The facts
• GivenAll( struct ) - Struct of facts

• When( closure/lambda ) - The conditions
• Except( closure/lambda ) - The exceptions
• Then( closure/lambda ) - The actions/consumers
Rules
Against a RuleBook
RuleBooks
component extends="rulebox.models.RuleBook"{
    function defineRules(){
setName( “My RuleBook” );
        // Add a new rule to this rulebook
        addRule(
            newRule( "MyRule" )
                .when( function( facts ){
                    return facts.keyExists( “hello” );
                } )
                .then( function( facts ){
                    systemOutput( "World" );
                } )
        );
    }
}
• ATransient CFC inherits from rulebox.models.RuleBook
• Can have a name property
• 1 Method: defineRules()
• Create rules using the DSL
Creating Rules
addRule(
    newRule( “name” )
    .when( function( facts ){
    } )
    .except( function( facts ){
    } )
    .then( function( facts, result ) {
    } )
)
.addRule( function( rule ){
    rule
    .setName( ‘name’ )
    .when( function( facts ){
    } )
    .except( function( facts ){
    } )
    .then( function( facts, result ) {
    } )
.stop();
} )
• Using the addRule( rule ) method
• Alternative Syntax, choose your comfort!
• Each Rule can have the following:
• Name (optional)
• 1 when()
• 0,1 except()
• * then()
• 1 stop()
• Best friend:Api Docs
https://apidocs.ortussolutions.com/#/coldbox-modules/rulebox/
When()
addRule(
    newRule()
        .when( function( facts ){
            return facts.keyExists( "hello" );
        })
        .then( function( facts ){
            sytemOutput( facts.hello );
        } )
)
• The condition portion
• Argument is a closure/lambda
• Must evaluate to boolean
• True => Executes Consumers (thens)
• False => Rule does not apply, skip consumers
• Receives facts as a struct
Except()
addRule(
    newRule()
        .when( function( facts ){
            return facts.keyExists( "hello" );
        })
.except( function( facts ){
    return facts.accountDisabled;
} )
        .then( function( facts ){
            sytemOutput( facts.hello );
        } )
)
• Negates the when() condition
• True => Skip consumers (thens)
• False => Continue to consumers
• Special cases and of course exceptions
• Why?To not pollute the when() with negated logic
Consumers : then()
then( function( facts, result ){ sytemOutput( facts.world ); } )
then( function( facts, result ){ result.setValue( result.getValue() * 0.80 ); } )
• The actions for your logic
• Closure that receives
• Facts => A struct of facts
• Results => A RuleBox Result object
• Can have multiple actions
• If the action returns true then it stops the chain of consumers
• Best friend:Api Docs
https://apidocs.ortussolutions.com/#/coldbox-modules/rulebox/
Stopping Consumers
.then( function( facts, result ) ){
    // do stuff
    // break the next then()
    return true;
})
.then( function( facts, result ) ){
    // This never fires
})
Stopping Rules
//credit score under 600 gets a 4x rate increase
addRule(
    newRule()
    .when( function( facts ){ return facts.applicant.getCreditScore() < 600; } )
    .then( function( facts, result ){ result.setValue( result.getValue() * 4 ); } )
    .stop()
);
• stop() on a rule
• Breaks the rule chain
• No more rules are processed if a stop() is issued
Result Object
• Rules can work on a result object’s value (rulebox.models.Result)
• Seed it with a default value
Operation Description
reset() Reset the value with the default value
getValue() Get the value
getDefaultValue() Get the default value (if any)
isPresent() Verifies the value is not null
ifPresent( consumer ) If a value is present, the consumer will be called and the value passed to it.
orElse( other ) If value is not set, then return other else the actual value
orElseGet( producer ) If value is not set, then call the producer and return its value, else return the
actual value
setValue() Set the value in the result object
setDefaultValue() Override the default value in the result object
Build a Loan Rule Engine
component extends="rulebox.models.RuleBook"{
    function defineRules(){
        addRule(
            newRule( “//credit score under 600 gets a 4x rate increase” )
            .when( function( facts ){ return facts[ "creditScore" ] < 600; } )
.then( function( facts, result ){ result.setValue( result.getValue() * 4 ); } )

.stop()
        )
        .addRule( //credit score between 600 and 700 pays a 1 point increase
            newRule()
            .when( function( facts ){ return facts[ "creditScore" ] < 700; } )
            .then( function( facts, result ){ result.setValue( result.getValue() + 1 ); } )
        )
        .addRule( //credit score is 700 and they have at least $25,000 cash on hand
            newRule()
            .when( function( facts ){
                return ( facts[ "creditScore" ] >= 700 && facts[ "cashOnHand" ] >= 25000 );
            } )
            .then( function( facts, result ){ result.setValue( result.getValue() - 0.25 ); } )
        )
        .addRule( // first time homebuyers get 20% off their rate (except if they have a creditScore < 600)
            newRule()
            .when( function( facts ){ return facts[ "firstTimeHomeBuyer" ]; } )
            .then( function( facts, result ){ result.setValue( result.getValue() * 0.80 ); } )
        );
    }
}
What’s Missing?
Execute Rules
Executing Rules
• Create the RuleBook and then we can:
• Set a result default value: withDefaultResult()
• Bind a fact: given( name, value )
• Bind multiple facts: givenAll( struct )
• Execute the rules: run( {facts} )
• Retrieve the Result object (if any): getResult()
describe( "Home Loan Rate Rules", function(){
    it( "Can calculate a first time home buyer with 20,000 down and 650 credit score", function(){
        var homeLoans = getInstance( "tests.resources.HomeLoanRateRuleBook" )
            .withDefaultResult( 4.5 )
            .given( "creditScore", 650 )
            .given( "cashOnHand", 20000 )
            .given( "firstTimeHomeBuyer", true );
        homeLoans.run();
        expect( homeLoans.getResult().isPresent() ).toBeTrue();
        expect( homeLoans.getResult().getValue() ).toBe( 4.4 );
    });
    it( "Can calculate a non first home buyer with 20,000 down and 650 credit score", function(){
        var homeLoans = getInstance( "tests.resources.HomeLoanRateRuleBook" )
            .withDefaultResult( 4.5 )
            .givenAll( {
                "creditScore" : 650,
                "cashOnHand" : 20000,
                "firstTimeHomeBuyer" : false
            } );
        homeLoans.run();
        expect( homeLoans.getResult().isPresent() ).toBeTrue();
        expect( homeLoans.getResult().getValue() ).toBe( 5.5 );
    });
});
Auditing Rules
• All rules are audited for execution
• Important to name them in a human readable form
• Else, love the UUID created for you
• Methods for status:
• getRuleStatus( ruleName ) - Get a single rule status
• getRuleStatusMap() - All rule statuses
Status Description
NONE Rule never executed (default)
SKIPPED Rule was skipped
EXECUTED Rule was executed
Still in infancy
Need your feedback
Stay true to simplicity
Focus on Functional Programming
Nested Rules
StatusVisualizer
Dynamic rules from DB/Storage
More Docs
More Samples
Roadmap
QUESTIONS?
Go Build Some Rules!!
www.ortussolutions.com
@ortussolutions

Mais conteúdo relacionado

Semelhante a RuleBox : A natural language Rule Engine

Кирилл Безпалый, .NET Developer, Ciklum
Кирилл Безпалый, .NET Developer, CiklumКирилл Безпалый, .NET Developer, Ciklum
Кирилл Безпалый, .NET Developer, Ciklum
Alina Vilk
 
fuser interface-development-using-jquery
fuser interface-development-using-jqueryfuser interface-development-using-jquery
fuser interface-development-using-jquery
Kostas Mavridis
 

Semelhante a RuleBox : A natural language Rule Engine (20)

Django Pro ORM
Django Pro ORMDjango Pro ORM
Django Pro ORM
 
Jquery Fundamentals
Jquery FundamentalsJquery Fundamentals
Jquery Fundamentals
 
JS Essence
JS EssenceJS Essence
JS Essence
 
Learn AJAX at ASIT
Learn AJAX at ASITLearn AJAX at ASIT
Learn AJAX at ASIT
 
Кирилл Безпалый, .NET Developer, Ciklum
Кирилл Безпалый, .NET Developer, CiklumКирилл Безпалый, .NET Developer, Ciklum
Кирилл Безпалый, .NET Developer, Ciklum
 
SharePoint and jQuery Essentials
SharePoint and jQuery EssentialsSharePoint and jQuery Essentials
SharePoint and jQuery Essentials
 
More on Fitnesse and Continuous Integration (Silicon Valley code camp 2012)
More on Fitnesse and Continuous Integration (Silicon Valley code camp 2012)More on Fitnesse and Continuous Integration (Silicon Valley code camp 2012)
More on Fitnesse and Continuous Integration (Silicon Valley code camp 2012)
 
EXPERTALKS: Feb 2013 - Rise of the Single Page Application
EXPERTALKS: Feb 2013 - Rise of the Single Page ApplicationEXPERTALKS: Feb 2013 - Rise of the Single Page Application
EXPERTALKS: Feb 2013 - Rise of the Single Page Application
 
ERRest - Designing a good REST service
ERRest - Designing a good REST serviceERRest - Designing a good REST service
ERRest - Designing a good REST service
 
Developer testing 101: Become a Testing Fanatic
Developer testing 101: Become a Testing FanaticDeveloper testing 101: Become a Testing Fanatic
Developer testing 101: Become a Testing Fanatic
 
Getting Started with Javascript
Getting Started with JavascriptGetting Started with Javascript
Getting Started with Javascript
 
Build Widgets
Build WidgetsBuild Widgets
Build Widgets
 
fuser interface-development-using-jquery
fuser interface-development-using-jqueryfuser interface-development-using-jquery
fuser interface-development-using-jquery
 
Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript Everywhere
 
SwampDragon presentation: The Copenhagen Django Meetup Group
SwampDragon presentation: The Copenhagen Django Meetup GroupSwampDragon presentation: The Copenhagen Django Meetup Group
SwampDragon presentation: The Copenhagen Django Meetup Group
 
Lecture 03 - JQuery.pdf
Lecture 03 - JQuery.pdfLecture 03 - JQuery.pdf
Lecture 03 - JQuery.pdf
 
Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019
 
Alternatives of JPA/Hibernate
Alternatives of JPA/HibernateAlternatives of JPA/Hibernate
Alternatives of JPA/Hibernate
 
CBStreams - Java Streams for ColdFusion (CFML)
CBStreams - Java Streams for ColdFusion (CFML)CBStreams - Java Streams for ColdFusion (CFML)
CBStreams - Java Streams for ColdFusion (CFML)
 
ITB2019 CBStreams : Accelerate your Functional Programming with the power of ...
ITB2019 CBStreams : Accelerate your Functional Programming with the power of ...ITB2019 CBStreams : Accelerate your Functional Programming with the power of ...
ITB2019 CBStreams : Accelerate your Functional Programming with the power of ...
 

Mais de Ortus Solutions, Corp

Mais de Ortus Solutions, Corp (20)

BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Ortus Government.pdf
Ortus Government.pdfOrtus Government.pdf
Ortus Government.pdf
 
Luis Majano The Battlefield ORM
Luis Majano The Battlefield ORMLuis Majano The Battlefield ORM
Luis Majano The Battlefield ORM
 
Brad Wood - CommandBox CLI
Brad Wood - CommandBox CLI Brad Wood - CommandBox CLI
Brad Wood - CommandBox CLI
 
Secure your Secrets and Settings in ColdFusion
Secure your Secrets and Settings in ColdFusionSecure your Secrets and Settings in ColdFusion
Secure your Secrets and Settings in ColdFusion
 
Daniel Garcia ContentBox: CFSummit 2023
Daniel Garcia ContentBox: CFSummit 2023Daniel Garcia ContentBox: CFSummit 2023
Daniel Garcia ContentBox: CFSummit 2023
 
ITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdf
ITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdfITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdf
ITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdf
 
ITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdf
ITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdfITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdf
ITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdf
 
ITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdf
ITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdfITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdf
ITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdf
 
ITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdf
ITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdfITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdf
ITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdf
 
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdfITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
 
ITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdf
ITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdfITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdf
ITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdf
 
ITB_2023_CBWire_v3_Grant_Copley.pdf
ITB_2023_CBWire_v3_Grant_Copley.pdfITB_2023_CBWire_v3_Grant_Copley.pdf
ITB_2023_CBWire_v3_Grant_Copley.pdf
 
ITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdf
ITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdfITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdf
ITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdf
 
ITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdf
ITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdfITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdf
ITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdf
 
ITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdf
ITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdfITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdf
ITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdf
 
ITB_2023_Chatgpt_Box_Scott_Steinbeck.pdf
ITB_2023_Chatgpt_Box_Scott_Steinbeck.pdfITB_2023_Chatgpt_Box_Scott_Steinbeck.pdf
ITB_2023_Chatgpt_Box_Scott_Steinbeck.pdf
 
ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf
ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdfITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf
ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf
 
ITB_2023_Create_as_many_web_sites_or_web_apps_as_you_want_George_Murphy.pdf
ITB_2023_Create_as_many_web_sites_or_web_apps_as_you_want_George_Murphy.pdfITB_2023_Create_as_many_web_sites_or_web_apps_as_you_want_George_Murphy.pdf
ITB_2023_Create_as_many_web_sites_or_web_apps_as_you_want_George_Murphy.pdf
 
ITB2023 Developing for Performance - Denard Springle.pdf
ITB2023 Developing for Performance - Denard Springle.pdfITB2023 Developing for Performance - Denard Springle.pdf
ITB2023 Developing for Performance - Denard Springle.pdf
 

Último

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Último (20)

Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 

RuleBox : A natural language Rule Engine

  • 1.
  • 2. RuleBox => Modern & Natural Rule Engine!
  • 3. WHO AM I? • Luis Majano • Computer Engineer • Born in El Salvador ->Texas • CEO of Ortus Solutions • Sandals -> ESRI -> Ortus @lmajano @ortussolutions
  • 4. What is RuleBox Why RuleBox was created The Problem What is a Rule Engine Why use a Rule Engine Implementation of RuleBox
  • 5. What is RuleBox • A modern and natural language rule engine • Inspired by RuleBook (Java Project) • Rules are written in the RuleBox Domain Specific Language (DSL) • Modeled after Given-When-Then • Dynamic and Expressive https://forgebox.io/view/rulebox Reference: https://github.com/rulebook-rules/rulebook install rulebox
  • 6. Why Create RuleBox • Thanks to RevAgency for inspiration: • Real world problem to handle cruise promotions • Legacy app plagued with nested if-then-else • Logic and data mixed • Much more… • Did my research: • Majority of rule engines are complex and convoluted • Nothing in ColdFusion (CFML) Landscape • Found RuleBook articles inspiring • Lots of caffeine, and RuleBox was born!
  • 8. The Problem • Ever nesting of if-then-else logic • Imperative algorithms showing how instead of what? • No Logic and Data Separation • Logic is not easily followed • Maintenance pain • How testable is that code? Has it really been tested? • The Domino Effect: Single if statement can rule them all
  • 9. What is a rule engine? • Alternative computational model to traditional imperative programming • Imperative: Sequence of commands with conditionals, loops and data • Set of rules that have a condition and an action based on data=>facts • The engine evaluates rules in the appropriate order and make sense of it • You focus on the conditions and actions and not the how you do it.
  • 10. Advantages • Functional and Declarative Programming • Speed and Scalability of development • Understandable and Named Rules • Increase Maintenance • Increase Encapsulation of Logic • Logic and Data Separation
  • 11. When?
  • 12. When… • Remember the problem • Logic and data intermixed • Maintenance is painful • Logic is brittle • The logic changes often • 500 lines of if-else statements
  • 13. How?
  • 14. How does it work?
  • 15. How does it work?
  • 16. Chain of Responsibility • RuleBox Models CoR • A RuleBook defines rules and chains them together to provider order • Facts flow to each rule (data-binding) • RuleBooks control results • Each Rule has a condition, an exception and one or more actions https://sourcemaking.com/design_patterns/chain_of_responsibility
  • 17. RuleBox Flow install rulebox Create RuleBooks Define Rules: when/then Run Rules with Given Facts Process Results
  • 18. WireBox Mappings • Rule@rulebox - A transient rule object • RuleBook@rulebox - A transient rule book object • Builder@rulebox - A static class that can be used to build a-la-carte rules and rulebooks. • Result@rulebox - RuleBooks produce results and this is the object that models such results. Similar to Java Optionals
  • 19. RuleBox DSL • Given( name, value ) - The facts • GivenAll( struct ) - Struct of facts
 • When( closure/lambda ) - The conditions • Except( closure/lambda ) - The exceptions • Then( closure/lambda ) - The actions/consumers Rules Against a RuleBook
  • 20. RuleBooks component extends="rulebox.models.RuleBook"{     function defineRules(){ setName( “My RuleBook” );         // Add a new rule to this rulebook         addRule(             newRule( "MyRule" )                 .when( function( facts ){                     return facts.keyExists( “hello” );                 } )                 .then( function( facts ){                     systemOutput( "World" );                 } )         );     } } • ATransient CFC inherits from rulebox.models.RuleBook • Can have a name property • 1 Method: defineRules() • Create rules using the DSL
  • 21. Creating Rules addRule(     newRule( “name” )     .when( function( facts ){     } )     .except( function( facts ){     } )     .then( function( facts, result ) {     } ) ) .addRule( function( rule ){     rule     .setName( ‘name’ )     .when( function( facts ){     } )     .except( function( facts ){     } )     .then( function( facts, result ) {     } ) .stop(); } ) • Using the addRule( rule ) method • Alternative Syntax, choose your comfort! • Each Rule can have the following: • Name (optional) • 1 when() • 0,1 except() • * then() • 1 stop() • Best friend:Api Docs https://apidocs.ortussolutions.com/#/coldbox-modules/rulebox/
  • 22. When() addRule(     newRule()         .when( function( facts ){             return facts.keyExists( "hello" );         })         .then( function( facts ){             sytemOutput( facts.hello );         } ) ) • The condition portion • Argument is a closure/lambda • Must evaluate to boolean • True => Executes Consumers (thens) • False => Rule does not apply, skip consumers • Receives facts as a struct
  • 23. Except() addRule(     newRule()         .when( function( facts ){             return facts.keyExists( "hello" );         }) .except( function( facts ){     return facts.accountDisabled; } )         .then( function( facts ){             sytemOutput( facts.hello );         } ) ) • Negates the when() condition • True => Skip consumers (thens) • False => Continue to consumers • Special cases and of course exceptions • Why?To not pollute the when() with negated logic
  • 24. Consumers : then() then( function( facts, result ){ sytemOutput( facts.world ); } ) then( function( facts, result ){ result.setValue( result.getValue() * 0.80 ); } ) • The actions for your logic • Closure that receives • Facts => A struct of facts • Results => A RuleBox Result object • Can have multiple actions • If the action returns true then it stops the chain of consumers • Best friend:Api Docs https://apidocs.ortussolutions.com/#/coldbox-modules/rulebox/
  • 25. Stopping Consumers .then( function( facts, result ) ){     // do stuff     // break the next then()     return true; }) .then( function( facts, result ) ){     // This never fires })
  • 26. Stopping Rules //credit score under 600 gets a 4x rate increase addRule(     newRule()     .when( function( facts ){ return facts.applicant.getCreditScore() < 600; } )     .then( function( facts, result ){ result.setValue( result.getValue() * 4 ); } )     .stop() ); • stop() on a rule • Breaks the rule chain • No more rules are processed if a stop() is issued
  • 27. Result Object • Rules can work on a result object’s value (rulebox.models.Result) • Seed it with a default value Operation Description reset() Reset the value with the default value getValue() Get the value getDefaultValue() Get the default value (if any) isPresent() Verifies the value is not null ifPresent( consumer ) If a value is present, the consumer will be called and the value passed to it. orElse( other ) If value is not set, then return other else the actual value orElseGet( producer ) If value is not set, then call the producer and return its value, else return the actual value setValue() Set the value in the result object setDefaultValue() Override the default value in the result object
  • 28. Build a Loan Rule Engine
  • 29. component extends="rulebox.models.RuleBook"{     function defineRules(){         addRule(             newRule( “//credit score under 600 gets a 4x rate increase” )             .when( function( facts ){ return facts[ "creditScore" ] < 600; } ) .then( function( facts, result ){ result.setValue( result.getValue() * 4 ); } )
 .stop()         )         .addRule( //credit score between 600 and 700 pays a 1 point increase             newRule()             .when( function( facts ){ return facts[ "creditScore" ] < 700; } )             .then( function( facts, result ){ result.setValue( result.getValue() + 1 ); } )         )         .addRule( //credit score is 700 and they have at least $25,000 cash on hand             newRule()             .when( function( facts ){                 return ( facts[ "creditScore" ] >= 700 && facts[ "cashOnHand" ] >= 25000 );             } )             .then( function( facts, result ){ result.setValue( result.getValue() - 0.25 ); } )         )         .addRule( // first time homebuyers get 20% off their rate (except if they have a creditScore < 600)             newRule()             .when( function( facts ){ return facts[ "firstTimeHomeBuyer" ]; } )             .then( function( facts, result ){ result.setValue( result.getValue() * 0.80 ); } )         );     } }
  • 31. Executing Rules • Create the RuleBook and then we can: • Set a result default value: withDefaultResult() • Bind a fact: given( name, value ) • Bind multiple facts: givenAll( struct ) • Execute the rules: run( {facts} ) • Retrieve the Result object (if any): getResult()
  • 32. describe( "Home Loan Rate Rules", function(){     it( "Can calculate a first time home buyer with 20,000 down and 650 credit score", function(){         var homeLoans = getInstance( "tests.resources.HomeLoanRateRuleBook" )             .withDefaultResult( 4.5 )             .given( "creditScore", 650 )             .given( "cashOnHand", 20000 )             .given( "firstTimeHomeBuyer", true );         homeLoans.run();         expect( homeLoans.getResult().isPresent() ).toBeTrue();         expect( homeLoans.getResult().getValue() ).toBe( 4.4 );     });     it( "Can calculate a non first home buyer with 20,000 down and 650 credit score", function(){         var homeLoans = getInstance( "tests.resources.HomeLoanRateRuleBook" )             .withDefaultResult( 4.5 )             .givenAll( {                 "creditScore" : 650,                 "cashOnHand" : 20000,                 "firstTimeHomeBuyer" : false             } );         homeLoans.run();         expect( homeLoans.getResult().isPresent() ).toBeTrue();         expect( homeLoans.getResult().getValue() ).toBe( 5.5 );     }); });
  • 33. Auditing Rules • All rules are audited for execution • Important to name them in a human readable form • Else, love the UUID created for you • Methods for status: • getRuleStatus( ruleName ) - Get a single rule status • getRuleStatusMap() - All rule statuses Status Description NONE Rule never executed (default) SKIPPED Rule was skipped EXECUTED Rule was executed
  • 34. Still in infancy Need your feedback Stay true to simplicity Focus on Functional Programming Nested Rules StatusVisualizer Dynamic rules from DB/Storage More Docs More Samples Roadmap
  • 35. QUESTIONS? Go Build Some Rules!! www.ortussolutions.com @ortussolutions