general, inference engine, expert system, rule engine, solver, workflow, classification, data-driven programming


g.infer help
g.infer [-dfist] rules=name [load_instances=name] [bload_instances=name] [rast=name[,name,...]] [rast3d=name[,name,...]] [vector=name[,name,...]] [facts=name] [output=name[,name,...]] [new=name] [save_instances=name] [bsave_instances=name] [columns=string] [save=string[,string,...]] [strategy=string] [limit=integer] [salience=string] [module=string] [watch=string[,string,...]] [print=string] [config=string] [classdefault=string][--overwrite] [--verbose] [--quiet]


Use log-files (dribble option).
Print facts before the inference run.
Launch interactive command prompt before the inference run. (Ctrl-D to exit)
Stop execution prior to inference run
Forward internal error messages of the rule engine
Allow output files to overwrite existing files
Verbose module output
Quiet module output


Vector point layer(s) to be imported.
Raster layer(s) to be imported, including raster labels (default).
Rast3d volume layer(s) to be imported.
ASCII file containing rule base data (facts)
ASCII file containing rulebase elements (rules, templates, facts or objects).
output (EXPORT)=name,[name,...]
Export map layers (a subset of imported vector, raster or rast3d layers)
columns=column name
Attribute columns definition for the output vector layer (output option).
New GRASS vector (points) layer to be created from the facts linked to a rule base template.
Sets conflict resolution (collission) strategy for the rulebase.
Options: breadth,complexity,depth,lex,mea,simplicity,random
Default: depth
Maximum number of rules to fire. Does not apply to the refiring of the same rule.
Strategy for rule precedence assessment by salience.
Options: when-defined,when-activated,every-cycle
Default: when-defined
Rule base module(s) on the focus stack.
Default: MAIN
watch =string[,string,...]
Selection of rule engine operations to be watched (logged):
Options: activations,compilations,facts,functions,genericfunctions,globals,methods,messagehandlers,messages,rules,slots,statistics,all
Default: none
print =string[,string,...]
Environment information to be printed out before the inference run: agenda,breakpoints,classes,deffacts,definstances,facts,focusstack,functions,generics,globals,instances,messagehandlers,modules,rules,templates
Options: agenda,breakpoints,classes,deffacts,definstances,facts,focusstack,functions,generics,globals,instances,messagehandlers,modules,rules,templates
Default: none
config =string
Rule engine configuration
Options: auto-float-dividend,dynamic-constraint-checking,fact-duplication,incremental-reset,reset-globals,sequence-operator-recognition,static-constraint-checking
Default: none
classdefault =string
Class defaults
Options: convenience,conservation
Default: convenience
Object instances to be saved (ASCII)
Object instances to be saved (binary).
ASCII file containing objects
Binary file containing objects
Rule base entities to be saved (ASCII)
Options: constructs,facts,instances
Rule base entities to be saved (binary)
Options: constructs,facts,instances


g.infer is a tool to create rule-based data-driven workflows from GRASS data layers and additional data sources. g.infer can modify existing GRASS data layers, can create new vector layers or can start additional processing within GRASS. This is controlled by an inference process, which applies a knowledge base on a set of known facts (data).

The g.infer inference environment is based on a strict separation of knowledge (rules) and data (facts and object instances). Data consists of GRASS-derived spatial information and other input. The g.infer inference engine applies the knowledge, consisting of rules (rulebase), to the available data. For development and testing, interactive access and logging options are available.

g.infer provides a convenient environment to start rule-based work right away. For complex tasks there are also advanced capabilities to extend the knowledge modelling whenever necessary. This approach can be used for geodata classification tasks, GIS workflow control and other tasks.

The CLIPS Expert System Shell environment is embedded within g.infer by the pyCLIPS environment. In depth information is found in the "Notes on CLIPS" section and the References. The latter contains also references to literature describing the projects Jess and Drools which are based on CLIPS. Their documentation contains useful clues for CLIPS-related development.

The exchange of data between the GRASS and CLIPS environments is handled by functions extending the pyCLIPS wrappers, connecting both GRASS and CLIPS.


g.infer can ingest multiple input sources as data: Spatial information can be imported from GRASS data layers (raster, rast3d, point-vector), rule base-related constructs (templates, facts, classes and instances) from external files and additional sources, including OGC services.

Additional data can also be imported during the inference process if requested by the rule base. The user can further enter facts and rulebase elements via the interactive CLIPS prompt.


g.infer can manipulate the content of imported GRASS data layers and other sources of data. These changes can be written back to the respective GRASS layers using the export option for persistent storage. A new vector layer can be created through the new(OUTPUT) option. The creation of additional GRASS layers can be invoked by the rulebase.


The g.infer rulebase contains the working knowledge for the inference process, which is seperate from the data (facts). It is read from file by the rulebase option and can be edited from the interactive CLIPS prompt (-i flag) before the actual inference run.

There are three ways to represent knowledge in g.infer. They are based concepts from the CLIPS programming language (see CLIPS documentation for details). All of them can be part of the rulebase:

Rules adhere to a IF THEN layout defined by the CLIPS programming language (see below). The condition antecedent ("IF") -part is referred to as left hand side (LHS), while the invoked consequent ("THEN") is called the right hand side (RHS). LHS and RHS sides are linked by the "=>" characters. Rule-based programming is further described in the section "Knowledge Engineering".

Within g.infer it is possible to apply just rules or a mixture of objects, function and rules.

Inference Engine

