home *** CD-ROM | disk | FTP | other *** search
- Chapter 3 Adding Details
-
-
-
-
- In the first two chapters, you learned the fundamentals of CLIPS. Now you will
- see how to build on that foundation to create more powerful programs.
-
-
- Stop And Go
-
-
- Until now you've only seen the simplest type of program consisting of just one
- rule. However, expert systems consisting of only one rule are
- not too useful. Practical expert systems may consist of hundreds or thousands
- of rules. Let's take a look now at an application requiring
- multiple rules.
- Suppose you wanted to write an expert system to simulate how a robot should
- respond to a traffic light. This type of problem requires multiple
- rules. For example, the rules for the red and green light situations can be
- written as follows.
-
- (defrule red-light
- (red)
- =>
- (printout "Stop" crlf))
-
- (defrule green-light
- (green)
- =>
- (printout "Go" crlf))
-
- To test out this program, you can either enter the rules with a word
- processor and (load) them into CLIPS, or type in each rule in response
- to a CLIPS prompt.
- After the rules have been entered to CLIPS, assert a (red) fact and run.
- You'll see "Stop" printed. Now assert a (green) fact and run. You
- should see "Go" printed.
- An alternative way of writing the conditional elements in the rules is as
- follows. By including the extra pattern "light", it is more clear
- to someone reading the program what is being matched. The only disadvantage
- is a slightly longer execution time by CLIPS because more work
- is required to find matches.
-
- (defrule red-light
- (light red)
- =>
- (printout "Stop" crlf))
-
- (defrule green-light
- (light green)
- =>
- (printout "Go" crlf))
-
-
- The Real Thing
-
-
- As long as our robot encounters only red and green lights, everything is
- alright. However, the real world is not quite that simple. In addition
- to red and green lights, there are also yellow lights. In order to make the
- program more realistic, we need to add a rule for yellow lights.
- But is that enough ?
- Other possibilities include blinking red and blinking yellow lights. Rules
- need to be made to cover these situations also. Now have we covered
- all possibilties ?
- Unfortunately, the answer is no. In the real world, things don't always
- operate perfectly. What if the light is blinking green ? What if
- none of the lights are on ? What if the lights don't change ? What if the
- light is red but a police officer waves you on ?
-
-
- Take A Walk
-
-
- If you think about it, there are other possibilities besides the simple red,
- green, and yellow cases. Some traffic lights also have a green
- arrow for protected left turns. Some have a hand that lights up to indicate
- whether a person can walk or not. Some have signs that say walk
- or don't walk. So depending on whether our robot is walking or driving, it
- may have to pay attention to different signs.
- The information about walking or driving must be asserted in addition to
- information about the status of the light. Rules can be made to
- cover these conditions but they must have more than one conditional element.
- For example, suppose we want a rule to fire if the robot is walking
- and if the walk-sign says walk. A rule could be written as follows.
-
- (defrule take-a-walk
- (status walking)
- (walk-sign walk)
- =>
- (printout "Go" crlf))
-
- The above rule has two conditional elements. Both elements must be
- satisfied by facts in the fact-list for the rule to fire. To see how
- this works, enter the rule and then assert the facts (status walking) and
- (walk-sign walk). When you (run), the program will print out "Go"
- since both conditional elements are satisfied and the rule is fired.
- You can have any number of conditional elements or actions in a rule. The
- important point to realize is that the rule is placed on the agenda
- only if all the conditional elements are satisfied by facts. This type of
- restriction is called a logical AND in reference to the AND relation
- of Boolean logic. An AND relation is said to be true only if all its
- conditions are true.
- Because the conditional elements are of the logical AND type, the rule will
- not fire if only one of the conditional elements are satisfied.
- All the facts must be present before the LHS of a rule is satisfied and the
- rule is placed on the agenda.
-
-
- Gimme Deffacts
-
-
- As you work with CLIPS, you may become tired of typing in assertions. Although
- you cannot load assertions in from disk, there is a way to load
- in facts using the define facts keyword, deffacts. For example, type the
- following in response to a CLIPS prompt or enter it in a word processor
- and load it in from disk.
-
- (deffacts walk
- (status walking)
- (walk-sign walk))
-
- Following the (deffacts) keyword is the required name of this deffacts
- statement. Any valid symbolic atom can be used as the name. In this
- case, the name chosen was walk. After the name are the facts that will be
- asserted in the fact-list by this deffacts statement.
- The facts in a deffacts statement are asserted using the CLIPS reset
- command. Just enter
-
- (reset)
-
- in response to a CLIPS prompt and then give a (facts) command. You'll see the
- facts from the deffacts statement and a new fact generated by
- the (reset) command called
-
- f-0 initial-fact
-
- The (initial-fact) is automatically put in by a reset. Even without any
- deffact statements, a (reset) will always assert an (initial-fact).
- At first you may think this is pretty silly, but as you write more CLIPS
- programs you'll appreciate (initial-fact) more. The utility of (initial-fact)
- lies in starting programs running. A CLIPS program will not start running
- unless there are rules whose LHS are satisfied by facts. Rather
- than your having to type in some fact to start things off, the (reset) command
- asserts it for you as well as asserting the facts in deffacts
- statements.
- The (reset) also has an advantage compared to a (clear) command in that
- (reset) doesn't get rid of all the rules. A (reset) leaves your rules
- intact. Like (clear), it also removes all activated rules from the agenda.
- Giving a (reset) command is a recommended way to start off program
- execution, especially if the program has been run before and the fact-list is
- cluttered up with old facts.
-
-
- Selective Elimination
-
-
- There may be times when you don't want a (deffacts) to assert facts when you
- issue a (reset) command. You can use the undeffacts command to
- prevent a (deffacts) from asserting facts. For example, enter
-
- (undeffacts walk)
-
- and then issue a (reset). If you check the fact-list, you'll see no facts from
- the (deffacts walk).
- You can even get rid of initial-fact with undeffacts. Just enter the command
-
- (undeffacts initial-fact)
-
- Now, whenever you do a (reset), the initial-fact will not appear.
- Besides facts, CLIPS also allows you to selectively eliminate rules by using
- the excise command. For example, to get rid of the take-a-walk
- rule, just specify the name of the rule as argument, as in
-
- (excise take-a-walk)
-
- Enter this rule in response to a CLIPS prompt and then issue a (rules) command.
- No rule called take-a-walk will be listed since take-a-walk
- has been excised.
-
-
- A Matter Of Priority
-
-
- Up to this point, we haven't seen any cases of competing rules in the agenda.
- But in most real situations, there is a need to specify which
- rules should have priority over other rules.
- Let's consider the case of our robot trying to cross the street. There may
- be two rules in the agenda that are satisfied by the facts. One
- fact may be (green) while the other fact is that a police officer says to
- stop, even though the light is green. For example, enter the following
- two rules.
-
- (defrule green-light
- (green)
- =>
- (printout "Go" crlf))
-
- (defrule police-officer
- (police-officer stop)
- =>
- (printout "Stop" crlf))
-
- Now enter the following
-
- (deffacts conditions
- (green)
- (police-officer stop))
-
- Do a (reset) and check the agenda. You'll see both rules are on the agenda
- since both are satisfied by the facts. When you (run), the "Stop"
- may appear before the "Go". However, since the rules have equal priority, you
- cannot count on the "Stop" always appearing first.
- The correct thing to do is to assign a priority to the rules so that the
- "Stop" rule will always fire before the "Go" rule. CLIPS has a keyword
- called salience which is used to set the priority of rules.
- The salience is set using a numeric value ranging from the smallest value of
- -10000 to the highest of 10000. If a rule has no salience explicitly
- assigned by the programmer, then CLIPS assumes a salience of 0. Notice that a
- salience of 0 is midway between the largest and smallest salience
- values. A salience of 0 does not mean that the rule has no salience but
- rather that it has an intermediate priority level.
- Let's declare the salience of the police-officer rule to be higher than the
- green-light rule. We could select any values for the rules such
- that the value for police-officer is higher than green-light. A simple way of
- doing this is shown as follows.
-
- (defrule police-officer
- (declare (salience 10))
- (police-officer stop)
- =>
- (printout "Stop" crlf))
-
- The (declare (salience)) statement assigns a salience value to a rule and
- must be the first pattern. In this case, the declared value of
- 10 for the police-officer rule is higher than the default value of 0 for the
- green-light rule. Although a salience value of 1 would also be
- higher, it's a good idea to spread out the salience values in case you later
- decide to add a rule with intermediate priority to the police-officer
- and green-light rules. That way, you won't have to modify the salience value
- of the police-officer rule since there are unused values of 1
- to 9 that can be used for the intermediate rule.
-
-
- Order, Order
-
-
- Besides selecting competing rules in the agenda, salience has another important
- application. By assigning appropriate salience values, you can
- force rules to execute in a sequential fashion. Let's first look at an
- example in which salience is not used and then see how salience changes
- things.
-
- (defrule first
- (first)
- =>
- (printout "Rule 1" crlf))
-
- (defrule second
- (second)
- =>
- (printout "Rule 2" crlf))
-
- (defrule third
- (third)
- =>
- (printout "Rule 3" crlf))
-
- (deffacts test
- (first)
- (second)
- (third))
-
- Enter these rules, then do a (reset) and check the agenda. Now run the
- program and you'll see this output.
-
- Rule 3
- Rule 2
- Rule 1
-
- Notice the order of output statements. First Rule 3 is printed, then Rule
- 2, and finally Rule 1. The reason this occurs is that the activated
- rules are put on a stack. The first fact (first) activates the first rule,
- Rule 1. When the second fact is asserted, it activates the second
- rule, Rule 2, which is stacked on top of Rule 1. Finally, the third fact is
- asserted and its activated rule, Rule 3, is stacked on top of Rule
- 2.
- In CLIPS, rules of equal salience which are activated by different
- conditional elements are prioritized based on the stack order of facts.
- Rules are fired from the agenda from the top of the stack down. So first
- Rule 3 is fired because it's on the top of the stack, then Rule 2
- and finally Rule 1. If you change the order of the facts in the deffacts,
- you'll see that the last fact always produces the first rule to be
- fired and so forth. However, if rules are written which are all activated by
- the same conditional element, there is no guarantee of rule priority.
- Now let's include salience. Suppose you want the rules to fire in the order
- Rule 1, Rule 2, and then Rule 3, no matter what the arrangement
- in deffacts. To accomplish this, just add salience as follows.
-
- (defrule first
- (declare (salience 30))
- (first)
- =>
- (printout "Rule 1" crlf))
-
- (defrule second
- (declare (salience 20))
- (second)
- =>
- (printout "Rule 2" crlf))
-
- (defrule third
- (declare (salience 10))
- (third)
- =>
- (printout "Rule 3" crlf))
-
- Now do a reset and check the agenda. Notice how the salience values have
- rearranged the priority of rules in the agenda, as shown below.
-
- 30 first f-1
- 20 second f-2
- 10 third f-3
-
- When you run the program, you'll see that the order of rule firing is now Rule
- 1, Rule 2, and then Rule 3.
-
-
- Watch It
-
-
- CLIPS has several commands to help you debug programs. These commands allow
- you to watch rules, watch facts, and watch activations on the agenda
- as the program is executing. To use these features, just enter the
- appropriate command for the information that you want to see. You can enter
- any or all of the commands.
-
- (watch rules)
- (watch facts)
- (watch activations)
-
- If you enter any one or all of these commands, CLIPS will print out the
- appropriate information on the screen.
- To turn off the effect of these commands, enter the appropriate following
- command.
-
- (unwatch rules)
- (unwatch facts)
- (unwatch activations)
-
- Another useful command in debugging is the (run) command which takes an
- optional argument of the number of rule firings. For example, (run
- 21), would tell CLIPS to run the program and then stop after 21 rule firings.
- A (run 1) command allows you to step through a program 1 rule
- firing at a time.
- The major difference between a rule-based system like CLIPS and languages
- such as Pascal or BASIC is that the rules of CLIPS can be activated
- in parallel while the statements of other languages are sequential in nature.
- That is, multiple rules can be put on the agenda.
- In procedural languages like Ada, Pascal and BASIC, execution normally
- proceeds line by line in sequence. In CLIPS, any of the rules can
- be executed if certain conditions for the rules are met. So debugging an
- expert system program is not quite as straight-forward as debugging
- a program in a procedural language. This is why the (watch) commands are
- so useful. Except for very simple programs, you can't just read
- a CLIPS program listing and figure out how it executes. Since the execution
- can occur from any triggered rule, you really need to know what's
- on the agenda to know what rule will be fired next. And to figure out why a
- rule got on the agenda, you have to know what the facts are.
- .PA
- Problems
-
-
- 1. Write a program to tell a robot what to do when it encounters a traffic
- light. The possible facts are
- (light red)
- (light green)
- (light yellow)
- (light blinking-red)
- (light blinking-yellow)
- (light blinking-green)
- (light none)
- (walk-sign walk)
- (walk-sign dont-walk)
-
- The status of the robot can be
- (status walking)
- (status driving)
-
- 2. Write a program to recognize and print the names of the following patterns.
- Store the patterns in separate deffacts. You'll have to include
- row numbers for some of the patterns because some rows are duplicates and
- CLIPS won't assert duplicate facts. Do not include row numbers in
- patterns that do not have duplicate patterns.
-
- 1******** 1 * 1 *
- 2* * 2 * * 2 * *
- 3* * 3 * * 3 *
- 4* * 4 * * 4*
- 5******** 5********* 5 *
- Square Triangle 6 *
- Big Dipper
- 1 * 1*****
- 2 * * 2* *
- 3 ***** 3*****
- 4 * * 4* *
- 5* * 5*****
- A B
-
-
-