SlideShare a Scribd company logo
1 of 25
Download to read offline
Hammurabi
 A Scala rule engine




by Mario Fusco
mario.fusco@gmail.com
twitter: @mariofusco
"Any fool can write code that a
computer can understand.
Good programmers write code that
humans can understand“
                       Martin Fowler
Programming can be fun,
so can cryptography;
however they should not
be combined    d=document,l=Math.floor,g=[],r=0,z=50,i=[],v=500,y="option
               ",$=[[],[200,251,299,300,301],[0,49,50,51,99,101,150]];eva
               l('~o(e,f){f.appendChild(k=d.createElement(e));return
               k}~m(t,x,y){o(y?y:"button",x);k.appendChild(d.createTextNo
               de(t));return
               k}onload=~(){b=d.body;b.style.margin=0;x=(c=b.children[0])
               .getContext("2d");o("br",b);c.width=c.height=v;c.onclick=~
               (e){n=l(e.clientX/10)+l(e.clientY/10)*z;f(g[n],n)};c=o("se
               lect",b);m("Empty",c,y);m("Glider",c,y);m("Small
               Exploder",c,y);(c.onchange=~(){for(a=0;a<z*z;a++)f(0,a,1),
               f(1,a);for(a in
               y=$[c.selectedIndex])f(0,y[a]+1075)})();m("Play/Pause",b).
               onclick=~(){if(r++)r=0,clearTimeout(t);else
               u()};(j=m("Faster",b)).onclick=m("Slower",b).onclick=~(){v
               *=this==j?.8:1.25}};~f(b,n,w){s=w?1:2;h=w?8:6;x.fillStyle=
               (g[n]=!b)?"#000":"#fff";x.fillRect((n%z)*10+s,l(n/z)*10+s,
               h,h)}~u(){i=g.slice();for(a=0;a<z*z;a++){s=0;for(h=-
               1;h<2;h++)for(y=-
               1;y<2;y++)n=y*z+a,b=(a+h)%z,s+=(h|y)&n<z*z&0<n&b<z+h&b>=h&
               i[n+h];f(i[a]?s&6^2:s!=3,a)}t=setTimeout("u()",v)}'.replac
               e(/~/g,'function '))
What a rule-based program is
• A rule-based program is made up of discrete rules, each of
  which applies to some subset of the problem
• It is simpler, because you can concentrate on the rules for one
  situation at a time
• It can be more flexible in the face of fragmentary or poorly
  conditioned inputs
• Used for problems involving control, diagnosis, prediction,
  classification, pattern recognition … in short, all problems
  without clear algorithmic solutions


           Declarative vs. Imperative
How a rule-based system works
The golfers problem
• A foursome of golfers is standing at a tee, in a line from left to
  right. Each golfer wears different colored pants; one is
  wearing red pants.
• The golfer to Fred’s immediate right is wearing blue pants.
• Joe is second in line.
• Bob is wearing plaid pants.
• Tom isn’t in position one or four, and he isn’t wearing the
  hideous orange pants.
• In what order will the four golfers tee off, and what color are
  each golfer’s pants?”
The Jess Solution (1)

(deftemplate pants-color (slot of) (slot is))
(deftemplate position (slot of) (slot is))



(defrule generate-possibilities =>
  (foreach ?name (create$ Fred Joe Bob Tom)
    (foreach ?color (create$ red blue plaid orange)
      (assert (pants-color (of ?name)(is ?color)))
    )
    (foreach ?position (create$ 1 2 3 4)
       (assert (position (of ?name)(is ?position)))
    )
  )
)
The Jess Solution (2)
(defrule find-solution
  ;; There is a golfer named Fred, whose position is ?p1
  ;; and pants color is ?c1
  (position (of Fred) (is ?p1))          Shared variables oblige to
  (pants-color (of Fred) (is ?c1))       have one single BIG rule

[……]                                             Uniqueness of colors and
                                                 positions is spread in all rules
    ;; Bob is wearing the plaid pants
    (position (of Bob)(is ?p3&~?p1&~?p&~?p2))
    (pants-color (of Bob&~?n)(is plaid&?c3&~?c1&~?c2))

    ;; Tom is not in position 1 or 4
    ;; and is not wearing orange
    (position (of Tom&~?n)(is ?p4&~1&~4&~?p1&~?p2&~?p3))
    (pants-color (of Tom)(is ?c4&~orange&~blue&~?c1&~?c2&~?c3))
)
"Domain users shouldn't be writing
code in our DSL but it must be
designed for them to understand
and validate“
                     Debasish Ghosh