The inference engine is the part of g.infer which evaluates what rules are to be applied based on the currently available data. The CLIPS inference engine used in g.infer is based on the Rete algorithm (FORGY 1982), using a forward-chaining data-driven approach. The order in which rules are to be executed can be controlled in three ways: By explicitly defining salience values for each rule, knowledge base partitioning by modules or implicitly by the setting of the conflict resolution strategy (strategy option). See section "Rulebase Development, Operation and Debugging" for details.


The Rete-algorithm performs well for a rate of approximately 20 percent of changes for the available data (facts) during an inference run. Scenarios, in which the complete content of a GRASS layer must be changed, resulting in 100 percent change, will be handled significantly less effectively.

Knowledge Engineering in g.infer

Knowledge engineering (modelling) in g.infer requires in most cases the definition of rules for the rulebase. It can also include more complex programming tasks, such as conditions, loops, functions and object oriented programming. For knowledge modelling and programming in g.infer, the programming language of the CLIPS Expert System Toolkit is used, which is closely related to the classic programming language LISP. For an in depth description of the CLIPS language, refer to the CLIPS Users's Guide and Reference Manuals (Giarratano 2007, 2008). A useful introduction to LISP is provided by Graham, 1995.

The following

are to be used within a rulebase file or via the interactive prompt. This CLIPS-based programming can not be mixed with GRASS GIS scripting.

Rulebase Notation

g.infer rulebase constructs use a fully parenthesized polish prefix notation: Any term or formula must be put in braces, with the the operator preceding the operands:
(operator operand1 operand2 ... operandN)

This differs from the infix notation used in GRASS GIS, like in r.mapcalc:

Data types

g.infer provides eight primitive data types for representing information. As the CLIPS programming language is weakly typed, variables can be created without explicitly setting a type. The available types are float, integer, symbol, string, external-address, fact-address, instance-name and instance-address. Numeric information can be represented using floats and integers. Symbolic information can be represented using symbols and strings.A number consists only of digits (0-9), a decimal point (.), a sign (+ or -), and, optionally, an (e) for exponential notation with its corresponding sign. A number is either stored as a float or an integer. Any number consisting of an optional sign followed by only digits is stored as an integer. All other numbers are stored as floats.


Facts are the common high ‑ level form for representing information in g.infer. Each fact represents a piece of data which has been placed in the current list of facts, called the fact ‑ list. Facts are the fundamental unit of data to be processed by the rulebase to infer information by firing applicable rules.

Facts may be added to the fact‑list (using the assert command), removed from the fact‑list (using the retract command), modified (using the modify command), or duplicated (using the duplicate command) through explicit user interaction or as the rule base is executed. The number of facts in the fact‑list and the amount of information that can be stored in a fact is limited only by the amount of memory in the computer. If a fact is asserted into the fact‑list that exactly matches an already existing fact, the new assertion will be ignored. This default behaviour can be changed.

Some commands, such as the retract, modify, and duplicate commands, require a fact to be specified. A fact can be specified either by fact ‑index or fact ‑ address. Whenever a fact is added (or modified) it is given a unique integer index called a fact ‑ index. Fact‑indices start at zero and are incremented by one for each new or changed fact. Whenever a reset or clear command is given, the fact‑indices restart at zero. A fact may also be specified through the use of a fact ‑ address. A fact‑address can be obtained by capturing the return value of commands which return fact addresses (such as assert, modify, and duplicate) or by binding a variable to the fact address of a fact which matches a pattern on the LHS of a rule.

A fact identifier is a shorthand notation for displaying a fact. It consists of the character “f”, followed by a dash, followed by the fact‑index of the fact.

There are two categories of facts, ordered facts and non-ordered facts, which can be used for different purposes. Both types are applied in g.infer to represent information imported from the GRASS GIS environment.

Ordered facts

Ordered facts consist of a symbol followed by a sequence of zero or more fields separated by spaces and delimited by an opening parenthesis on the left and a closing parenthesis on the right. Ordered facts encode information positionally. The first field of an ordered fact specifies a “relation” that applied to the remaining fields in the ordered fact. For example, (father‑of jack bill) states that bill is the father of jack.

(assert (animal-is duck))


assert, retract, modify, duplicate

(assert (duck))

A simple fact can contain multiple fields for content:

(assert (duck vanilla scrooge))
GRASS environment variables as ordered facts

Ordered facts are used to represent GRASS enironment variables into g.infer, including g.region parameters. These ordered facts can be changed within the CLIPS environment and be used when calling GRASS modules from within CLIPS. They must be exported back into GRASS to become permanent within the current session, which is not done by default. The following GRASS environment facts are generated by default:


Adding and Removing Facts

(assert (person (name John S. Liu) (age 23) (eye-color brown) (hair-color black)))

(facts) (retract 0)

Modifying and Duplicating Facts

(modify 0 (age 24) ) (facts)

(duplicate 2 (name "Jack P. Chen") ) (facts)

Non-ordered facts

Non ‑ ordered (deftemplate) facts allow to abstract the structure of a fact by assigning names to each field in the fact. So to access that information, a user must know what content is stored in a g.infer - fact and which field contains the information. The deftemplate construct is used to create a template which can then be used to access fields by name. This approach is used to import GRASS layers in g.infer.

The deftemplate construct allows the name of a template to be defined along with zero or more definitions of named fields or slots. Unlike ordered facts, the slots of a deftemplate fact may be constrained by type, value, and numeric range. In addition, default values can be specified for a slot. A slot consists of an opening parenthesis followed by the name of the slot, zero or more fields, and a closing parenthesis.

