A squeaky rule engine

Published: 12:08 AM GMT+12, Tuesday, 9 August 2005 under: technology
smalltalk  rules  squeak 

Following on from the weekends simple java rule engine, I thought I'd give a squeak implementation a try. Following a similar API I have two classes: RuleManager and RuleSet, as initially defined as:

Object subclass: #RuleManager
	instanceVariableNames: 'ruleMap'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Talios'

Object subclass: #RuleSet
	instanceVariableNames: 'rules'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Kernel-Objects'

The RuleManager contains a dictionary of rules, with a simple wrapper to add a rule:

at: name put: rule 
	"Store a map under the define named"
	ruleMap at: name put: rule

This is pretty straight forward, so lets move over to the actual RuleSet. Unlike the earlier java implementation which used instances of the Rule interface as assertion definitions, we'll simply use block instances. A simple wrapper method is provided to add these to the rule:

assert: aBlock "A rule is made up with a series of assertions, defined as blocks" rules addLast: aBlock

Putting these together we can define a rule with:

ruleManager := RuleManager new. nameIsMark := RuleSet new. nameIsMark assert: [:x| x = 'mark']. ruleManager at: 'nameIsMark' put: nameIsMark.

Here we first create a RuleManager and Ruleset and start adding assertions, finally we add the rule into named slot.

Now we want to actually use it...

ruleManager if: 'nameIsMark' with: 'amrk' do: [ Transcript show: 'rule passed'. ]

Here we have a simplistic message that conditionally executes a block of code if the rule evaluated to true.

RuleManager>>if: name with: value do: aBlock "If the named rule passes all assertions, evaluate the block." (ruleMap at: name) ifNotNilDo: [:rule | (rule check: value) ifTrue: [aBlock value]] RuleSet>>check: value "Run each assertion against the value, if anything returns false, the rule fails." rules do: [:assertion| (assertion value: value) ifFalse: [^false]]. ^true

Now we have the "guts" (if we can call it that) of the rule evaluation loop. RuleManager>>if simply pulls out the named RuleSet, and if it exists, calls RuleSet>>check with the value and block.

RuleSet simply iterates over each defined block. If everything returns true, the block is executed.

Both this and my earlier java rule system are extremely simplistic, but they'd both be good for general purpose rule checking.

Comments (1)

Thanks Mark - this is a great starting point for a rule system I want to implement in order to model animal behaviour. With Smalltalk, Squeak, the Bots Inc book and your posting I feel I have a great start provided for me. Thanks for blogging - apart from talented you're very generous. Dave (mailto:david.urquhart@hotmail.com)

left by David Urquhart . Wednesday, 24 January 2007 12:27 AM
Add Comment