The only purpose of languages,
   even programming ones
     IS COMMUNICATION
The Hammurabi Solution (1)
                              var allPos = (1 to 4).toSet
                              var allColors =
class   Person(n: String) {     Set("blue", "plaid", "red", "orange")
  val   name = n
  var   pos: Int = _          val assign = new {
  var   color: String = _      def position(p: Int) = new {
}                                 def to(person: Person) = {
                                    person.pos = p
                                    allPos = availablePos - p
                                  }
                                }

                                  def color(c: String) = new {
                                    def to(person: Person) = {
                                      person.color = c
                                      allColors = availableColors - c
                                    }
                                  }
                              }
The Hammurabi Solution (2)
import hammurabi.Rule._

val ruleSet = Set(
  rule ("Unique positions") let {
     val p = any(kindOf[Person])
     when {
       (availablePos.size equals 1) and (p.pos equals 0)
     } then {
       assign position availablePos.head to p
     }
  },
[……]
  rule ("Person to Fred’s immediate right is wearing blue pants") let {
     val p1 = any(kindOf[Person])
     val p2 = any(kindOf[Person])
     when {
       (p1.name equals "Fred") and (p2.pos equals p1.pos + 1)
     } then {
       assign color "blue" to p2
     }
  }
)
The Hammurabi Solution (3)
val   tom = new Person("Tom")
val   joe = new Person("Joe")
val   fred = new Person("Fred")
val   bob = new Person("Bob")

val workingMemory = WorkingMemory(tom, joe, fred, bob)

RuleEngine(ruleSet) execOn workingMemory

val allPersons = workingMemory.all(classOf[Person])

val tom = workingMemory.firstHaving[Person](_.name == "Tom").get
Why an internal DSL?
I am lazy
 o I didn't want to implement a parser
 o I wanted the Scala compiler to syntactically validate the rules

I wanted Hammurabi's users to be lazier than me
 o No need to learn a new language: it's plain Scala
 o Leverage all the goodies of your favorite IDE like:
   autocompletion, syntax highligthing, …



   Scala allows all of us to stay lazy and have a very
     readable and flexible DSL at the same time
Working with immutable objects
case class Person(name: String, pos: Int = 0, color: String = null)

val assign = new {
  def color(color: String) = new {
    def to(person: Person) = {
      remove(person)
      produce(person.copy(color = color))
      availableColors = availableColors - color
    }
  }
  def position(pos: Int) = new {
    def to(person: Person) = {
      remove(person)
      produce(person.copy(pos = pos))
      availablePos = availablePos - pos
    }
  }
}
Exiting with a result
rule("Person to Joe’s immediate right is wearing blue pants") let {
  val p1 = any(kindOf[Person])
  val p2 = any(kindOf[Person])
  when {
    (p1.name equals "Joe") and (p2.pos equals p1.pos + 1)
  } then {
    p2.color = "blue“
    exitWith(p2)
  }
}

val result = RuleEngine(ruleSet).execOn(workingMemory).get
Making evaluation fail

rule ("Unique positions") let {
  val p = any(kindOf[Person])
  when {
    (availablePos.size equals 0) and (p.pos equals 0)
  } then {
    failWith("No more positions available for " + p.name)
  }
}
Changing rule's priority
Sometimes you may find that a particular rule should be
treated as a special case

A rule that reports a security breach might need to fire immediately …

      rule ("Important rule") withSalience 10 let { ... }


… and on the other hand, a rule that cleans up unused facts might
only need to run during the idle time

      rule ("Negligible rule") withSalience -5 let { ... }
