Вы находитесь на странице: 1из 13

Tutorial B2

The matching process in CLIPS; use of variables in CLIPS


1. Local simple variables; role of variables in the matching process
As generally in programming, variables are used in rule-based programming to keep (store values);
in addition, here they play an important role in the matching process. CLIPS variables can be
classified according to several criteria. Thus, according to the purpose they are used for (the way
they are visible and product certain effects), variables are local and global. According to the number
of fields (constants) that variables can store and retrieve, they are simple and multiple. Finally, a
variable is specified when it has a name and it actually keeps a value, or it is an unspecified variable
if it does not possess a name, does not store a value and is only used for the matching process.
A CLIPS local simple specified variable appears in a CLIPS program as follows:
?<variable-name>
where variable-name must be a CLIPS symbol (a field of type symbol) that must start with a letter
and between ? and the variable-name no space exists. Examples of CLIPS variables are: ?x, ?A21, ?
Temperature, ?color.
To use a variable, this must have been previously assigned a value; in rule-based programming when
a value is assigned to a variable, it is said that the variable is bound. For example, if one introduces
the following rule definition, the CLIPS interpreter signals an error:
(defrule wrong-rule => (printout t ?x crlf) )
The error in the above rule regards the use of the variable ?x in the Right Hand Side (RHS) of the
rule, without that the variable ?x has been previously bound. Local variables can be used in the RHS
of a rule only if they were bound in the Left Hand Side (LHS) of the rule. Thus, a correct example of
using a local variable is shown in the following rule:
(defrule R1 (student ?name) => (assert (graduated high school ?name) ) )
If the Working Memory (WM) contains the fact (student John), then rule R1 is activated and after
the command run (which determines the rule firing), a new fact will be added to the WM:
(graduated high school John)
In fact, during the matching process of facts towards the Conditional Elements (CEs) of rules, the
variables existing in the LHS of a rule are bound according to the fields existing in the facts that
match the rule. The value assigned to a variable in the matching process is kept and can be used in
the RHS of rule, as it happens in the above rule.
The following remarks are important with respect to the use of variables.
1. A local simple variable that appears in a CE of a rule can match a single field, which can be of
any type (be it a number, a symbol or a string). It means a simple variable cannot be bound to either

zero or two fields, but to a single field and this creates a matching constraint. For example, the
above rule R1 is not activated by the fact (student John Smith) because the simple variable ?name
cannot be bound to two fields. However, the fact (student 234.45) activates the rule R1, since the
variable ?name can be bound to a field without any restriction about its type (the way constraints on
the type of fields can be included into a rule will be shown latter).
2. A local variable is bound only during the operation of the rule where it appears in; with respect to
this, no connection is created between two rules that use the same variable. Let us consider the
following example:
(defrule R2 (fact ?x) => (assert (a ?x) ) )
(defrule R3 (fact ?x 12) => (assert (b ?x) ) )
Though the two rules use the same variable ?x, no connection is created between rules, since a
variable is bound and stores a value only during the rule activation and execution; after the rule
firing, the local variable does not exist any longer.
3. A variable can be used more times in the RHS of a rule and it can be used in different actions, as
in the following rule:
(defrule R4 (normal-state computer ?computer-name) =>
(assert (can be used ?computer-name) )
(printout t The following computer is available: ?computer-name crlf ) )
4. The same variable can be repeatedly used in the LHS of a rule to create certain constraints in the
matching process (since a variable can be bound to a single value), as in the following example:
(defrule R5 a professor that has published a book is determined
(professor ?name teaches discipline ?dis)
(book on ?dis appeared in year ?y and was written by ?name)
=>
(printout t Professor ?name published a book for the discipline
?dis in year ?y crlf) )
The rule R5 is activated if the WM contains two facts satisfying the following conditions:
the first fact must have 5 fields;
the second fact must have 12 fields;
the first fact must have in the first position the symbol constant professor, and in the third and
fourth positions the symbols teaches and discipline;
the second fact must have in the first two positions the fields book, and on, in positions 4 to 6
the symbols appeared, in, and year, and in positions 8 to 11 the symbols and, was,
written, and by;
the second field of the first fact must be the same as the last field in the second fact;
the last field in the first fact must be the same as the third field in the second fact.

