Developing applications with rules, workflow and event processing (it@cork 2010)
●
The SkyNet funding bill is passed.
●
The system goes online on August 4th, 1997.
●
Human decisions are removed from strategic defense.
●
SkyNet begins to learn at a geometric rate.
●
It becomes self-aware at 2:14am Eastern time, August
29th
●
In a panic, they try to pull the plug.
●
And, Skynet fights back
Mark Proctor
Co-Creator
Project Lead
2
Topics
Books
Community
History
Unified Concept
Declarative Domain Overview
● Declarative Programming
● Domain Overview
● The Future
Expert
● Quick Example
● Conditional Elements
● Truth Maintenance and Inference
Fusion
Decision Tables
Guvnor
What's new in 5.1
3
Books
Introduction to Expert Systems
● Peter Jackson
Expert Systems, Principles and Programming
● Joseph C. Giarratano and Gary D. Riley
9
Sample Industries and Users
Investment
● Millennium Investment Group (MIG)
Logistics
● Fedex
Airline
● Sabre
Mortgage
● Franklin American
Healthcare
● OSDE
10
Boot Camps
San Francisco 2009 (40+ attendees)
● Sponsored by Third Pillar
● Sun, FAMC, OSDE, Kaseya, Fedex, TU Group, Intermountain
Healthcare, Gap, Sony Pictures, Lockheed Martin, Kaiser, HP,
Wells Fargo, US Navy Research, FOLIOfn, Boeing .....
San Diego 2010 (80+ attendess)
● Sponsored by US Navy
● 5 day event, with 2 days focus on the healthcare industry
● OSDE, AT&T, SAIC, US Navy Research, Kaiser, Clinica,
Intermountain Healthcare, GE Healthcare, VA, Boeing,
Nationwide ....
13
It All Started Here
Birth of CDSS
Dendral
Baobab
Mycin
Guidon
Neomycin
Teiresias
Puff
Emycin
WM
Sacon
Centaur
Wheeze
Gravida
Clot
Oncocin
1970s
1980s
31
Self monitoring and adaptive
declare ProcessStartedEvent
@role( event )
end
rule "Number of process instances above threshold" when
Number( nbProcesses : intValue > 1000 )
from accumulate(
e: ProcessStartedEvent(
processInstance.processId == "com.sample.order.OrderProcess" )
over window:size(1h),
count(e) )
then
System.err.println( "WARNING: Nb of order processes in the last
hour > 1000: " + nbProcesses );
end
41
The Future
Full Hybrid Engine
● http://community.jboss.org/wiki/DroolsLanguageEnhancements
●Nested Objects
●Casting Nested Objects
●Positional Constraints
●POSL - Positional-Slotted
Language
●Method Calls
●Maps and Arrays
(Collections)
●Collections and XPath like
filtering
●Free form Expressions
●Managed Object Graphs
(MOGS)
●Nested Patterns and Queries
●Queries and Unification
●Ontologies and Relations via
●Query Based Backward
Chaining with POSL
●Triples with Hybrid POJO Graph
Notation.
●Escapes for Dialects
●Accumulate Improvements to
Support Haskell map/fold/filter
and MVEL projection/fold
● Otherwise
● Branch (Labelled Else)
● Rule Execution Groups
● Rule Dependency Meta-Rule
Language
●Parallel Meta-Rule Language
● Field Versioning
●Logical Closures/OnFalse
●Opportunistic Backward
Chaining, Lazy Field/Object
Values
●...
43
Definitions
public class Applicant {
private String name;
private int age;
private boolean valid;
// getter and setter methods here
}
rule "Is of valid age" when
$a : Applicant( age < 18 )
then
modify( $a ) { valid = false };
ends
47
Definitions
public class Room {
private String name
// getter and setter methods here
}
public class Sprinkler {
private Room room;
private boolean on;
// getter and setter methods here
}
public class Fire {
private Room room;
// getter and setter methods here
}
public class Alarm {
}
48
Definitions
rule "When there is a fire turn on the sprinkler" when
Fire($room : room)
$sprinkler : Sprinkler( room == $room, on == false )
then
modify( $sprinkler ) { on = true };
println( "Turn on the sprinkler for room " + $room.name );
end
rule "When the fire is gone turn off the sprinkler" when
$room : Room( )
$sprinkler : Sprinkler( room == $room, on == true )
not Fire( room == $room )
then
modify( $sprinkler ) { on = false };
println( "Turn off the sprinkler for room " + $room.name );
end
49
Definitions
rule "Raise the alarm when we have one or more fires" when
exists Fire()
then
insert( new Alarm() );
println( "Raise the alarm" );
end
rule "Cancel the alarm when all the fires have gone" when
not Fire()
$alarm : Alarm()
then
retract( $alarm );
println( "Cancel the alarm" );
end
51
Executing
String[] names = new String[]{"kitchen", "bedroom", "office", "livingroom"};
Map<String,Room> name2room = new HashMap<String,Room>();
for( String name: names ){
Room room = new Room( name );
name2room.put( name, room );
ksession.insert( room );
Sprinkler sprinkler = new Sprinkler( room );
ksession.insert( sprinkler );
}
ksession.fireAllRules()
> Everything is ok
52
Executing
Fire kitchenFire = new Fire( name2room.get( "kitchen" ) );
Fire officeFire = new Fire( name2room.get( "office" ) );
FactHandle kitchenFireHandle = ksession.insert( kitchenFire );
FactHandle officeFireHandle = ksession.insert( officeFire );
ksession.fireAllRules();
> Raise the alarm
> Turn on the sprinkler for room kitchen
> Turn on the sprinkler for room office
53
Executing
ksession.retract( kitchenFireHandle );
ksession.retract( officeFireHandle );
ksession.fireAllRules()
> Turn off the sprinkler for room office
> Turn off the sprinkler for room kitchen
> Cancel the alarm
> Everything is ok
rule "Status output when things are ok" when
not Alarm()
not Sprinkler( on == true )
then
println( "Everything is ok" );
end
57
Accumulate CE
Patterns and CE's can be chained with 'from'
rule "collect"
when
$zipCode : ZipCode()
$sum : Number( intValue > 100 )
from accumulate( Bus( color == "red", $t : takings )
from $hbn.getNamedQuery(“Find Buses”)
.setParameters( [ “zipCode” :
$zipCode ] )
.list(),
sum( $t ) )
then
print "sum is “ + $sum;
end
59
Timers
rule “name”
timer 1m30s
when
$l : Light( status == “on” )
then
modify( $l ) { status = “off” };
rule “name”
timer (int: 1m30s 0)
when
$l : Light( status == “on” )
then
modify( $l ) { status = “off” };
When the light is on, and has been
on for 1m30s then turn it off
Same as above. Interval timer with
JDK semantics for initial duration,
then repeat duration.
60
Timers
rule “name”
timer ( cron: 0 0/15 * * * * )
when
Alarm( )
then
sendEmail( ”Alert Alert Alert!!!” )
Field Name Mandatory? Allowed Values Allowed Special Characters
Seconds YES 0-59 , - * /
Minutes YES 0-59 , - * /
Hours YES 0-23 , - * /
Day of month YES 1-31 , - * ? / L W
Month YES 1-12 or JAN-DEC , - * /
Day of week YES 1-7 or SUN-SAT , - * ? / L #
Year NO empty, 1970-2099 , - * /
Send alert every quarter of an hour
61
Calendars
rule "weekdays are high priority"
calendars "weekday"
timer (int:0 1h)
when
Alarm()
then
send( "priority high - we have an alarm” );
end
rule "weekend are low priority"
calendars "weekend"
timer (int:0 4h)
when
Alarm()
then
send( "priority low - we have an alarm” );
end
Execute now and after
1 hour duration
Execute now and after
4 hour duration
63
D a te d a te
d o u b le a m o u n t
in t ty p e
lo n g a c c o u n tN o
C a s h flo w
lo n g a c c o u n tN o
d o u b le b a la n c e
A c c o u n t
D a te s ta r t
D a te e n d
A c c o u n tin g P e r io d
Classes
64
Account
accountNo balance
1 0
increase balance for AccountPeriod Credits
select * from Account acc,
Cashflow cf, AccountPeriod ap
where acc.accountNo == cf.accountNo and
cf.type == CREDIT
cf.date >= ap.start and
cf.date <= ap.end
decrease balance for AccountPeriod Debits
select * from Account acc,
Cashflow cf, AccountPeriod ap
where acc.accountNo == cf.accountNo and
cf.type == DEBIT
cf.date >= ap.start and
cf.date <= ap.end
AccountingPeriod
start end
01-Jan-07 31-Mar-07
trigger : acc.balance += cf.amount trigger : acc.balance -= cf.amount
Account
accountNo balance
1 -25
Creating Views with Triggers
date amount type
12-Jan-07 100 CREDIT 1
2-Feb-07 200 DEBIT 1
18-May-07 50 CREDIT 1
9-Mar-07 75 CREDIT 1
CashFlow
accountNo
CashFlow
date amount type
12-Jan-07 100 CREDIT
9-Mar-07 75 CREDIT
CashFlow
date amount type
2-Feb-07 200 DEBIT
65
rule “increase balance for AccountPeriod Credits”
when
ap : AccountPeriod()
acc : Account( $accountNo : accountNo )
CashFlow( type == CREDIT,
accountNo == $accountNo,
date >= ap.start && <= ap.end,
$ammount : ammount )
then
acc.balance += $amount;
end
select * from Account acc,
Cashflow cf, AccountPeriod ap
where acc.accountNo == cf.accountNo and
cf.type == CREDIT
cf.date >= ap.start and
cf.date <= ap.end
trigger : acc.balance += cf.amount
Bringing it Together
66
rule “increase balance for AccountPeriod
Credits”
when
ap : AccountPeriod()
acc : Account( $accountNo : accountNo )
CashFlow( type == CREDIT,
accountNo == $accountNo,
date >= ap.start && <= ap.end,
$ammount : ammount )
then
acc.balance += $amount;
end
rule “decrease balance for AccountPeriod
Debits”
when
ap : AccountPeriod()
acc : Account( $accountNo : accountNo )
CashFlow( type == DEBIT,
accountNo == $accountNo,
date >= ap.start && <= ap.end,
$ammount : ammount )
then
acc.balance -= $amount;
end
Rules as a “view”
date amount type
12-Jan-07 100 CREDIT 1
2-Feb-07 200 DEBIT 1
18-May-07 50 CREDIT 1
9-Mar-07 75 CREDIT 1
CashFlow
accountNo
CashFlow
date amount type
12-Jan-07 100 CREDIT
9-Mar-07 75 CREDIT
CashFlow
date amount type
2-Feb-07 200 DEBIT
AccountingPeriod
start end
01-Jan-07 31-Mar-07
Account
accountNo balance
1 0
Account
accountNo balance
1 -25
68
TMS and Inference
rule "Issue Child Bus Pass"
when
$p : Person( age < 16 )
then
insert(new ChildBusPass( $p ) );
end
rule "Issue Adult Bus Pass"
when
$p : Person( age >= 16 )
then
insert(new AdultBusPass( $p ) );
end
Couples the logic
What happens when the Child
stops being 16?
70
TMS and Inference
A rule “logically” inserts an object
When the rule is no longer true, the object is retracted.
when
$p : Person( age < 16 )
then
logicalInsert( new IsChild( $p ) )
end
when
$p : Person( age >= 16 )
then
logicalInsert( new IsAdult( $p ) )
end
de-couples the logic
Maintains the truth by
automatically retracting
71
TMS and Inference
rule "Issue Child Bus Pass"
when
$p : Person( )
IsChild( person =$p )
then
logicalInsert(new ChildBusPass( $p ) );
end
rule "Issue Adult Bus Pass"
when
$p : Person( age >= 16 )
IsAdult( person =$p )
then
logicalInsert(new AdultBusPass( $p ) );
end
The truth maintenance cascades
72
TMS and Inference
rule "Issue Child Bus Pass"
when
$p : Person( )
not( ChildBusPass( person == $p ) )
then
requestChildBusPass( $p );
end The truth maintenance cascades
73
TMS and Inference
Good
● De-couple knowledge responsibilities
● Encapsulate knowledge
● Provide semantic abstractions for those encapsulation
● Integrity robustness – truth maintenance
79
Drools Fusion: Enables...
Event Detection:
● From an event cloud or set of streams, select all the
meaningful events, and only them.
[Temporal] Event Correlation:
● Ability to correlate events and facts declaring both temporal
and non-temporal constraints between them.
● Ability to reason over event aggregation.
Event Sequencing:
● A → ( B OR C ) → D
Event Abstraction:
● Ability to compose complex events from atomic events AND
reason over them
80
Drools Fusion: Features
Support to Event semantics:
● Usually immutable, but not enforced
● Strong temporal relationships
● Managed lifecycle
● Point-in-time and Interval events
Time semantics
● Discrete
Temporal relationships
● All 13 operators defined by James Allen (+ negations)
81
Drools Fusion: Temporal Reasoning
P o i n t - P o i n t P o i n t - I n t e r v a l I n t e r v a l - I n t e r v a l
A b e f o r e B
A m e e t s B
A o v e r la p s B
A f in is h e s B
A in c lu d e s B
A s t a r t s B
A c o in c id e s B
A
B
A
B
A
B
A
B
A
B
A
B
A
B
82
Drools Fusion: Temporal Reasoning
P o i n t - P o i n t P o i n t - I n t e r v a l I n t e r v a l - I n t e r v a l
A a f t e r B
A m e t B y B
A o v e r la p e d B y B
A f in is h e d B y B
A d u r in g B
A f in is h e s B
A
B
A
B
A
B
A
B
A
B
A
B
83
$c : Custumer( type == “VIP )
$oe : BuyOrderEvent( customer == $c )
from entry-point “Home Broker Stream”
not BuyAckEvent( relatedEvent == $oe.id, this after[1s, 10s] $oe )
from entry-point “Stock Trader Stream”
Operators
Existing Drools 'not'
Conditional Elements can
be used to detect non-
occurrence of events
BackAckEvent must occur
between 1s and 10s 'after'
BuyOrderEvent
84
Aggregations
Rule Engines do not deal with aggregations
$n : Number( intValue > 100 )
from accumulate( $s : StockTicker( symbol == “RHAT” ) over window:time( 5s ),
average( $s.price ) )
Over 5 seconds
Aggregate ticker price
for RHAT over last 5
seconds
The pattern 'Number'
reasons 'from' the
accumulate result
100
Questions?Questions?
• Dave Bowman: All right, HAL; I'll go in
through the emergency airlock.
• HAL: Without your space helmet, Dave,
you're going to find that rather difficult.
• Dave Bowman: HAL, I won't argue with
you anymore! Open the doors!
• HAL: Dave, this conversation can serve
no purpose anymore. Goodbye.
Joshua: Greetings, Professor Falken.
Stephen Falken: Hello, Joshua.
Joshua: A strange game. The only
winning move is not to play. How
about a nice game of chess?