Selecting with Boolean functions

rule ("Person to Fred’s immediate right is wearing blue pants") let {
   val p1 = any(kindOf[Person])
            kindOf[Person] having (_.name == "Fred")
   val p2 = any(kindOf[Person])
   when {
     (p1.name equals "Fred") 1and (p2.pos equals p1.pos + 1)
     p2.pos equals p1.pos +
   } then {
     assign color "blue" to p2
   }
 }
Hammurabi internals
                       Evaluate
    Rule Engine                         Rule Evaluator
                   EvaluationFinished   (Actor)
     RuleSet                                    Rule1

S                       Working
a     Agenda            Memory
l   RuleExecutor                        Rule Evaluator
i                      Evaluate         (Actor)
    RuleExecutor
e                                               Rule2
n   RuleExecutor   EvaluationFinished
c
e   RuleExecutor

                       Evaluate         Rule Evaluator
                                        (Actor)
                   EvaluationFinished           Rule3
How Hammurabi DSL works (1)
case class Rule(description: String,
                bind: () => RuleDefinition[_], salience: Int = 0)

case class RuleDefinition[A](condition: () => Boolean,
                             execution: () => A)

def rule(description: String) = new {
  def let(letClause: => RuleDefinition[_]): Rule =
    Rule(description, letClause _)

    def withSalience(salience: Int) = new {
      def let(letClause: => RuleDefinition[_]): Rule =
        Rule(description, letClause _, salience)
    }
}

rule ("An extremly useful rule") withSalience 5 let {
  ...
}
How Hammurabi DSL works (2)
def when(condition: => Boolean) = new {
  def then[A](execution: => A): RuleDefinition =
    RuleDefinition(condition _, execution _)
}

rule("Joe is in position 2") let {
  val p = any(kindOf[Person])
  when {
    p.name equals "Joe"
  } then {
    assign position 2 to p
  }
}

def ruleExecution() = {
  val ruleDef = rule.bind()
  if (ruleDef.condition()) ruleDef.execution()
}
Future enhancements
 Evaluate use of Scala 2.9 parallel collections instead of actors

 Improve performances by implementing the RETE algorithm

 Provide alternative way to select objects from the working
 memory. For example:
 produce(person) as 'VIP

 rule ("only for Very Important Persons") let {
   val vip = any('VIP)
   ...
 }


Any feedback or suggestion is welcome!
Questions?


 Don’t forget to check out Hammurabi at:
http://hammurabi.googlecode.com

               Thank you!
Mario Fusco
mario.fusco@gmail.com
twitter: @mariofusco

More Related Content

What's hot

FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
Mario Fusco
 
Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)
stasimus
 

What's hot (20)

FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
 
Sneaking inside Kotlin features
Sneaking inside Kotlin featuresSneaking inside Kotlin features
Sneaking inside Kotlin features
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New Game
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
 
Testing in the World of Functional Programming
Testing in the World of Functional ProgrammingTesting in the World of Functional Programming
Testing in the World of Functional Programming
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka Actors
 
Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)
 
Python легко и просто. Красиво решаем повседневные задачи
Python легко и просто. Красиво решаем повседневные задачиPython легко и просто. Красиво решаем повседневные задачи
Python легко и просто. Красиво решаем повседневные задачи
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
 
Grammarware Memes
Grammarware MemesGrammarware Memes
Grammarware Memes
 
Kotlin collections
Kotlin collectionsKotlin collections
Kotlin collections
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And Monad
 
Kotlin, why?
Kotlin, why?Kotlin, why?
Kotlin, why?
 
Scala best practices
Scala best practicesScala best practices
Scala best practices
 
Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class Patterns
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
 
Humble introduction to category theory in haskell
Humble introduction to category theory in haskellHumble introduction to category theory in haskell
Humble introduction to category theory in haskell
 
What's New In C# 7
What's New In C# 7What's New In C# 7
What's New In C# 7
 

Viewers also liked

If You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongIf You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are Wrong
Mario Fusco
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Mario Fusco
 