Deftemplate facts are distinguished from ordered facts by the first field within the fact. If the symbol serving as the first field corresponds to the name of a deftemplate, then the fact is a deftemplate fact. Like ordered facts, deftemplate facts are enclosed by an opening parenthesis on the left and a closing parenthesis on the right.

In addition to being asserted and retracted, deftemplate facts can also be modified and duplicated (using the modify and duplicate commands). Modifying a fact changes a set of specified slots within that fact. Duplicating a fact creates a new fact identical to the original fact and then changes a set of specified slots within the new fact. The benefit of using the modify and duplicate commands is that slots which don’t change, don’t have to be specified.

Facts which contain structured information require a template to define this structure:

Its content can to be applied on various input data layers and interactive user input.

The Deftemplate Construct

(deftemplate person (slot name) (slot age) (slot eye-color) (slot hair-color))

Multified Slots

(deftemplate person (multislot name) (slot age) (slot eye-color) (slot hair-color))

(person (name John S. Liu) ;multislot (age 23) (eye-color brown) (hair-color black))

(deftemplate person "Human" (slot family_name) (multislot first_names) (slot age) (slot gender) (slot status)))
(deftemplate raster "GRASS-layer" (slot layername) (slot x) (slot y) (slot value) (multislot label)))

(assert (xanadu (x 0.5) (y 0.5) (value 42) (label "Newton-John")))

(assert (person ("Thompson") ("Hunter Stockton") (67) ("male") ("deceased")))
(assert (raster ("geology") (11.25) (12.5) (100) ("Navajo Sandstone")))

Allowed Value

(deftemplate person (multislot name (type SYMBOL)) (slot age (type INTEGER)) (slot gender (type SYMBOL) (allowed-symbols male female)) )


(deftemplate person (multislot name (type SYMBOL)) (slot age (type INTEGER) (range 0 ?VARIABLE)) )


(deftemplate volleyball-team (slot name (type STRING)) (multislot player (type STRING) (cardinality 6 6)) (multislot alternates (type STRING) (cardinality 0 2)) )

Default The default value is assigned in a slot if no value is explicitly stated in an assert command. The default value is determined when the slot definition is parsed.

(deftemplate example1 ;default values (slot a) ; nil (slot b (type INTEGER)) ; 0 (slot c (allowed-values red green blue)) ; red (multislot d) (multislot e (cardinality 0 2) ; 3.5 3.5 (type FLOAT) (range 3.5 10.0)) )

(deftemplate example2 (slot a) (slot b (default ?NONE)) ) ;no default value

(deftemplate example3 (slot a (default 3)) ; 3 (slot b (default (+ 3 4))) ; 7 (multislot c (default a b c)) ; a b c (multislot d (default (+ 1 2) (+ 3 4))) ) ; 3 7


A slot with default-dynamic attribute will have its default value generated when the fact with that slot is asserted.

(deftemplate data (slot create-time (default-dynamic (time))) (slot value))

(defrule retract-data-facts-after-one-minute ?f <- (data (create-time ?t1)) (current-time ?t2) (test (> (- ?t2 ?t1) 60)) => (retract ?f))

(assert (data (value 3)))

(assert (current-time (time)))

(deftemplate person (multislot name (type SYMBOL)) (slot age (type INTEGER)))

(assert (person (name Fred Smith) (age four))) ;wrong type

The type attribute is either ?VARIABLE for any data type, or one or more of SYMBOL, STRING, LEXEME, INTEGER, FLOAT, or NUMBER. Static and Dynamic Constraint Checking

(defrule create-person => (printout t "What's your name? ") (bind ?name (explode$ (readline))) (printout t "What's your age? ") (bind ?age (read)) (assert (person (name ?name) (age ?age))) )

If age entered is of a wrong type, e.g. "four", it is not checked at parse time. Dynamic constraint checking can be enabled using

(set-dynamic-constraint-checking TRUE) ; FALSE if disable


Whenever a GRASS layer is imported by g.infer, a template is created according to its data structure and facts are asserted for the layers content. While the templater for vector layers will differ depending on the attribute layers, raster data templates adhere to the following structure:


(geo_test (x 599000.0) (y 4921800.0) (value 5) (attribute))
(random_slice_00009 (x 599000.0) (y 4921800.0) (z 9.0) (value 1.0))

"_slice_000009" has been added by g.infer for internal bookkeeping.


The primary method of representing knowledge in g.infer are rule. Rules are used to represent heuristics, or "rules of thumb", which specify a set of actions to be performed for a given situation. They also compare to exceptions used in languages like Python. Rules can cause actions such as the creation, modification or deletion of facts or the call-up of GRASS modules and scripts. This can in turn lead to the activation (firing) of other rules. Any g.infer rulebase comprises of a set of rules which collectively work together to solve a classification task, establish a workflow or do similar. A rule is composed of an antecedent and a consequent. The antecedent of a rule is also referred to as the if portion or the left ‑ hand side (LHS) of the rule. The consequent of a rule is also referred to as the then portion or the right ‑ hand side (RHS) of the rule.

The antecedent of a rule (LHS) is a set of conditions (or conditional elements) which must be satisfied for the rule to be applicable. The conditions of a rule are satisfied based on the existence or non ‑ existence of specified facts in the fact ‑ list or specified instances of user ‑ defined classes in the instance ‑ list. One type of condition which can be specified is a pattern. Patterns consist of a set of restrictions which are used to determine which facts or objects satisfy the condition specified by the pattern.

The process of matching facts and objects to patterns is called pattern ‑ matching. A mechanism, called the inference engine, matches patterns against the current state of the fact ‑ list and instance ‑ list and determines which rules are applicable during the inference run.