Thus, it results how complex matching conditions can be created by a repeated use of variables in
the LHS of rules.
5. All the variables that were used in previous rules are local, simple and specified variables. The
other types of variables will be introduced in the next sections.
Problems to be solved
1. Include the previous rule R5 in a file, together with the facts needed to obtain at least two
activations of the rule. Test the rule and notice the results it produces.
2. Consider the rule
(defrule R6
(grandfather-of ?name ?name)
=>
(assert (has-nephew ?name named ?name) ) )
Supposing that the WM contains the following facts: (grandfather-of John Dan), (grandfather-of
Dan Dana), (grandfather D D), (grandfather-of 12 12), (grandfather-of Dan Dan)
how many times is the rule R6 placed in agenda? (explain why).
3. Considering that the following rule was loaded:
(defrule R7
(father-of ?child is ?father)
(father-of ?father is ?grandfather)
=>
(printout t Grandfather of ?child is ? grandfather crlf) )
and the following group of facts is loaded from the following command deffacts:
(deffacts kinship
(father-of
(father-of
(father-of
(father-of
(father-of
(father-of
(father-of

John is Michael)
Dan is Michael)
Michael is Andrew)
Jh is 10)
Mary is 10)
10 is 20)
John is John) )

specify how many times is the rule R7 placed in agenda (explain why).
4. Write a rule labeled R8 and specify a group of facts that determines the following agenda:
0
0

R8
R8

f - 1, f - 2
f - 1, f - 1

0
0

R8
R8

f - 2, f - 1
f - 2, f 2

2. The deleting of facts by the means of variables


Frequently it is necessary to delete one or more facts from the WM during a CLIPS program run,
namely through the action of a rule. Such an example could be:
(defrule R9 => (retract 0) )
When the above rule is fired, the fact from the identifier f-0 is deleted. Such an action will be almost
never considered in a rule-based program, because it supposes that the programmer knows the index
of the fact to be deleted, this being difficult due to the dynamic content of the WM. Instead of this, it
is possible to use variables in the LHS of rules and get the deleting of a fact whose content is known,
without having to specify the index of that fact. To obtain such an effect, the special operator <must be used; this operator allows a variable to be bound to the index of a fact in the LHS of a rule.
After a variable is bound in this way, it can be used in the RHS of the same rule in a fact deleting
action, as it is shown in the following example:
(defrule R10
?address <- (a 1)
(b 2)
=>
(retract ?address)
(assert (c 3) ) )
The LHS of rule R10 is to be understood as follows. Rule R10 is activated if the WM contains two
facts: (a 1) and (b 2). If the rule is activated, the variable ?address is bound to the index of the
identifier for the fact (a 1). If the rule is executed, then the retract command will determine the
deleting of the fact (a 1). According to this example, it is to notice that the programmer must know
only the content of the fact to be deleted, and not the address of the fact in the WM. This is a feature
of AI programming languages, namely they free programmers from keeping address evidence. In
what it follows, the index of a fact from its identifier will be named the address of the fact.
Variables can appear inside a CE that it is used for assigning an address to a variable, and more
assignments of addresses can be used within the same rule, as it happens in the following example:
(defrule R11
?a <- (a ?x)
?b <- (b ?y ?x)
=>
(retract ?a ?b) (printout t ?x ?y crlf) )
Problem to be solved
Load from the same file the above rule and the group of facts needed to activate the rule. Test the
rule activation and the effects of its execution.

Remarks

Now, we can conclude about the syntax of the command retract:


(retract <fact-address>+)

where fact-address can be a positive integer, representing the index of the identifier for the fact to be
deleted, or a variable that is bound to the address of the fact to be deleted.

The variables that are bound to a fact address cannot be used to obtain the adding of the
WM with a fact having a content similar to that of the fact whose address is kept in the variable.
Anyhow, the content of a variable being bound to an address can be used in the RHS of the rule, as it
happens in the following two rules:
(defrule R12
?a <- (a ?x)
?b <- (b ?y ?x)
=>
(retract ?b) (assert (fact ?a)) )
(defrule R13
?ad <- (a ?x)
(fact ?ad)
=>
(printout t ?x " " ?ad crlf))
Problem to be solved
Load the rules R12 and R13 and test their operation.

3. Simple unspecified variables


In some cases of the matching process the value of a field from a fact may be of no interest. In these
cases an unspecified variable can be used (a variable without a name). Such a variable is also called
a wildcard. The simple unspecified variable is: ?. Let us consider the following example. A
knowledge base contains information on students of a university. The used facts comply with the
following pattern:
(student <name> <faculty> <year-of-study> <group> <home-address>)
By using different rules, specific information from the knowledge base can be obtained. For
example, the following rule determines all students having their home address Iasi.
(defrule R14
(student ?name ?faculty ? ? Iasi)
=>
(printout t ?name from the faculty ?faculty has his/her address in Iasi crlf) )