Why we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingWhy we cannot ignore Functional Programming
Why we cannot ignore Functional Programming
Mario Fusco
 
Real world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same languageReal world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same language
Mario Fusco
 
Swiss army knife Spring
Swiss army knife SpringSwiss army knife Spring
Swiss army knife Spring
Mario Fusco
 

Viewers also liked (20)

If You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongIf You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are Wrong
 
OOP and FP - Become a Better Programmer
OOP and FP - Become a Better ProgrammerOOP and FP - Become a Better Programmer
OOP and FP - Become a Better Programmer
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
 
Monadic Java
Monadic JavaMonadic Java
Monadic Java
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
Why we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingWhy we cannot ignore Functional Programming
Why we cannot ignore Functional Programming
 
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...
 
Comparing different concurrency models on the JVM
Comparing different concurrency models on the JVMComparing different concurrency models on the JVM
Comparing different concurrency models on the JVM
 
Real world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same languageReal world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same language
 
Drools 6 deep dive
Drools 6 deep diveDrools 6 deep dive
Drools 6 deep dive
 
Writing DSL in Clojure
Writing DSL in ClojureWriting DSL in Clojure
Writing DSL in Clojure
 
Seven Deadly Sins
Seven Deadly Sins Seven Deadly Sins
Seven Deadly Sins
 
Swiss army knife Spring
Swiss army knife SpringSwiss army knife Spring
Swiss army knife Spring
 
Maven c'est bien, SBT c'est mieux
Maven c'est bien, SBT c'est mieuxMaven c'est bien, SBT c'est mieux
Maven c'est bien, SBT c'est mieux
 
Universitélang scala tools
Universitélang scala toolsUniversitélang scala tools
Universitélang scala tools
 
Les monades Scala, Java 8
Les monades Scala, Java 8Les monades Scala, Java 8
Les monades Scala, Java 8
 
Université des langages scala
Université des langages   scalaUniversité des langages   scala
Université des langages scala
 
Scala Intro
Scala IntroScala Intro
Scala Intro
 
Lagom, reactive framework
Lagom, reactive frameworkLagom, reactive framework
Lagom, reactive framework
 

Similar to Hammurabi

import os import matplotlib-pyplot as plt import pandas as pd import r.docx
import os import matplotlib-pyplot as plt import pandas as pd import r.docximport os import matplotlib-pyplot as plt import pandas as pd import r.docx
import os import matplotlib-pyplot as plt import pandas as pd import r.docx
Blake0FxCampbelld
 
Clojure for Java developers - Stockholm
Clojure for Java developers - StockholmClojure for Java developers - Stockholm
Clojure for Java developers - Stockholm
Jan Kronquist
 
The groovy puzzlers (as Presented at JavaOne 2014)
The groovy puzzlers (as Presented at JavaOne 2014)The groovy puzzlers (as Presented at JavaOne 2014)
The groovy puzzlers (as Presented at JavaOne 2014)
GroovyPuzzlers
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Code
stasimus
 

Similar to Hammurabi (20)

Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014
 
groovy & grails - lecture 3
groovy & grails - lecture 3groovy & grails - lecture 3
groovy & grails - lecture 3
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
Are we ready to Go?
Are we ready to Go?Are we ready to Go?
Are we ready to Go?
 
Scala: the language of languages - Mario Fusco (Red Hat)
Scala: the language of languages - Mario Fusco (Red Hat)Scala: the language of languages - Mario Fusco (Red Hat)
Scala: the language of languages - Mario Fusco (Red Hat)
 
A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
 
Start Writing Groovy
Start Writing GroovyStart Writing Groovy
Start Writing Groovy
 
GE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python ProgrammingGE8151 Problem Solving and Python Programming
GE8151 Problem Solving and Python Programming
 
Go ahead, make my day
Go ahead, make my dayGo ahead, make my day
Go ahead, make my day
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlin
 
Scala in a Java 8 World
Scala in a Java 8 WorldScala in a Java 8 World
Scala in a Java 8 World
 
An Introduction to Scala (2014)
An Introduction to Scala (2014)An Introduction to Scala (2014)
An Introduction to Scala (2014)
 