The consequent of a rule (RHS) is the set of actions to be executed when the rule is applicable. This is colloquially reffered to as "the rule fires". The actions of applicable rules are executed when the inference engine is instructed to begin execution of applicable rules. If more than one rule is applicable, the inference engine uses a conflict resolution strategy to select which rule should have priority. The actions of the selected rule are executed (which may affect the list of applicable rules) and then the inference engine selects another rule and executes its actions. This process continues until no applicable rules remain.

In many ways, rules can be thought of as IF - THEN statements found in procedural programming languages. However, the conditions of an IF - THEN statement in a procedural language are only evaluated when the program flow of control is directly at the IF ‑ THEN statement. In contrast, rules act like WHENEVER - THEN statements. The inference engine always keeps track of rules which have their conditions satisfied and thus rules can immediately be executed when they are applicable. In this sense, rules are similar to exception handlers found in other programming languages.

(assert (animal-is duck))
(defrule duck (animal-is duck) => (assert (sound-is quack)))


GRASS example


GRASS example

Search Patterns


Rulebase content and other CLIPS code can be commented by starting lines with a semicolon.

; This is commented line 


Variables in CLIPS are weakly typed. They are not restricted to holding a value of a single data type. So when creating a variable, it is not required to provide typing information. The defglobal construct allows variables to be defined which are global in scope throughout the CLIPS environment. That is, a global variable can be accessed anywhere in the CLIPS environment and retains its value independent of other constructs. In contrast, some constructs (such as defrule and deffunction) allow local variables to be defined within the definition of the construct. These local variables can be referred to within the construct, but have no meaning outside the construct.

defrule output (suggestion ?action) => (printout t crlf "I would like to suggest you to " crlf ?action crlf crlf) )

Multiple Use of Variables

(defrule eye-color (find (eye-color ?eye)) (person (name ?name) (eye-color ?eye)) => (printout t crlf ?name " has " ?eye " eye." crlf))


A function in CLIPS is a piece of executable code identified by a specific name which returns a useful value or performs a useful side effect (such as displaying information).

The defun command allows to define new functions. The body of a deffunction is a series of expressions similar to the RHS of a rule that are executed in order by CLIPS when the deffunction is called. The return value of a deffunction is the value of the last expression evaluated within the deffunction. Calling a deffunction is identical to calling any other function in CLIPS.


(defun fahrenheit_celsius (celsius_value) (+ (* celsius_value 1.8) 32))

Functions: Variable Number of Aruguments bind Function

(bind ?new-size (- ?size ?choice)) THIS BINDS A VARIABLE !

Control Structures

Rulebase Development, Operation and Debugging:

g.infer can be used to develop and run rule-based workflows for information classification and data processing. An knowledge base, consisting of a set of rules, will be loaded via a 'rulebase'-file.

When a rule is newly activated, its placement on the agenda is based (in order) on the following factors:

a) Newly activated rules are placed above all rules of lower salience and below all rules of higher salience.

b) Among rules of equal salience, the current conflict resolution strategy is used to determine the placement among the other rules of equal salience.

c) If a rule is activated (along with several other rules) by the same assertion or retraction of a fact, and steps a and b are unable to specify an ordering, then the rule is arbitrarily (not randomly) ordered in relation to the other rules with which it was activated. In this respect, the order in which rules are defined has an arbitrary effect on conflict resolution (which is highly dependent upon the current underlying implementation of rules). This arbitrary ordering for the proper execution of rules should not be depended on.

Once a knowledge base (in the form of rules) is built and the fact ‑ list and instance ‑ list is prepared, the inference engine is ready to execute rules:

Whenever a rule modifies a specific fact, the fact is retracted, that is, removed from the fact stack and a new (altered) fact is instantiated and added on the fact stack.

The set-up of a rule set similar to r.mapcalc requires a multi-stage design: Otherwise, the rules will keep processing the first layer cell ad infinitum. It is easily possible to construct a rule set which acts like an infinity-loop, which never terminates. This is in the most part undesired, but may be an asset for monitoring activities.

Phases and Control Facts

(deffacts control-information (phase detection) (phase-seq detection isolation recovery))

(defrule change-phase (declare (salience -10)) ?phase <- (phase ?current-phase) ?list <- (phase-seq ?next-phase $?other-phases) => (retract ?phase ?list) (assert (phase ?next-phase)) (assert (phase-seq ?other-phases ?next-phase)))

Replacing Phases and Control Facts

(defmodule DETECTION) (defmodule ISOLATION) (defmodule RECOVERY)

(deffacts MAIN::control-information (phase-seq DETECTION ISOLATION RECOVERY))

(defrule change-phase ?list <- (phase-seq ?next-phase $?other-phases) => (focus ?next-phase) (retract ?list) (assert (phase-seq ?other-phases ?next-phase)))

Conflict Resolution

The conflict resolution strategy is an implicit mechanism for specifying the order in which rules of equal salience should be executed.

g.infer provides seven conflict resolution strategies: depth, breadth, simplicity, complexity, lex, mea, and random. The default strategy is depth. The current strategy can be set by using the set‑strategy command (which will reorder the agenda based upon the new strategy).

Tthe preferred mechanisms in g.infer for ordering the execution of rules are salience and modules. Salience allows one to explicitly specify that one rule should be executed before another rule.

Options to apply salience values:


(deffacts init (priority first) (priority second) (priority third))

with salience declaration To assign a salience value to a rule, use the declare command,

(defrule fire-first (declare (salience 30)) (priority first) => (printout t "Print first" crlf))

(defrule fire-second (declare (salience 20)) (priority second) => (printout t "Print second" crlf))