The rule R14 determines all the facts on students that have as the last field (the sixth field) the
symbol Iasi. At execution, the rule displays the values that appear in the positions of fields <name>
and <faculty>. It results that the values of the fields <year-of-study> and <group> doesnt matter,
and that is why for these positions the simple unspecified variable is used. To conclude, the simple
unspecified variable is to be used when a value (a field) within the fact to activate the rule doesnt
matter and that value is not needed in the RHS of the rule. About the simple unspecified variables,
the following remarks are important, too.

In a CE of a rule an unspecified variable can be used more times; it can be also used in
more CEs of the same rule, and these cases do not determine constraints for the matching process, as
it happens when a specified variable is repeatedly used. For the example, the variable ? appears in
rule R14 for two times, without determining a constraint for the values of the forth and fifth fields of
the fact that activates the rule.

Even if the value of a field from a CE in a rule does not matter from the point of view of
the matching process, if that field is needed in the RHS of the rule, the unspecified variable cannot
be used, but a specified variable is needed. This was the case for the fields <name> and <faculty> in
the rule R14.
Problems to be solved
1. Explain which is the difference in operation for the following two rules:
(defrule R15 (person ?name has children ?x) => )
(defrule R16 (person ?name has children ? x) => )
2. Continuing the example with the rule R14, determine the rule which displays all students from the
faculty AC, and the fifth year of study. Test the developed rule operation, by providing an
appropriate group of facts.

4. Multiple specified and unspecified variables


All the variables used until now were simple (either specified or not); this regards the way in the
matching process these variables can be bound to only a single field.
The multiple unspecified variable is $?. It can be used to match zero or more fields from a fact,
fields that do not matter. For example, the rule R17 is activated by any fact of the following form:
(list <list-name> <element>*)
This means that the WM contains facts on lists and the rule R17 has to display the name of all the
lists existing in the WM, independent of the number of elements existing in a list (in particular, the
list may be empty).
(defrule R17
(list ?name $?)
=>
(printout t There is a list with the name ?name crlf) )
Problem to be solved

Include the rule R17 in a file together with the following group of facts:
(deffacts Lists
(list L1 3)
(list L2)
(list L3 1 3 5)
(list L4 1 2 3)
(list L5 1 3 3 5)
(list L6 3 4 2)
(list L7 3 4)
(list L8 1 3 4 2)
(list L9 1 4 3 2) )
Load the file and run the program; explain the operation.
Multiple specified variables can be also used; they appear under the form: $?<variable-name>,
where variable-name must be a symbol, used in the same conditions as for the simple specified
variables. Multiple variables are bound and influence the matching process in the same way as
simple variables, but they can be assigned to 0, 1, 2, ... , n fields (constants). When the value of a
multiple variable is displayed, it appears between parentheses.
As an example, the previous rule can be modified to display not only the names of lists, but also
their elements, as shown below:
(defrule R18
(list ?name $?elements)
=>
(printout t The list with the name ?name contains the elements $?elements crlf) )
The simple and multiple variables, specified and unspecified can be used together, which allows
complex matching conditions to be obtained. About the decision on using a multiple specified or
unspecified variable, this is to be taken according to the criteria discussed for the simple variables.
Problems to be solved
1. Using the same pattern for the facts representing lists as it was used in the case of rules R17 and
R18, write the rule that finds all the lists containing the number 3 as element, independent of the
position of number 3 in the list, and displays the elements being placed in that list before and after 3,
respectively. Test the rule operation with the same previously used group of facts Lists and explain
the number of rule activations.
Remark
It is to notice how the fact (list L5 1 3 3 5) determines two activations of the rule. This is an
example of how a single fact can determine more activations of the same rule; this is possible
because each rule activation regards a distinct matching and binding of the variables used by the
rule.