import os import matplotlib-pyplot as plt import pandas as pd import r.docx
import os import matplotlib-pyplot as plt import pandas as pd import r.docximport os import matplotlib-pyplot as plt import pandas as pd import r.docx
import os import matplotlib-pyplot as plt import pandas as pd import r.docx
 
여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language
 
Clojure for Java developers - Stockholm
Clojure for Java developers - StockholmClojure for Java developers - Stockholm
Clojure for Java developers - Stockholm
 
Lập trình Python cơ bản
Lập trình Python cơ bảnLập trình Python cơ bản
Lập trình Python cơ bản
 
The groovy puzzlers (as Presented at JavaOne 2014)
The groovy puzzlers (as Presented at JavaOne 2014)The groovy puzzlers (as Presented at JavaOne 2014)
The groovy puzzlers (as Presented at JavaOne 2014)
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Code
 
Functional JS for everyone - 4Developers
Functional JS for everyone - 4DevelopersFunctional JS for everyone - 4Developers
Functional JS for everyone - 4Developers
 

More from Mario Fusco

Introducing Drools
Introducing DroolsIntroducing Drools
Introducing Drools
Mario Fusco
 
No more loops with lambdaj
No more loops with lambdajNo more loops with lambdaj
No more loops with lambdaj
Mario Fusco
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Mario Fusco
 

More from Mario Fusco (8)

Kogito: cloud native business automation
Kogito: cloud native business automationKogito: cloud native business automation
Kogito: cloud native business automation
 
Let's make a contract: the art of designing a Java API
Let's make a contract: the art of designing a Java APILet's make a contract: the art of designing a Java API
Let's make a contract: the art of designing a Java API
 
How and why I turned my old Java projects into a first-class serverless compo...
How and why I turned my old Java projects into a first-class serverless compo...How and why I turned my old Java projects into a first-class serverless compo...
How and why I turned my old Java projects into a first-class serverless compo...
 
OOP and FP
OOP and FPOOP and FP
OOP and FP
 
Lazy java
Lazy javaLazy java
Lazy java
 
Introducing Drools
Introducing DroolsIntroducing Drools
Introducing Drools
 
No more loops with lambdaj
No more loops with lambdajNo more loops with lambdaj
No more loops with lambdaj
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
 

Recently uploaded

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
 

Recently uploaded (20)

Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
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
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
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 New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
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
 
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...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
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
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 

