3. Ch’ti JUG ●
Editeur de logiciels exclusivement dédiés aux enseignes du
Retail
●
Création en 1986
●
35 M€ de CA en 2008 (+20 %/an en moyenne depuis 5 ans)
●
34 % à l’International
●
5 sites en France dont le siège à Roubaix. (Paris, Belfort,
Antibes, Vannes)
●
5 filiales hors hexagone : Shanghai, Portugal, Espagne,
Tunisie, Pologne en cours
●
Une expérience éprouvée dans 60 pays
4. Ch’ti JUG Effectifs : 430 collaborateurs dans le monde, 360 en France, 300 ressources
basées à Roubaix
10
0 E pe Me rs
x rts tie
90 D cte de P t
ire ur roje
80 C f d P t Mé r
he e roje tie
70
C fd P t
he e roje
60 T chnique
e s
F a ur e @le rning
orm te t a
50
D cte de P
ire urs roduits
40
30 D ve
é loppeurs
20 R ce e Q lifica
e tte t ua tion
10 H L
ot ine
0 P pa te e
ré ra urs t
E c
ffe tifs déploie e
m nts
4
5. Ch’ti JUG
Storeland pilote l’ensemble de votre supply chain étendue
6. Ch’ti JUG CYLANDE partenaire de la FFJ
Le judo véhicule des valeurs
Cylande a accompagné l’équipe de France
de Judo à Pékin
7. Ch’ti JUG
Une croissance résolument tournée vers l’international
Lauréat du Prix PME France CHINE ACFCI / CCIFC
8. Mark
Proctor
Project Lead
●
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
12. Classes
C a s h f lo w
A c c o u n t
D a t e d a t e
lo n g a c c o u n t N o
d o u b l e a m o u n t
d o u b le b a la n c e
in t t y p e
lo n g a c c o u n t N o
A c c o u n t in g P e r io d
D a t e s t a r t
D a t e e n d
12
13. Creating Views with Triggers
date amount type accountNo AccountingPeriod
12-Jan-07 100 CREDIT 1 start end
2-Feb-07 200 DEBIT 1 01-Jan-07 31-Mar-07
18-May-07 50 CREDIT 1
9-Mar-07 75 CREDIT 1 Account
accountNo balance
1 0
increase balance for AccountPeriod Credits decrease balance for AccountPeriod Debits
select * from Account acc, select * from Account acc,
Cashflow cf, AccountPeriod ap Cashflow cf, AccountPeriod ap
where acc.accountNo == cf.accountNo where acc.accountNo == cf.accountNo
and and
cf.type == CREDIT cf.type == DEBIT
cf.date >= ap.start and cf.date >= ap.start and
trigger : acc.balance +=
cf.date <= ap.end cf.date <= ap.end
trigger : acc.balance -=
cf.amount cf.amount
CashFlow CashFlow
date amount type
date amount type
12-Jan-07 100 CREDIT
2-Feb-07 200 DEBIT
9-Mar-07 75 CREDIT
Account
accountNo balance
1 -25
13
14. What is a Rule
Quotes on Rule names salience <int>
are optional if the rule agenda-group <string>
name has no spaces. no-loop <boolean>
auto-focus <boolean>
duration <long>
• rule “<name>” ....
<attribute> <value>
when
<LHS>
then RHS can be any valid
<RHS> java. Or MVEL. Other
end languages could be
added.
14
15. Imperative vs Declarative
Methods that must specific passing of
be called directly instances
• public void helloMark(Person person) {
Rules can never if ( person.getName().equals( “mark” ) {
be called directly System.out.println( “Hello Mark” );
Specific instances
} cannot be passed.
}
LHS
• rule “Hello Mark”
when
Person( name == “mark” )
then
System.out.println( “Hello Mark” );
RHS
end
15
16. What is a Pattern
P a t t e r n
O b j e c t T y p Fe i e l d C o n s t r a i n t
F i e l d N a R m e es t r i c t i o n
E v a l Vu a lt uo er
S h o( t ew m e r p = e “= r ha )ot u t
16
17. Bringing it Together
select * from Account acc,
Cashflow cf, AccountPeriod ap
where acc.accountNo == cf.accountNo
and
cf.type == CREDIT Pattern
triggercf.date >= +=
: acc.balance
Pattern Binding ap.start and
cf.amount
cf.date <= ap.end
field Binding
rule “increase balance for AccountPeriod Credits”
when Variable Restriction
ap : AccountPeriod()
acc : Account( $accountNo : accountNo )
Literal Restriction
CashFlow( type == CREDIT,
accountNo == $accountNo,
date >= ap.start && <=
ap.end, Multri Restriction -
$ammount : ammount ) Restriction
Variable
then
acc.balance += $amount; field Binding
end
Consequence (RHS) 17
18. Rules as a “ view”
date amount type accountNo AccountingPeriod
12-Jan-07 100 CREDIT 1 start end
2-Feb-07 200 DEBIT 1 01-Jan-07 31-Mar-07
18-May-07 50 CREDIT 1
9-Mar-07 75 CREDIT 1 Account
accountNo balance
1 0
rule “increase balance for AccountPeriodrule “decrease balance for AccountPeriod
Credits” Debits”
when when
ap : AccountPeriod() ap : AccountPeriod()
acc : Account( $accountNo : accountNo ) acc : Account( $accountNo : accountNo )
CashFlow( type == CREDIT, CashFlow( type == DEBIT,
accountNo == $accountNo, accountNo == $accountNo,
date >= ap.start && <= date >= ap.start && <=
ap.end, ap.end,
CashFlow $ammount : ammount ) CashFlow $ammount : ammount )
then date amount type then date amount type
acc.balance += $amount; CREDIT
12-Jan-07 100 acc.balance -= $amount;200 DEBIT
2-Feb-07
end 9-Mar-07 75 CREDIT end
Account
accountNo balance
1 -25
18
19. Patterns in more details
CashFlow( type == “credit” )
$ap : AccountPeriod()
CashFlow( date >= $ap.start )
$ap : AccountPeriod()
CashFlow( date >= $ap.start && <=
$ap.end )
$ap : AccountPeriod()
CashFlow( type == “credit”,
date >= $ap.start && <= $ap.end
)
19
20. More Pattern Examples
Person( $age : age )
Person( age == ( $age + 1 ) )
Person( $age : age )
Person( eval( age == $age + 1 ) )
Person( $age1 : age )
Person( $age2 : age )
eval( $age2 == $age1 + 1 )
20
22. What is a Production Rule
System
Codification of
the business Repository of
knowledge inserted Java
instances
Inference
Engine
Production Pattern Working
Memory Matcher Memory
(rules) (facts)
Agenda
insert
Rules can update
change retract
on the fly
22
23. Production Rule System
Approximated by SQL and
Views
T a b le s A c c o u nAt c c o u n t i n g C P a e s r h i o f l do w
O b je c t T A y c p c eo su nAt c c o u n t i n g C P a e s r h i o f l do w
V ie w s v i e1 w v i e2 w
V ie w
m a in v ie w R u le s r u1 le r u2 le
a g e n d a
a g e n d a
23
24. Conflict Resolution with
Salience
Salience
rule “Print blance for AccountPeriod”
salience -50
when
ap : AccountPeriod()
acc : Account( )
then
System.out.println( acc.accountNo + “ : “
acc.balance );
end
Agenda
1 increase balance
2 decrease balance arbitrary
3 increase balance
4 print balance
24
25. RuleFlow
rule “increase balance for AccountPeriod Credits”
ruleflow-group “calculation”
when
ap : AccountPeriod()
acc : Account( $accountNo : accountNo )
CashFlow( type == CREDIT,
accountNo == $accountNo,
date >= ap.start && <= ap.end,
$ammount : ammount )
then
acc.balance += $amount;
end
ruleflow-group
rule “Print blance for AccountPeriod”
ruleflow-group “report”
when
ap : AccountPeriod()
acc : Account( )
then
System.out.println( acc.accountNo + “ : “
acc.balance );
end
25
26. Two Phase System
Determine
possible rules to
fire
Agenda Evaluation
Working Memory Action
Rule
insert modify
Found Select
Fire Rule
Rule to Fire
retract
No Rule
Found
exit
26
30. From CE for Expressions
Using 'from' to reason over the nested list
rule “Find all the pets for a given owner”
when
$owner : Person( name == “mark” )
Pet( name == “rover” ) from
$owner.pets
30
31. From CE for Expressions
'from' can work on any expression, not just a nested field
on a bound variable.
rule “Find People for given zip code”
when
$zipCode : ZipCode()
Person( ) from $hbn.getNamedQuery(“Find People”)
.setParameters( [ “zipCode” :
$zipCode ] )
Hibernate session
.list()
31
35. Accumulate CE
rule "accumulate"
when
$sum : Number( intValue > 100 )
from accumulate( Bus( color == "red", $t :
takings )
init( sum = 0 ),
action( sum += $t ),
result( sum ) )
then
print "sum is “ + $sum;
end
35
36. Accumulate CE
rule "accumulate"
when
$sum : Number( intValue > 100 )
from accumulate( Bus( color == "red", $t :
takings ) sum( $t ) )
then
print "sum is “ + $sum;
end
36
37. rule "collect" Accumulate CE
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 37
39. Timers
rule “name”
timer 1m30s
when
$l : Light( status == “on” )
then
SendEmail( “turn the light off” )
rule “name”
timer (int: 0 1m30)
when
$l : Light( status == “on” )
then
SendEmail( “turn the light off” )
39
40. Timers
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 ,-*?/LW
Month YES 1-12 or JAN-DEC ,-*/
Day of week YES 1-7 or SUN-SAT ,-*?/L#
Year NO empty, 1970-2099 ,-*/
rule “name”
timer ( cron: 0 0/15 * * * * )
when
$l : Light( status == “on” )
then
sendEmail( “turn the light off” )
40
41. 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 41
43. TMS and Inference
rule "Issue Child Bus Pass" Couples the logic
when
$p : Person( age < 16 )
then
insert(new ChildBusPass( $p ) );
end
What happens when the Child
rule "Issue Adult Bus Pass" stops being 16?
when
$p : Person( age >= 16 )
then
insert(new AdultBusPass( $p ) );
end
43
44. TMS and Inference
Bad
● Monolithic
● Leaky
● Brittle integrity - manual maintenance
44
45. TMS and Inference
A rule “ logically” inserts an object
When the rule is no longer true, the object is retracted.
when de-couples the logic
$p : Person( age < 16 )
then
logicalInsert( new IsChild( $p ) )
end
Maintains the truth by
when automatically retracting
$p : Person( age >= 16 )
then
logicalInsert( new IsAdult( $p ) )
end
45
46. 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"
The truth maintenance cascades
when
$p : Person( age >= 16 )
IsAdult( person =$p )
then
logicalInsert(new AdultBusPass( $p ) );
end 46
47. TMS and Inference
rule "Issue Child Bus Pass"
when
$p : Person( )
not( ChildBusPass( person == $p ) )
then
requestChildBusPass( $p ); The truth maintenance cascades
End
47
48. TMS and Inference
Good
● De-couple knowledge responsibilities
● Encapsulate knowledge
● Provide semantic abstractions for those encapsulation
● Integrity robustness – truth maintenance
48
57. Scalability
Rule engines do not scale for CEP. They have a single point of
insertion and are single threaded, CEP has concurrent streams
of events.
session.insert( event ) $c : Custumer( type == “VIP” )
; BuyOrderEvent( customer == $c )
Single Point of
entry
Patterns, evaluate
facts sequentially in
a single thread.
57
58. Scalability
So lets allow
multiple named
entry points for
those streams
EntryPoint entryPoint = session.getEntryPoint( “Home Broker Stream” );
entryPoint.insert( event ) ;
So now we can When not specified
insert different uses the “default”
streams entry-point
concurrently
$c : Custumer( type == “VIP )
BuyOrderEvent( customer == $c ) from entry-point “Home Broker Stream”
Patterns can now
optional specify their
entry-point.
58
59. Automatic Life-Cycle
Management
All Fact life-cycles must be managed by the user, so
retractions are manual.
declare Just use the declare statement
StockTick to declare a type as an event
@role( event ) and it will be retracted when it is
end no longer needed
declare StockTick
@role( event )
@timestamp( timestampAtt The declare statement can also
r) specify an internal model, that
external objects/xml/csv map on
companySymbol : String to. We support Smooks and
stockPrice : double JAXB
timestampAttr : long
end
59
60. Operators
Rule engines do not have rich enough set of temporal
comparison operators BackAckEvent must occur
between 1s and 10s 'after'
$c : Custumer( type == “VIP ) BuyOrderEvent
$oe : BuyOrderEvent( customer == $c )
from entry-point “Home Broker Stream”
BuyAckEvent( relatedEvent == $oe.id, this after[1s,
10s] $oe )
from entry-point “Stock Trader Stream”
The Full set of Operators are supported
●
coincides ●
overlaps ●
starts
●
before ●
overlappedby ●
startedby
●
after ●
during ●
finishes
●
meets ●
includes ●
finishedby
●
metby
60
62. Operators
$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”
Existing Drools 'not'
Conditional Elements
can be used to detect
non-occurrence of
events
62
63. Sliding time windows
Rule engines react to events happening now, there is no
temporal understanding of changes over time.
StockTicker( symbol == “RHAT” ) over window:time( 5s ) 5s
StockTicker( symbol == “RHAT” ) over window:length( 1000 )
1000 tickers
That isn't much without the ability to deal with aggregations,
rules engines suck.
63
64. Aggregations
Rule Engines do not deal with Over 5 seconds
aggregations
$n : Number( intValue > 100 )
from accumulate( $s : StockTicker( symbol == “RHAT” ) over window:time( 5s ),
average( $s.price ) )
Aggregate ticker price
The pattern 'Number' for RHAT over last 5
reasons 'from' the seconds
accumulate result
$n : accumulate( $s : StockTicker( symbol == “RHAT” ) over window:time( 5s ),
average( $s.price ) > 100 )
We can use some sugar to
reduce verbosity
64
76. Example
Business decisions are externalized using a decision
service
rule rule
Decision1
when
rule Decision1
Decision1
//
when
when
conditions
//
then //
conditions
conditions
// actions
then
end // actions
then
end
//
actions 76
end
77. Example
What if there is a lot of business logic like this?
rule Decision1 rule Decision1
when
rule Decision1 rule Decision1 when
rule Decision1
rule Decision1 rule Decision1
when
rule Decision1 //
when
rule Decision1
rule Decision1 //
when
rule Decision1
when when
rule Decision1 rule Decision1 rule Decision1
//
when conditions
when//
when
rule Decision1 conditions
//
when //
rule Decision1 when
when //
when
rule rule
then //
conditions rule
then // rule
conditions conditions rule
conditions
// //
when //
when // conditions
//
Decision1 conditions
then ////
actions
then
conditions conditions ////
actions then
then Decision1 conditions
conditions conditions
Decision1 conditions
Decision1 Decision1
then
when end then
then // actions end
// actions conditions
then when // actions then
thenthen
conditions
when when
// actions when
// actions
then
end actions
// actions end actions
// actions // actions
end //
// actions then
//
//
//
then
//
end actions end end actions
end // end //
// actions
end end //
conditions conditions // end end
end endconditions conditions conditions
then then then then then
// // // // //
actions actions actions actions actions
end end end 77
end end
80. 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 80
96. 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.
Joshua: Greetings, Professor
Falken.
Goodbye.
Stephen Falken: Hello, Joshua.
Joshua: A strange game. The only
winning move is not to play. How
about a nice game of chess?
96