2. Regarding the same examples of handling lists, write the rule that determines all the lists
containing the number 3 in the penultimate position, and that contain at least another element before
the number 3.
General remarks on local variables
1. All the variables used in the previous examples were local (simple multiple, specified
unspecified). These possess a certain significance only inside a rule, significance that is lost outside
the rule. For example, if one gives as command in CLIPS ?x, an error is displayed since a local
variable can be used and bound only inside a rule. When a rule is activated a local variable used in
its LHS gets a value, through the matching process, and this value is kept until the end of rule
execution.
2. Though the use of multiple variables can be essential for guiding the matching process, their
excessive use conducts to inefficiency, as they determine greater memory consumption and an
increase of the running time, in comparison with simple variables. The explanation is easy to
understand; for example, if a rule contains the CE (data $?x), then the matching process will have
to try to match the CE against facts with 1, 2, ..., n fields, and the multiple variable $?x would store
0, 1, 2, ..., n fields, depending on the facts existing in the WM. As a general idea, a multiple variable
(be it specified or not, as it is the case) has to be used only when the number of fields of the fact
supposed to satisfy the matching condition is not a priori known. When this number is known, it is
to prefer the use of simple variables, even if they have to be used for more times, since a more
efficient solution is got in this way.
3. A multiple specified variable, be it $?x, used in the LHS of a rule, can be written in the RHS
without the sign $, namely ?x. The sign $ is important only in the LHS, for the matching process,
and in the RHS, when the variable is already bound, the sign $ is not need any longer. Such an
example is:
(defrule R19 (fact

$?a1) => (printout t ?a1 crlf) )

5. Variable binding in the RHS of rules


In the presented examples on variable use, these were bound (assigned) in the LHS of rules, through
the matching process. If it is necessary, the variable binding is possible in the RHS of rules, too (the
variable binding process in rule-based programming is similar to the variable assignment in classical
programming). For this purpose, the following CLIPS command can be used, which resembles the
variable assignment in a procedural programming language:
(bind <variable> <expression>)
The variable appearing in the second position in the above command can be a local specified
variable, either simple or multiple; it can also be a global variable (these will be presented in the
next section). The expression can be a constant, a function or a global variable.
Problem to be solved
Load the following rule and explain its operation (of course, the conditions for rule activation must
be created).

(defrule R20
(a ?x ?y ?z ?t)
=>
(bind ?y as) (bind ?z (* (+ 1 3) 2)) (bind ?t John John)
(printout t ?x ?y ?z ?t crlf) )
To bind a variable to a multifield value, a function that outputs such a result can be used. Several
CLIPS functions exist for handling multifield values; one of them is:
(mv-append <element>*)
The result of this function is a multifield value that is obtained with the elements that are the
function arguments. These elements can be constants, simple or multiple variables that are already
bound, or functions that produce as result a value with zero or more fields. To see the effect of this
command, execute in the CLIPS environment:
(mv-append 1 (+ 12 13) asa (mv-append 2 an))
Remark
The command bind can be used to assign a value to a variable that was already used in the LHS of a
rule, but also to assign a value to a new variable, one that is introduced only in the RHS of the rule,
if this is necessary.
Problem to be solved
Test the following rule and explain its operation (the conditions for the rule activation have to be
created, by using the suggested assert command, or by using another fact correspondingly
introduced in the WM).
(defrule R21
(fact ?x $?y ?z) =>
(bind $?y (mv-append The result is))
(bind ?a 12)
(printout t the new variable is a= ?a crlf ?y (+ ?x ?z ?a) crlf) )
(assert (fact 2 as 34 6) )

6. CLIPS global variables


Global variables store values as long as the CLIPS interpreter is operating (in contrast with local
variables that keep a value only during the activation and execution of rules). A global variable is
labeled: ?*<variable-name>*, where variable-name must be a symbol that satisfies the same
constraints as for the names of local specified variables. Before being used, a global variable must
be introduced through the following construct definition:
(defglobal <global-variable-assignment>+)

where global-variable-assignment is of the following form: ?*<variable-name>* = <expression>.


The below example is used to define three global variables:
(defglobal ?*g* = 9.8 ?*pi* = 3.14 ?*name* = John)
Remarks
1. In a construct defglobal, a space must exist before and after the sign = .
2. A global variable can be bound to a multifield value, as it appears in the following example:
(defglobal ?*name* = (mv-append John Smith) )
3. A global variable cannot be used in the LHS of rules to get a value through the matching process.
For example, the next rule is incorrect:
(defrule R22 (fact ?*y*) => )
Anyhow, global variables can be used in the LHS of rules within the tests that will be discussed
later, and they can be used in the RHS of rules, as in the following example:
(defglobal ?*g* = 9.8)
(defrule R23 (time ?t) => (printout t Speed is (* ?*g* ?t) crlf) )
4. A global variable can be bound to a new value, different from that assigned when the variable was
defined, by the means of the command bind. This can be done from the top level of the CLIPS
environment or in the RHS of rules. If a command bind is used with a global variable and no value
to be assigned, then the global variable gets its default value, the one appearing in the construct
defglobal. The following commands can be used to test these possibilities:
(defglobal ?*A* = 12.3)
?*A*
(bind ?*A* Hey!)
?*A*
(bind ?*A*)
?*A*
Problem to be solved
Write a rule that uses a global variable in its RHS, namely it changes the value of the global
variable. Test the operation by loading the rule and the global variable definition from a file.
5. Certain commands can be used to know information on global variables.
(list-defglobals)
The above command has as result the displaying of all the names and values for the global variables
that were defined. Actually, a window can be opened to display information on existing global