(defrule fire-third (declare (salience 10)) (priority third) => (printout t "Print third" crlf))


The agenda is the list of all rules which have their conditions satisfied (and have not yet been executed). If the knowledge base is partitioned into multiple modules, each module has its own agenda. The agenda acts similar to a stack (the top rule on the agenda is the first one to be executed).
The Agenda and Execution
To list the list of rules on the agenda, use


Fact Addresses

(defrule process-moved-information ?f1 <- (moved (name ?name) (address ?address)) ?f2 <- (person (name ?name)) => (retract ?f1) ;a MUST or infinite loop (modify ?f2 (address ?address)))

Modules allow one to explicitly specify that all of the rules in a particular group (module) should be executed before all of the rules in a different group.

Defmodules allow a knowledge base to be partitioned. Every construct defined must be placed in a module. The programmer can explicitly control which constructs in a module are visible to other modules and which constructs from other modules are visible to a module. The visibility of facts and instances between modules can be controlled in a similar manner. Modules can also be used to control the flow of execution of rules.

A knowledge base can be partitioned using the defmodule construct.

(defmodule DETECTION) (defmodule ISOLATION) (defmodule RECOVERY)

(defrule example1 =>) ; in current module (defrule ISOLATION::example2 =>) ; in module ISOLATION

(get-current-module) (set-current-module DETECTION)


The current focus determines which agenda the run command uses during execution. The reset and clear commands automatically set the current focus to the MAIN module.


Manipulating and Examining the Focus Stack

(list-focus-stack) (get-focus-stack) (clear-focus-stack) (get-focus) ;get current focus (pop-focus) ;remove current focus


Terminate current module and return to the next module.

(defmodule MAIN (export deftemplate initial-fact)) ; must

(defmodule DETECTION (import MAIN deftemplate initial-fact)) ; must

(defrule MAIN::start => (focus DETECTION))

(defrule DETECTION::example-1 => (return) (printout t "No printout!" crlf)) ; not printed

(defrule DETECTION::example-2 ; no chance to fire => (return) (printout t "No printout!" crlf))

Importing and Exporting Facts

(deftemplate DETECTION::fault (slot component)) (assert (fault (component A))) ; in module DETECTION

(deftemplate ISOLATION::possible-failure (slot component)) (assert (possible-failure (component B))) ; in module ISOLATION

(facts DETECTION) ; (fault (component A)) (facts ISOLATION) ; (possible-failure (component B)) (facts RECOVERY) ; none (facts *) ; list all facts

export and import

A fact is "owned" by the module in which its deftemplate is contained. To make facts visible to other modules, use the export in the owning module. In order to use the deftemplate defined in another module, a module must import the deftemplate.

The export attribute use one of the following formats:

(export ?ALL) (export ?NONE) (export deftemplate ?ALL) (export deftemplate ?NONE) (export deftemplate +)

The import attribute use one of the following formats:

(import ?ALL) (import ?NONE) (import deftemplate ?ALL) (import deftemplate ?NONE) (import deftemplate +)

Modules and Execution Control

(defrule DETECTION::rule-1 (fault (component A | C)) =>)

(defrule ISOLATION::rule-2 (possible-failure (component B | D)) =>)

(defrule RECOVERY::rule-3 (fault (component A | C)) (possible-failure (component B | D)) =>)

Logging and Debugging

Several features of g.infer support the development and debugging of rule-bases:

Debugging: g.infer Flags for Logging, Interaction and Abort:

Watch-Option: Logging of Knowledge Base Performance

See the section "Notes on CLIPS" for complete definition of terminology.


Configuration options for CLIPS engine: auto-float-dividend,dynamic-constraint-checking,fact-duplication,incremental-reset,reset-globals,sequence-operator-recognition,static-constraint-checking.


Class default of CLIPS engine: convenience(default),conservation
Explicit Options within CLIPS Programming
Watching Activations, Rules, and Statistics

(clear) ; remove all facts, rules, and deffacts.

(reset) (watch activations) (assert (emergency (type fire))) (agenda) (retract 1) (agenda)

(reset) (watch rules) (assert (emergency (type fire))) (run) (agenda)

(unwatch all) (watch statistics) (assert (emergency (type fire))) (run)

Commands for Manipulating Constructs

Displaying the List of Members of a Specified Construct




Displaying the Text Representation of a Specified Construct Member

(ppdefrule )

(ppdeftemplate )

(ppdeffacts )

Deleting a Specified Construct Member

(undefrule )

(undeftemplate )

(undeffacts )

Notes on g.infer pyCLIPS extensions

Several CLIPS elements are superseded in g.infer by customized versions. g.infer extends the pyCLIPS- amd CLIPS language by several constructs to communicate and interact the GRASS GIS:

Calling a GRASS Module:


(defrule verbose_gversion_read (verbose on) => (bind ?la_version (python-call grass_read_command "g.version" )) (ginfer_printout t "GRASS Version = " ?la_version crlf))


(python-call grass_run_command "g.region" "3p")


(defrule grassrun_rmapcalc_random1 (raster_mapcalc run) => (python-call grass_message "** RHS: r.mapcalc 1 **") (python-call grass_run_command "r.mapcalc" "rhs_mapcalc_1=rand(1,10)") (assert (mapcalc1 done)))

defrule grassrun_rinwms (raster_wms run) => (python-call grass_message "** RHS: **") (python-call grass_run_command "c" output=akl_srtm mapserver=  layers=worldwind_dem format=geotiff style=short_int maxcols=100 maxrows=100) (assert (rinwms done)))
d.mon (GRASS 6.4.2)
(defrule grassrun_rinwms_display2 (rinwms_rename done) => (python-call grass_message "** RHS: display **") (python-call grass_run_command d.mon start=x0) (python-call grass_run_command d.rast map=rhs_srtm) (assert (rinwms_display1 done)))

