home *** CD-ROM | disk | FTP | other *** search
- Chapter 2 Following The Rules
-
-
-
-
- In the previous chapter you learned about facts. Now you'll see how the rules
- of an expert system utilize facts in making a program execute.
-
-
- Making Good Rules
-
-
- In order to accomplish useful work, an expert system must have rules as well as
- facts. Now that you've seen how facts are asserted and retracted,
- it's time to see how rules work.
- A rule is analogous to an IF THEN statement in a language such as Ada,
- Pascal, FORTRAN, BASIC, or C. An IF THEN rule can be expressed in
- a mixture of natural language and computer language as follows.
-
- IF certain conditions are true
- THEN execute the following actions
-
- Another term for the above statement is pseudocode, which literally means false
- code. More specific pseuodocode statements are a useful aid
- to the programmer in designing and documenting rules.
- In computer languages such as Ada, Pascal, FORTRAN, BASIC, and C, there are
- IF THEN keywords which are recognized by the language. However,
- since CLIPS has a LISP-like syntax, there are no IF THEN keywords in CLIPS.
- However, the translation of rules from natural language to CLIPS
- is not very difficult if you keep the IF THEN analogy in mind. As your
- experience with CLIPS grows, you'll soon find that writing rules in
- CLIPS becomes easy.
- You can either type rules directly into CLIPS or load rules in from a file
- of rules created by a word processor. You can use any type of
- word processor so long as it does not introduce formatting characters into
- your source code. Formatting characters will not be accepted by
- CLIPS, so be sure your word processor is in non-document mode when you type in
- the source code of your program.
- Initially, let's see how to type rules directly into CLIPS. The pseudocode
- for this rule is
-
- IF there is a duck THEN make a quack
-
- The following is the rule expressed in CLIPS syntax. The only additional
- feature is the term in double quotes, which is an optional description
- of the rule. To enter the rule, just type it in after the CLIPS prompt and
- then press the Return key.
-
- (defrule duck-quack "The First Rule" (duck) => (assert (quack)))
-
- If you type in the rule correctly as shown, you should see the CLIPS prompt
- reappear. Otherwise, you'll see an error message. If you get an
- error message, most likely you misspelled a keyword or left out a parenthesis.
- Remember, the number of left and right parentheses must always
- match in a statement.
- Shown following is the same rule with numbers below the rule keyed to an
- explanation of the parts of the rule.
-
- (defrule duck-quack "The First Rule" (duck) => (assert (quack)))
- |< 2 >|< 3 >|< 4 >|< 5 >|<6>|< 7 >|
- |< 1 >|
-
- A rule consists of the following parts:
- 1. The entire rule must be surrounded by parentheses.
- 2. The rule must start with a defrule keyword.
- 3. Following defrule must be the name of the rule. The name can be any
- valid symbolic atom. If you type in a rule name that is the same
- as an existing rule, the new rule replaces the old rule. In this rule, the
- rule name is duck-quack.
- 4. Next is an optional comment within double quotes. The comment is
- normally used to describe the purpose of the rule or any other information
- the programmer desires.
- 5. After the optional comment are one or more conditional elements or
- patterns. Each conditional element consists of one or more fields.
- In the duck-quack rule, the conditional element is (duck) and the one field
- is duck. An example of a conditional element with two fields is
- (duck quack).
- CLIPS attempts to match conditional elements of rules against facts in the
- fact-list. If all the conditional elements of a rule match facts,
- the rule is activated and put on the agenda. The agenda is a collection of
- activated rules. There may be zero or more rules in the agenda.
- 6. The symbol => that follows the conditional elements in a rule is called
- an arrow. The arrow is a symbol representing the THEN part of
- an IF THEN rule.
- 7. The last part of a rule is the list of actions that will be executed
- when the rule fires. The term fires means that CLIPS has selected
- a certain rule for execution from the agenda. While there may be multiple
- rules in the agenda, CLIPS fires the rule with the highest priority.
- In our example, the one action is to assert the fact (duck).
- The part of the rule on the left of the arrow is called the left-hand side
- (LHS) and the part on the right of the arrow is called the right-hand
- side (RHS).
-
-
- No Quack
-
-
- A rule fires when it has the highest priority of all rules in the agenda. It
- follows that if there is only one rule in the agenda, that rule
- will fire. Since we have the duck-quack rule and its conditional element is
- satisfied by the fact (duck), then the duck-quack rule should fire.
- To make a program run, just enter the run command. Type (run) and press the
- Return key in response to the CLIPS prompt.
- Nothing happens.
- In case you're wondering, no, CLIPS is not all messed up. The reason CLIPS
- does not fire the rule has to do with the way CLIPS is designed.
- The design of CLIPS is such that rules only see facts that have been entered
- after the rules. Remember that you asserted (duck) first when
- you learned about (clear) in the previous section. Then you typed in the
- duck-quack rule. Since (duck) was entered before the duck-quack rule,
- the rule doesn't see the fact and is not put on the agenda for firing.
- Because duck-quack is not on the agenda, it can't be fired.
- You can check what's in the agenda with the agenda command. Type (agenda)
- and press Return in response to the CLIPS prompt. In this case,
- nothing will be printed since there's nothing in the agenda and CLIPS will
- just respond with a prompt.
-
-
- A Quack At Last
-
-
- OK, it's time now to get serious and fire this crazy rule. In order to fire
- it, we've got to assert a (duck) after the rule has been entered.
- At first thought, this seems trivial since you just need to assert (duck).
- However, if you try this and (run) again, the rule still won't
- fire. This may be somewhat frustrating. However, before you do something
- drastic to ease your frustration, like getting married or kicking
- your pet duck, just think a minute.
- Since there is already a (duck) in the fact-list, typing in a new (duck)
- doesn't do anything. CLIPS will not accept the new (duck) because
- there is already a (duck). So, what's the solution?
- The solution is to retract the first (duck) and then assert the new duck.
- Once you've done this, issue an (agenda) command again. You'll
- see
-
- 0 duck-quack f-1.
-
- The 0 indicates this is the priority of the rule in the agenda. You'll learn
- about priority in the next chapter. Next comes the name of the
- rule followed by the fact identifiers that match the rule. In this case,
- there is only one fact identifier, f-1.
- Now type the (run) command and you'll see the rule fire at last. If you
- check the fact-list, you'll see that there is a quack at last.
-
-
- Nevermore, Nevermore
-
-
- An interesting question may occur to you at this time. What if you (run) again
- ? There is a rule and there is a fact which satisfies the rule
- and so the rule should fire again. Try a (run) command and you'll see that
- nothing happens. If you check the agenda, you'll see that the rule
- didn't fire because there was nothing on the agenda.
- The rule didn't fire again because of the way that CLIPS is designed. CLIPS
- was programmed with a characteristic of a nerve cell called a
- neuron. After a neuron transmits a nerve impulse (fires), no amount of
- stimulation will make it fire for some time. This phenomenon is called
- refraction and is very important in expert systems.
- Without refraction, expert systems would be always caught in trivial loops.
- That is, as soon as a rule fired, it would keep on firing on
- that same fact over and over again. In the real world, the stimulus that
- caused the firing would eventually disappear. For example, the duck
- would eventually swim away or fly south for the winter. However, in the
- computer world, once a fact is entered in the fact-list, it stays there
- until explicitly removed or the power is turned off.
- So how do you get the rule to fire again ? Just retract the fact and assert
- it again. It's as if the old duck flew away and a new one came
- to trigger the rule again. Basically, CLIPS remembers the fact identifiers
- that triggered a rule into firing and will not activate that rule
- again with the same fact identifiers. Of course, a rule may be put on the
- agenda with the same fact identifiers many times. However, being
- put on the agenda is not the same as being fired. Only rules that have been
- fired experience refraction, not rules on the agenda.
-
-
- Show Me The Rules
-
-
- Very often you'd like to see the rules while you're in CLIPS. There's a
- command that shows the rules called pprule, which stands for pretty
- print rule. To see a rule, specify the rule name as argument. For example,
- enter the following in response to a CLIPS prompt and press Return.
-
- (pprule duck-quack)
-
- You'll see
-
- (defrule duck-quack "The First Rule"
- (duck)
- =>
- (assert (quack)))
-
- CLIPS puts different parts of the rule on different lines for the sake of
- readability for you. You can enter rules on one line, if there's
- enough room, or multiple lines. From now on, we'll show rules on multiple
- lines for the sake of readability.
- Using a word processor is very convenient for typing programs because of all
- the editing commands that are available. The terms before the
- arrow are still considered the LHS and those after the arrow are the RHS of
- the rule.
- What if you want to print a rule but can't remember the name of the rule?
- No problem. Just use the rules command in response to a CLIPS
- prompt and CLIPS will print out the names of all the rules. For example, enter
-
- (rules)
-
- and the duck-quack name will be printed since it's the only rule name.
-
-
- Getting Loaded
-
-
- You can load a file of rules made on a word processor into CLIPS using the load
- command. Let's assume you have made the duck rule on a word
- processor and stored it in a file called duck.clp on drive b. Of course, the
- actual device that you use for file storage will be system dependent
- and so this example should be taken only as a guide. To load the rule into
- CLIPS from the file duck.clp on drive b, enter the following in
- response to the CLIPS prompt.
-
- (load "b:duck.clp")
-
- If you have typed the file using a word processor and loaded it in, you may
- see an error message from CLIPS like
-
- Illegal construct defrule
- Unidentified input character (ASCII 229) found
-
- The problem is that you used document mode in typing the rule in the word
- processor and so formatting characters like soft returns (ASCII
- character code 229) were put in. CLIPS is designed to accept only standard
- characters. Be sure to type CLIPS programs in non-document mode
- to avoid error messages like the above.
- You can use multiple files to save rules. That is, you don't have to store
- all your rules in one big file. It does take time to read rules
- into CLIPS and if you have hundreds of rules, it could take a long time.
- CLIPS also provides the opposite of the (load) command. With the save
- command, you can save rules in CLIPS to a disk file. For example,
- to save the duck-quack rule to a file called duck.clp on drive b:, just enter
- the following in response to a CLIPS prompt.
-
- (save "b:duck.clp")
-
- The (save) command will save all the rules in CLIPS to the specified file.
- It is not possible to save specified rules to a file.
-
-
- Comments, Anyone
-
-
- It's a good idea to include comments in your CLIPS program. Sometimes, rules
- can be difficult to understand and comments can be used to explain
- to the reader what the rule is doing. Comments are also used for good
- documentation of a program and will be very helpful in lengthy programs.
- A comment in CLIPS is any text that begins with semicolon and ends with a
- Return. The following is an example of comments in the duck program.
-
- ;***********************************
- ;* *
- ;* Programmer: J. Giarratano *
- ;* *
- ;* Title : The Duck Program *
- ;* *
- ;* Date : 7/7/86 *
- ;* *
- ;***********************************
- ;
- ;The purpose of this rule is to
- ;make a quack if there is a duck
- (defrule duck-quack "The First Rule" ;IF
- (duck) ;there is a duck
- => ;THEN
- (assert (quack))) ;quack
-
- If you type this in a word processor and then load it into CLIPS, you'll
- notice that all the comments are eliminated in the CLIPS program.
- That is, CLIPS will ignore the program comments as it's loading the program.
-
- Write To Me
-
-
- Besides asserting facts in the RHS of rules, you can also print out information
- using the printout keyword. For example, enter a (clear) command
- and then the following.
-
- (defrule duck-quack
- (duck)
- =>
- (printout "quack"))
-
- The argument of (printout) is enclosed in double quotes, as shown.
- Assert a new (duck) and then enter a (run) command. You'll see the output
-
- quack1 rules fired
-
- where the quack is from the (printout) statement and the informational message
- "1 rules fired" is from CLIPS.
- CLIPS has a carriage return keyword called crlf which is very useful in
- improving the appearance of output by formatting it on different lines.
- For a change, the crlf is not included in parentheses. The following example
- of crlf shows how it's used to separate the program output from
- the informational message of CLIPS.
-
- (defrule duck-quack (duck) => (printout "quack" crlf))
-
- When you enter a (run) command, you'll see
-
- quack
- 1 rules fired
-
- Notice how the quack is separated now from the CLIPS message.
- .PA
- Problems
-
-
- 1. Write a program that will print your name and address when you assert your
- first name. For example, if you enter (assert (Bob)), the program
- could print out
-
- Bob Jones
- 1000 Main St.
- Houston, TX 77058
-
- 2. Write a program that will print out the following if an assertion of
- (holidays) is made.
-
- *
- * *
- * *
- * *
- | |
- Happy Holidays
-
-
-