variables; this can be done by using the option Globals from the menu Window. Moreover, global
variables can be watched by using the command:
(watch globals)
After the above command, the user is informed by proper messages whenever the values of global
variables are changed. This option can be activated from the menu Execution, too.
Problem to be solved
Write and load some global variable definitions, watch the variables and change their values.
6. The command reset does not delete the global variables. The way this command operates on
global variables depends on the state of a flag, whose state can be changed by the means of the
following command:
(set-reset-globals {TRUE, FALSE})
The result of the above command is the old (previous) value of the flag. The default value of the flag
is TRUE. For this value of the flag the command reset will bring the global variables to their
original values, the ones from their construct defglobal. If the value of the flag is FALSE, then the
command reset does not modify the values of the global variables. The state of the flag that
influences the global variables can be found by using the command (get-reset-globals) or from the
menu Execution, the option Options, where one can see the state of the flag Reset Global
Variables. From the respective option, the state of the flag can be directly changed, without the
need of the command (get-reset-globals). It is to notice that in CLIPS there are more flags that
allow the user to tune the CLIPS environment operation; for all these flags, commands of the type
set and get are available, and these flags can be watched and changed from the above mentioned
menu.
Problem to be solved
Notice the effect of the command reset on global variables in the two states of the flag that
establishes the influence of this command.
7. The global variables can be deleted by using the command clear, the one that removes all the
information from the CLIPS environment. Furthermore, a certain global variable can be deleted by
using the command undefglobal followed by the name of the variable (without the signs ? and *).
For example, the previously defined variable ?*A* can be removed by the command:
(undefglobal A)
The content of the global variable definitions can be seen from the menu Browse, option Defglobal
Manager, from which the removing of a global variable can be also obtained.
Problems to be solved
1. Answer the following questions:

Which is the role of variables in rule-based programming?


Which is the difference between a local and a global variable?
Which is the difference between a specified and an unspecified variable? When you use a
type and when the other?
Which are the differences between the following two rules:
(defrule R24 (a ?x) (b $?y) => (printout t ?x crlf ?y crlf) )
(defrule R25 (a $?x) (b ?y) => (printout t ?x crlf ?y crlf) )

Which are the facts that can be deleted according to the commands included in the RHS of
a rule?
Specify if the following rule is correct or not. If not, indicate which are the errors.
(defrule R26 ?a <- (a) => (retract ?a) (bind ?a 10) (printout t ?a crlf) )

Are the following rules correct? If they are correct load the facts that activate them.
(defrule R27
?a <- (fact)
?b <- (fact-adr ?a) => (retract ?b))
(defrule R28
(fact ?a)
?a <- (new-fact ?b) => (retract ?a))

When is the following rule activated? Which is the result displayed when the rule is
executed?
(defrule R29 (a ?x) (bind ?x 1) => (printout t ?x crlf) )

How many unspecified variables can be used in a rule?


The problem is to conceive a rule that finds all the lists with three elements. Which of the
following two rules is the best solution and why?
(defrule R30 (list ?name ? ? ?) => (printout t A list with 3 elements is found crlf) )
(defrule R31 (list ?name $?) => (printout t A list with 3 elements is found crlf) )

Which is the effect of the command reset on global variables?

2. Regarding the example that was used in Section 3, write a rule that finds all students from the
Faculty of Mechanics, the fourth year of study. The rule must display the name of students and their
home address.
3. Regarding the example that was used in Section 4, write the rules that find:

Two lists with the same element on the second position;


Two lists that have the same elements;

Two lists that have an element in common, independent of the position of that element in
the two lists.

4. Write the definition of a global variable. Write the CLIPS program with the following behavior: if
the WM contains the fact (change), then the value of the global variable must become YES; if the
WM contains the fact (keep), then the value of the global variable must become its original value
(the value from the construction defglobal). It is supposed that the facts (change) and (keep) cannot
simultaneously exist in the WM.
5. Write a CLIPS program that should contain information on a family and is able to determine the
kinship degree of aunt/uncle.
6. A technological process is monitored by 10 sensors. Each sensor has to states: 0 and 1. Write a
CLIPS program that is able to display a warning message if 3 or more sensors are in 0. The program
must display the message only one time, even when more than 3 sensors are in 0.

Вам также может понравиться