I/O Functions

(defrule player-select (phase choose-player) => (printout t "Who moves first (Computer: c " "Human: h)? ") (assert (player-select (read))))


(open "input.dat" data "r")


(open "example.dat" xmp "w") (printout xmp "green" crlf) (printout xmp 7 crlf) (close xmp)

(open "example.dat" xmp "r") (read xmp) (read xmp) (close xmp)


(format nil "Name: %-15s Age: %3d" "Bob Green" 35) (bind ?name (format nil "Name: %-15s Age: %3d" "Bob Green" 35)) (printout t ?name)

discouraged: read, format

works: open, close

Notes on CLIPS:

The core of g.infer consists of the C Language Integrated Production System (CLIPS) Expert System Toolkit. Python-Wrappers (PyClips project, g.infer code) provide access to the embedded CLIPS inference engine, including rulebase, factbase, templates and classes/instances of the CLIPS Object Oriented Language (COOL).

The following content of this section has been compiled from the CLIPS ONLINE DOCUMENTATION. More detailed information can be found there.

CLIPS - an Expert System Toolkit

The expert system toolkit CLIPS provides a complete environment for developing expert systems. The term shell is reserved for historic reasons for the part of CLIPS which performs the actual inferences or reasoning. This CLIPS shell provides the basic elements of an expert system:

A program written in CLIPS may consist of rules, facts, and objects. The inference engine decides which rules should be executed and when. A rule ‑ based expert system written in CLIPS is a data - driven program where the facts, and objects if desired, are the data that stimulate execution via the inference engine.

Use of Prefix Notation in CLIPS

Function calls are expressed within the CLIPS environment in prefix notation. In prefix notation, the formula is put in braces, with the the operator preceding the operands.

Knowledge Representation

CLIPS provides heuristic and procedural paradigms for representing knowledge. Both paradigms are described here. Object ‑ oriented programming cpabilities are briefly covered below.

Procedural Knowledge

CLIPS supports a procedural paradigm for representing knowledge like that of other programming languages. Deffunctions and generic functions allow the user to define new executable elements to CLIPS that perform a useful side ‑ effect or return a useful value. These new functions can be called just like the built ‑ in functions of CLIPS. Message ‑ handlers allow the user to define the behavior of objects by specifying their response to messages. Deffunctions, generic Defmodules allow a knowledge base to be partitioned.functions and message ‑ handlers are all procedural pieces of code specified by the user that CLIPS executes interpretively at the appropriate times.

Generic Functions

Generic functions are similar to deffunctions in that they can be used to define new procedural code directly in CLIPS, and they can be called like any other function. However, generic functions are much more powerful because they can be overloaded. A generic function will do different things depending on the types (or classes) and number of its arguments. Generic functions are comprised of multiple components called methods, where each method handles different cases of arguments for the generic function. The return value of a generic function is the evaluation of the last expression in the method executed.

Object Message ‑ Passing

Objects are described in two basic parts: properties and behavior. Object properties are specified in terms of slots obtained from the object's class. Object behavior is specified in terms of procedural code called message ‑ handlers which are attached to the object's class. Objects are manipulated via message ‑ passing. The result of a message is similar to a function call in CLIPS: a useful return value or side ‑ effect.

Left Hand Side (LHS) Syntax

This section describes the syntax used on the LHS of a rule in more detail. The LHS of a CLIPS rule is made up of a series of conditional elements (CEs) that must be satisfied for the rule to be placed on the agenda. There are eight types of conditional elements: pattern CEs, test CEs, and CEs, or CEs, not CEs, exists CEs, forall CEs, and logical CEs. The pattern CE is the most basic and commonly used conditional element. Pattern CEs contain constraints which are used to determine if any pattern entities (facts or instances) satisfy the pattern. The test CE is used to evaluate expressions as part of the pattern ‑ matching process. The and CE is used to specify that an entire group of CEs must all be satisfied. The or CE is used to specify that only one of a group of CEs must be satisfied. The not CE is used to specify that a CE must not be satisfied. The exists CE is used to test for the occurence of at least one partial match for a set of CEs. The forall CE is used to test that a set of CEs is satisfied for every partial match of a specified CE. Finally, the logical CE allows assertions of facts and the creation of instances on the RHS of a rule to be logically dependent upon pattern entities matching patterns on the LHS of a rule (truth maintenance).
Field Contraints
Not Field Contraint

(defrule person-without-brown-hair (person (name ?name) (hair ~brown)) => (printout t ?name " does not have brown hair." crlf))

Or Field Contraint

(defrule person-with-brown-or-black-hair (person (name ?name) (hair brown|black)) => (printout t ?name " has dark hair." crlf))

And Field Contraint

(defrule person-with-brown-or-black-hair (person (name ?name) (hair ?color&brown|black)) => (printout t ?name " has " ?color " hair." crlf))

(defrule person-without-brown-nor-black-hair (person (name ?name) (hair ?color&~brown|~black)) => (printout t ?name " has " ?color " hair." crlf))

Combining Field Contraint

(defrule complex-eye-hair-match (person (name ?name1) (eyes ?eyes1&blue|green) (hair ?hair1&~black)) (person (name ?name2&~?name1) (eyes ?eyes2&~eyes1) (hair ?hair2&red|?hair1)) => (printout t ?name1 " has " ?eyes1 "eyes and " ?hair1 " hair." crlf) (printout t ?name2 " has " ?eyes2 "eyes and " ?hair2 " hair." crlf))

