A
production system describes a set of condition-action rules to be applied in given situations. At the simplest level this could just be a set of if-then commands, but usually implies a more complicated arrangement such as that employed in
Expert System shells such as
CLIPS which do pattern-matching and
unification of pre-conditions written in a
predicate logic-like language over a database of facts.
CLIPS is a forward-chaining production system, whereas
Prolog is a form of backward-chaining production system (i.e., it tries to reason backwards from a goal to find facts that support it, rather than reasoning from known facts to find their consequences).
Here is a simple example of a production system for a game
AI opponent [
1]:
set health 100 ;# Current health
set range 100 ;# Maximum weapons range
set nearest 50 ;# Distance of nearest enemy
set target ... ;# Position of target
set base ... ;# Position of base
# etc ...
plan Attack {
when {$health < 40} do { goal Retreat }
when {$nearest < $range} do { fire_at $target }
otherwise { move_to $target }
}
plan Retreat {
when {$health > 60} do { goal Attack }
when {![at $base]} do { move_to $base }
otherwise { repair }
}
goal Attack
This uses a form of
[Reactive Planning
] based on Teleo-Reactive programs [
2]. The code that implements this simple production system is:
proc goal {name} {
global GOAL
set GOAL $name
}
proc plan {goal body} {
global GOAL ACTIONS ELSE
set GOAL $goal
set ACTIONS($GOAL) [list]
set ELSE($GOAL) ""
uplevel #0 $args
}
proc when {cond _do_ action} {
global ACTIONS GOAL
lappend ACTIONS($GOAL) $cond $action
}
proc otherwise {action} {
global ELSE GOAL
set ELSE($GOAL) $action
}
# Typically, "run" would be incorporated into your game main-loop
proc run {} {
global ACTIONS GOAL ELSE
while 1 {
set fired 0
foreach {cond action} $ACTIONS($GOAL) {
if {[uplevel #0 [list expr $cond]]} {
uplevel #0 $action
set fired 1
break; # Only first matching action fires
}
}
if {!$fired} {
uplevel #0 $ELSE($GOAL)
}
}
}