Hammurabi

  • 1. Hammurabi A Scala rule engine by Mario Fusco mario.fusco@gmail.com twitter: @mariofusco
  • 2. "Any fool can write code that a computer can understand. Good programmers write code that humans can understand“ Martin Fowler
  • 3. Programming can be fun, so can cryptography; however they should not be combined d=document,l=Math.floor,g=[],r=0,z=50,i=[],v=500,y="option ",$=[[],[200,251,299,300,301],[0,49,50,51,99,101,150]];eva l('~o(e,f){f.appendChild(k=d.createElement(e));return k}~m(t,x,y){o(y?y:"button",x);k.appendChild(d.createTextNo de(t));return k}onload=~(){b=d.body;b.style.margin=0;x=(c=b.children[0]) .getContext("2d");o("br",b);c.width=c.height=v;c.onclick=~ (e){n=l(e.clientX/10)+l(e.clientY/10)*z;f(g[n],n)};c=o("se lect",b);m("Empty",c,y);m("Glider",c,y);m("Small Exploder",c,y);(c.onchange=~(){for(a=0;a<z*z;a++)f(0,a,1), f(1,a);for(a in y=$[c.selectedIndex])f(0,y[a]+1075)})();m("Play/Pause",b). onclick=~(){if(r++)r=0,clearTimeout(t);else u()};(j=m("Faster",b)).onclick=m("Slower",b).onclick=~(){v *=this==j?.8:1.25}};~f(b,n,w){s=w?1:2;h=w?8:6;x.fillStyle= (g[n]=!b)?"#000":"#fff";x.fillRect((n%z)*10+s,l(n/z)*10+s, h,h)}~u(){i=g.slice();for(a=0;a<z*z;a++){s=0;for(h=- 1;h<2;h++)for(y=- 1;y<2;y++)n=y*z+a,b=(a+h)%z,s+=(h|y)&n<z*z&0<n&b<z+h&b>=h& i[n+h];f(i[a]?s&6^2:s!=3,a)}t=setTimeout("u()",v)}'.replac e(/~/g,'function '))
  • 4. What a rule-based program is • A rule-based program is made up of discrete rules, each of which applies to some subset of the problem • It is simpler, because you can concentrate on the rules for one situation at a time • It can be more flexible in the face of fragmentary or poorly conditioned inputs • Used for problems involving control, diagnosis, prediction, classification, pattern recognition … in short, all problems without clear algorithmic solutions Declarative vs. Imperative
  • 5. How a rule-based system works
  • 6. The golfers problem • A foursome of golfers is standing at a tee, in a line from left to right. Each golfer wears different colored pants; one is wearing red pants. • The golfer to Fred’s immediate right is wearing blue pants. • Joe is second in line. • Bob is wearing plaid pants. • Tom isn’t in position one or four, and he isn’t wearing the hideous orange pants. • In what order will the four golfers tee off, and what color are each golfer’s pants?”
  • 7. The Jess Solution (1) (deftemplate pants-color (slot of) (slot is)) (deftemplate position (slot of) (slot is)) (defrule generate-possibilities => (foreach ?name (create$ Fred Joe Bob Tom) (foreach ?color (create$ red blue plaid orange) (assert (pants-color (of ?name)(is ?color))) ) (foreach ?position (create$ 1 2 3 4) (assert (position (of ?name)(is ?position))) ) ) )
  • 8. The Jess Solution (2) (defrule find-solution ;; There is a golfer named Fred, whose position is ?p1 ;; and pants color is ?c1 (position (of Fred) (is ?p1)) Shared variables oblige to (pants-color (of Fred) (is ?c1)) have one single BIG rule [……] Uniqueness of colors and positions is spread in all rules ;; Bob is wearing the plaid pants (position (of Bob)(is ?p3&~?p1&~?p&~?p2)) (pants-color (of Bob&~?n)(is plaid&?c3&~?c1&~?c2)) ;; Tom is not in position 1 or 4 ;; and is not wearing orange (position (of Tom&~?n)(is ?p4&~1&~4&~?p1&~?p2&~?p3)) (pants-color (of Tom)(is ?c4&~orange&~blue&~?c1&~?c2&~?c3)) )
  • 9. "Domain users shouldn't be writing code in our DSL but it must be designed for them to understand and validate“ Debasish Ghosh
  • 10. The only purpose of languages, even programming ones IS COMMUNICATION
  • 11.
  • 12. The Hammurabi Solution (1) var allPos = (1 to 4).toSet var allColors = class Person(n: String) { Set("blue", "plaid", "red", "orange") val name = n var pos: Int = _ val assign = new { var color: String = _ def position(p: Int) = new { } def to(person: Person) = { person.pos = p allPos = availablePos - p } } def color(c: String) = new { def to(person: Person) = { person.color = c allColors = availableColors - c } } }
  • 13. The Hammurabi Solution (2) import hammurabi.Rule._ val ruleSet = Set( rule ("Unique positions") let { val p = any(kindOf[Person]) when { (availablePos.size equals 1) and (p.pos equals 0) } then { assign position availablePos.head to p } }, [……] rule ("Person to Fred’s immediate right is wearing blue pants") let { val p1 = any(kindOf[Person]) val p2 = any(kindOf[Person]) when { (p1.name equals "Fred") and (p2.pos equals p1.pos + 1) } then { assign color "blue" to p2 } } )
  • 14. The Hammurabi Solution (3) val tom = new Person("Tom") val joe = new Person("Joe") val fred = new Person("Fred") val bob = new Person("Bob") val workingMemory = WorkingMemory(tom, joe, fred, bob) RuleEngine(ruleSet) execOn workingMemory val allPersons = workingMemory.all(classOf[Person]) val tom = workingMemory.firstHaving[Person](_.name == "Tom").get
  • 15. Why an internal DSL? I am lazy o I didn't want to implement a parser o I wanted the Scala compiler to syntactically validate the rules I wanted Hammurabi's users to be lazier than me o No need to learn a new language: it's plain Scala o Leverage all the goodies of your favorite IDE like: autocompletion, syntax highligthing, … Scala allows all of us to stay lazy and have a very readable and flexible DSL at the same time
  • 16. Working with immutable objects case class Person(name: String, pos: Int = 0, color: String = null) val assign = new { def color(color: String) = new { def to(person: Person) = { remove(person) produce(person.copy(color = color)) availableColors = availableColors - color } } def position(pos: Int) = new { def to(person: Person) = { remove(person) produce(person.copy(pos = pos)) availablePos = availablePos - pos } } }
  • 17. Exiting with a result rule("Person to Joe’s immediate right is wearing blue pants") let { val p1 = any(kindOf[Person]) val p2 = any(kindOf[Person]) when { (p1.name equals "Joe") and (p2.pos equals p1.pos + 1) } then { p2.color = "blue“ exitWith(p2) } } val result = RuleEngine(ruleSet).execOn(workingMemory).get
  • 18. Making evaluation fail rule ("Unique positions") let { val p = any(kindOf[Person]) when { (availablePos.size equals 0) and (p.pos equals 0) } then { failWith("No more positions available for " + p.name) } }
  • 19. Changing rule's priority Sometimes you may find that a particular rule should be treated as a special case A rule that reports a security breach might need to fire immediately … rule ("Important rule") withSalience 10 let { ... } … and on the other hand, a rule that cleans up unused facts might only need to run during the idle time rule ("Negligible rule") withSalience -5 let { ... }
  • 20. Selecting with Boolean functions rule ("Person to Fred’s immediate right is wearing blue pants") let { val p1 = any(kindOf[Person]) kindOf[Person] having (_.name == "Fred") val p2 = any(kindOf[Person]) when { (p1.name equals "Fred") 1and (p2.pos equals p1.pos + 1) p2.pos equals p1.pos + } then { assign color "blue" to p2 } }
  • 21. Hammurabi internals Evaluate Rule Engine Rule Evaluator EvaluationFinished (Actor) RuleSet Rule1 S Working a Agenda Memory l RuleExecutor Rule Evaluator i Evaluate (Actor) RuleExecutor e Rule2 n RuleExecutor EvaluationFinished c e RuleExecutor Evaluate Rule Evaluator (Actor) EvaluationFinished Rule3
  • 22. How Hammurabi DSL works (1) case class Rule(description: String, bind: () => RuleDefinition[_], salience: Int = 0) case class RuleDefinition[A](condition: () => Boolean, execution: () => A) def rule(description: String) = new { def let(letClause: => RuleDefinition[_]): Rule = Rule(description, letClause _) def withSalience(salience: Int) = new { def let(letClause: => RuleDefinition[_]): Rule = Rule(description, letClause _, salience) } } rule ("An extremly useful rule") withSalience 5 let { ... }
  • 23. How Hammurabi DSL works (2) def when(condition: => Boolean) = new { def then[A](execution: => A): RuleDefinition = RuleDefinition(condition _, execution _) } rule("Joe is in position 2") let { val p = any(kindOf[Person]) when { p.name equals "Joe" } then { assign position 2 to p } } def ruleExecution() = { val ruleDef = rule.bind() if (ruleDef.condition()) ruleDef.execution() }
  • 24. Future enhancements Evaluate use of Scala 2.9 parallel collections instead of actors Improve performances by implementing the RETE algorithm Provide alternative way to select objects from the working memory. For example: produce(person) as 'VIP rule ("only for Very Important Persons") let { val vip = any('VIP) ... } Any feedback or suggestion is welcome!
  • 25. Questions? Don’t forget to check out Hammurabi at: http://hammurabi.googlecode.com Thank you! Mario Fusco mario.fusco@gmail.com twitter: @mariofusco