Pattern Conditional Elements

Pattern conditional elements consist of a collection of field constraints, wildcards, and variables which are used to constrain the set of facts or instances which match the pattern CE. A pattern CE is satisfied by each and every pattern entity that satisfies its constraints. Field constraints are a set of constraints that are used to test a single field or slot of a pattern entity. A field constraint may consist of only a single literal constraint, however, it may also consist of several constraints connected together. In addition to literal constraints, CLIPS provides three other types of constraints: connective constraints, predicate constraints, and return value constraints. Wildcards are used within pattern CEs to indicate that a single field or group of fields can be matched by anything. Variables are used to store the value of a field so that it can be used later on the LHS of a rule in other conditional elements or on the RHS of a rule as an argument to an action.

The first field of any pattern must be a symbol and can not use any other constraints. This first field is used by CLIPS to determine if the pattern applies to an ordered fact, a template fact, or an instance. The symbol object is reserved to indicate an object pattern. Any other symbol used must correspond to a deftemplate name (or an implied deftemplate will be created). Slot names must also be symbols and cannot contain any other constraints.

For object and deftemplate patterns, a single field slot can only contain one field constraint and that field constraint must only be able to match a single field (no multifield wildcards or variables). A multifield slot can contain any number of field constraints.


CLIPS has two wildcard symbols that may be used to match fields in a pattern. CLIPS in­terprets these wildcard symbols as standing in place of some part of a pattern entity. The single ‑ field wild­card, denoted by a question mark character (?), matches any value stored in exactly one field in the pattern entity. The multifield wildcard, denoted by a dollar sign followed by a question mark ($?), matches any value in zero or more fields in a pattern entity. Single ‑ field and multifield wildcards may be combined in a single pattern in any combination. It is illegal to use a multifield wildcard in a single field slot of a deftemplate or object pattern. By default, an unspecified single ‑ field slot in a deftemplate/object pattern is matched against an implied single ‑ field wildcard. Similarly, an unspecified multifield slot in a deftemplate/object pattern is matched against an implied multifield‑wildcard.
Single-field Wildcards

(deftemplate person (multislot name) (slot phone-number)) (defrule print-telephone-number (person (name ? ? ?last-name) (phone-number ?phone)) => (printout t ?phone crlf))

Multifield Wildcards

(defrule print-telephone-number (person (name $? ?last-name) (phone-number ?phone)) => (printout t ?phone crlf))

Conflict Resolution Strategies

A conflict resolution strategy is an implicit mechanism for specifying the order in which rules of equal salience should be executed.

Because they require explicit declarations, the preferred mechanisms in CLIPS for ordering the execution of rules are salience and modules. Salience allows one to explicitly specify that one rule should be executed before another rule. Modules allow one to explicitly specify that all of the rules in a particular group (module) should be executed before all of the rules in a different group

The agenda is the list of all rules which have their conditions satisfied (and have not yet been executed). Each module has its own agenda. The agenda acts similar to a stack (the top rule on the agenda is the first one to be executed). When a rule is newly activated, its placement on the agenda is based (in order) on the following factors:

a) Newly activated rules are placed above all rules of lower salience and below all rules of higher salience.

b) Among rules of equal salience, the current conflict resolution strategy is used to determine the placement among the other rules of equal salience.

c) If a rule is activated (along with several other rules) by the same assertion or retraction of a fact, and steps a and b are unable to specify an ordering, then the rule is arbitrarily (not randomly) ordered in relation to the other rules with which it was activated. Note, in this respect, the order in which rules are defined has an arbitrary effect on conflict resolution (which is highly dependent upon the current underlying implementation of rules). Do not depend upon this arbitrary ordering for the proper execution of your rules.

CLIPS provides seven conflict resolution strategies: depth, breadth, simplicity, complexity, lex, mea, and random. The default strategy is depth. The current strategy can be set by using the set‑strategy command (which will reorder the agenda based upon the new strategy).


A rule's module is automatically focused upon when that rule, being declared auto-focus, is activated.

(defmodule MAIN (export deftemplate initial-fact))

(defmodule DETECTION (import MAIN deftemplate initial-fact))

(defrule DETECTION::example (declare (auto-focus TRUE)) =>)

CLIPS Object‑Oriented Language

The CLIPS Object ‑ Oriented Language (COOL) includes elements of data abstraction and knowledge representation. It supports abstraction, encapsulation, inheritance, polymorphism and dynamic binding. An overview of COOL as a whole, incorporating the elements of both concepts is given in [BPG].


An object in CLIPS is defined to be a symbol, a string, a floating ‑ point or integer number, a multifield value, an external ‑ address or an instance of a user - defined class. Objects are described in two basic parts: properties and behavior. A class is a template for common properties and behavior of objects which are instances of that class.

Objects in CLIPS are split into two important categories: primitive types and instances of user‑defined classes. These two types of objects differ in the way they are referenced, created and deleted as well as how their properties are specified.

Primitive type objects are referenced simply by giving their value, and they are created and deleted implicitly by CLIPS as they are needed. Primitive type objects have no names or slots, and their classes are predefined by CLIPS. The behavior of primitive type objects is like that of instances of user ‑ defined classes, however, in that you can define message ‑ handlers and attach them to the primitive type classes. It is anticipated that primitive types will not be used often in an object ‑ oriented programming (OOP) context; the main reason classes are provided for them is for use in generic functions. Generic functions use the classes of their arguments to determine which methods to execute.

An instance of a user‑defined class is referenced by name or address, and they are created and deleted explicitly via messages and special functions. The properties of an instance of a user ‑ defined class are expressed by a set of slots, which the object obtains from its class. As previously defined, slots are named single field or multifield values.

The primary difference between object slots and template (or non ‑ ordered) facts is the notion of inheritance. Inheritance allows the properties and behavior of a class to be described in terms of other classes. COOL supports multiple inheritance: a class may directly inherit slots and message‑handlers from more than one class. Since inheritance is only useful for slots and message‑handlers, it is often not meaningful to inherit from one of the primitive type classes, such as MULTIFIELD or NUMBER. This is because these classes cannot have slots and usually do not have message - handlers.

Pattern ‑ Matching with Object Patterns

Instances of user ‑ defined classes in COOL can be pattern ‑ matched on the left ‑ hand side of rules. Patterns can only match objects for which the object's most specific class is defined before the pattern and which are in scope for the current module. Any classes which could have objects which match the pattern cannot be deleted or changed until the pattern is deleted. Even if a rule is deleted by its RHS, the classes bound to its patterns cannot be changed until after the RHS finishes executing.


Simple Vector Example

Point Vector Classification
(rule_01 (raster (geology) ?x ?y (1000) (gold)) => print "We found gold !" )

Simple Raster Example

Raster Example

R.mapcalc Example

Linked Rules

Print to User

Query User

(defrule grassrun_rinwms (raster_wms run) => (python-call grass_message "** RHS: **") (python-call grass_run_command "c" output=akl_srtm mapserver= layers=worldwind_dem format=geotiff style=short_int maxcols=100 maxrows=100) (assert (rinwms done)))

(defrule grassrun_rinwms_remove (rinwms done) => (python-call grass_message "** RHS: remove raster2 **") (python-call grass_run_command g.remove rast=akl_srtm.2) (assert (rinwms_remove done)))

(defrule grassrun_rinwms_rename (rinwms_remove done) => (python-call grass_message "** RHS: rename raster1 **") (python-call grass_run_command g.rename rast=akl_srtm.1,rhs_srtm) (assert (rinwms_rename done)))

(defrule grassrun_rmapcalc_random1 (raster_mapcalc run) => (python-call grass_message "** RHS: r.mapcalc 1 **") (python-call grass_run_command "r.mapcalc" "rhs_mapcalc_1=rand(1,10)")

(defrule grassread_rstats (verbose on) => (python-call grass_message "** RHS: r.stats read **") (bind ?result (python-call grass_read_command "r.stats" "cl" "input=geology" "fs=_")) (ginfer_printout t "===========" crlf)(ginfer_printout t ?result) (ginfer_printout t "===========" crlf))


(deftemplate event (slot tstamp (default-dynamic (time))) (slot value)) (assert (event (value 1)))

(defrule time1 ?foo <- (event (tstamp ?t1)(value 3)) (start-time ?t2) (test (> (- ?t1 ?t2) 0.01)) => (retract ?foo) (ginfer_printout t "Retracting" ?t1 ?t2 crlf) )

(defrule time2 (timetest) => (assert (event (value 3))) (ginfer_printout t "Timing: ON" (time) crlf) )

(assert (event (value 2)))

(assert (start-time (time)))


r.fuzzy, r.mapcalc: Raster algebra, r.infer, Definition of vector columns for output vectors



(person (name "John S. Liu") (age 23) (eye-color brown) (hair-color black)) The Watch Command

(watch )

: facts, rules, activations, statistics, compilations, focus, all

(watch facts) (modify 3 (age 25) ) (facts)

The Deffacts Construct

(deffacts [] *) ; initially define a set of facts


reset : 1. remove all activated rules from agenda 2. remove all facts from the fact-list 3. assert the facts from existing deffacts


Browne P. (2009) JBOSS Drools Business Rules. Packt Publishing. ISBN 1-847-19606-3

Forgy C., (1982) Rete: A Fast Algorithm for the Many Pattern/Many Object Pattern Match Problem", Artificial Intelligence, 19, pp 17–37

Friedman-Hill E. (2003). Jess in Action. Manning Publications. ISBN 1-930-11089-8

Garosi F. (2008). PyCLIPS Manual Release 1.0. URL

Giarratano J., Gary R. (2004). Expert Systems: Principles and Programming. Course Technology. ISBN 0-534-38447-1

Giarratano, J.C. (2007). CLIPS User's Guide. URL

Giarratano, J.C. (2007). CLIPS Reference Manual: Basic Programming Guide. URL

Giarratano, J.C. (2008). CLIPS Reference Manual: Advanced Programming Guide. URL

Graham P. (1995). ANSI Common Lisp. Prentice Hall, ISBN 0-133-79875-6

Löwe P. (2004). Technical Note - A Spatial Decision Support System for Radar-Metereology in South Africa. Transactions in GIS. 8(2):235-244. Blackwell Publishing Ltd. Oxford.

Löwe P. (2004). Methoden der Künstlichen Intelligenz in Radarmeteorologie und Bodenerosionsforschung (Dissertation). URL

Jackson P. (1998). Introduction to Expert Systems. Addison Wesley. ISBN 0-201-87686-8

Puppe F. (1993) Systematic Introduction to Expert Systems. Springer. ISBN 3-540-56255-9

Riley G., (2008). The Hsitory of CLIPS. URL

Rudolph G. (2008). Some Guidelines For Deciding Whether To Use a Rule Engine. URL


Peter Löwe

Last changed: $Date: 2012-07-26 22:56:45 +0100 (Thu, 26 Jul 2012) $