home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / program / compiler / clips / clip_doc / clips4.man < prev    next >
Encoding:
Text File  |  1993-09-01  |  14.5 KB  |  407 lines

  1.                  Chapter 4   Variable Interests
  2.  
  3.  
  4.  
  5.  
  6. The type of rules you've seen so far illustrate simple pattern matching of 
  7. conditional elements to facts.  In this chapter you'll learn very 
  8.  powerful ways to match and manipulate facts.
  9.  
  10.  
  11. Let's Get Variable
  12.  
  13.  
  14. Just as with other programming languages, CLIPS has variables available to 
  15. store values.  Variables give the programmer a powerful tool that 
  16.  is indispensible in many applications.
  17.    Variables in CLIPS are always written in the syntax of a question mark 
  18. followed by a symbolic atom name.  Some examples of variables are as 
  19.  follows.
  20.  
  21. ?x
  22. ?sensor
  23. ?valve
  24. ?noun
  25. ?color
  26.  
  27. Be sure there is no space between the question mark and symbolic atom name or 
  28. else CLIPS will misinterpret it.
  29.    Before a variable can be used, it should be assigned a value.  As an example 
  30. of a case where it's not assigned, enter the following rule which 
  31.  has variable ?x in the (printout).
  32.  
  33. (defrule test
  34.    (initial-fact)
  35. =>
  36.    (printout ?x crlf))
  37.  
  38.    In the above example, notice how initial-fact is used to trigger the rule.  
  39. This is convenient since you can assert initial-fact by simply 
  40.  doing a (reset), which saves you the trouble of asserting initial-fact.
  41.    When you run the program, the output will be
  42.  
  43. Variable x not found
  44. number
  45.  
  46.    CLIPS gives an error message because it cannot find a value which has been 
  47. bound to ?x.  The terms bound and bind are used to describe the 
  48.  assignment of a value to a variable.  Variables can be bound to symbolic atoms 
  49. or numbers.  Although no value was bound to ?x in the previous 
  50.  example, CLIPS returned a symbolic atom called "number".  The atom "number" is 
  51. meaningless and you should not rely on its assignment to unassigned 
  52.  variables in future releases of CLIPS.
  53.  
  54.  
  55. Be Assertive
  56.  
  57.  
  58. One common use of variables is to bind a value on the LHS and then assert the 
  59. bound variable on the RHS.  For example, enter
  60.  
  61. (defrule make-quack
  62.    (duck ?sound)
  63. =>
  64.    (assert (?sound)))
  65.  
  66. Now assert (duck quack) and then (run) the program.  Check the facts and you'll 
  67. see that the rule has produced (quack) because the variable ?sound 
  68.  was bound to (quack).
  69.    Of course, you can also use a variable more than once.  For example, enter 
  70. the following.  Also, be sure to do a (reset) and assert (duck 
  71.  quack) again.
  72.  
  73. (defrule make-quack
  74.    (duck ?sound)
  75. =>
  76.    (assert (?sound ?sound)))
  77.  
  78. When the rule fires, it will produce (quack quack) since the variable ?sound is 
  79. used twice.
  80.  
  81.  
  82. What The Duck Said
  83.  
  84.  
  85. Variables are also commonly used in (printout), as in
  86.  
  87. (defrule make-quack
  88.    (duck ?sound)
  89. =>
  90.    (printout "The duck said " ?sound crlf))
  91.  
  92. Enter this rule and run to find out what the duck said.  How would you modify 
  93. the rule to put double quotes around quack in the output?
  94.  
  95.  
  96. The Happy Bachelor
  97.  
  98.  
  99. Retraction is very useful in expert systems and is usually done on the RHS.  
  100. Before a fact can be retracted, it must be specified to CLIPS.  
  101.  To retract a fact from a rule, the fact address must first be bound to a 
  102. variable on the LHS.
  103.    There is a big difference between binding a variable to the contents of a 
  104. fact and binding a variable to the address of a fact.  In the examples 
  105.  you've seen, such as (duck ?sound), a variable was bound to the contents of a 
  106. fact.  That is, ?sound was bound to quack.  However, if you want 
  107.  to remove the fact whose contents are (duck quack), you must tell CLIPS the 
  108. address of the fact to be retracted.
  109.    The address of the fact is specified using the left arrow operator, "<-".  
  110. To make this operator, just type a "<" symbol followed by a "-".
  111.    As an example of fact retraction from a rule, enter the following example.  
  112.  
  113. (defrule marriage
  114.    ?bachelor <- (Rey)
  115. =>
  116.    (printout  "Rey is now happily married" crlf)
  117.    (retract ?bachelor))
  118.  
  119. Assert the fact (Rey) and then run.  After execution, check the fact-list and 
  120. you'll see no (Rey) since it has been retracted.  The conditional 
  121.  element in the rule assigns the address of (Rey) to the variable ?bachelor.  
  122. The (retract) then removes the fact (Rey) whose address was assigned 
  123.  to ?bachelor.
  124.    Variables can be used to pick up a fact content at the same time as an 
  125. address.  For example
  126.  
  127. (defrule marriage
  128.    ?bachelor <- (?name)
  129. =>
  130.    (printout  ?name " is now happily married" crlf)
  131.    (retract ?bachelor))
  132.  
  133.    The above rule will fire when ?name is assigned to any fact.  Enter the rule 
  134. and then assert the facts (duck), (Marlon), and (Gary).  When 
  135.  you run, you'll see the three happily married ex-bachelors.  Notice how the 
  136. rule fired on all facts which matched the conditional element (?name).
  137.  
  138.  
  139. John Smith's Marriage
  140.  
  141.  
  142. Will the marriage rule fire on a fact with two symbolic atoms like (John 
  143. Smith)?  Try it and see.  The rule will not fire because there are two 
  144.  atoms in (John Smith) while the conditional element specifies one atom to be 
  145. matched to (?name).
  146.    So how do we get John Smith married? One approach you might try is the 
  147. following, in which two variables called ?name are specified to match 
  148.  the two atoms in (John Smith).
  149.  
  150. (defrule marriage
  151.    ?bachelor <- (?name ?name)
  152. =>
  153.    (printout  ?name ?name" is now happily married" crlf)
  154.    (retract ?bachelor))
  155.  
  156. However, this rule won't fire on (John Smith) because the conditional element 
  157. (?name ?name) specifies that the two atoms must be the same since 
  158.  the same variable ?name is used for both atoms.
  159.    The way to get John Smith married is to use two different variables, as 
  160. follows.
  161.  
  162. (defrule marriage
  163.    ?bachelor <- (?first ?last)
  164. =>
  165.    (printout ?first ?last " is now happily married" crlf)
  166.    (retract ?bachelor))
  167.  
  168. Enter this rule and then assert (John Smith).  When you run, you'll see that 
  169. John Smith finally gets married.
  170.    Suppose John has a brother whose first name is Smith (their parents liked 
  171. simple names).  Will this rule make Smith Smith get married too? 
  172.   Assert (Smith Smith) and run again.  You'll see that there will be a double 
  173. wedding indeed.
  174.    Notice that the conditional element (?first ?last) matched any two symbolic 
  175. atoms while (?name ?name) required that the two atoms were the 
  176.  same.
  177.  
  178.  
  179. How To Make John Very, Very Happy
  180.  
  181.  
  182. The (assert) can be used with (retract) to produce some interesting effects.  
  183. As a simple example, suppose we wanted to make John not just happy, 
  184.  but very, very happy.  The following program shows how John can become very, 
  185. very happy.  Enter it and assert (John Smith).  Be sure to save 
  186.  the program before you run it.
  187.  
  188.  
  189. (defrule ecstatic
  190.    ?bachelor <- (?first ?last)
  191. =>
  192.    (printout ?first " " ?last " is a happy man" crlf)
  193.    (retract ?bachelor)
  194.    (assert (?first ?last)))
  195.  
  196.    The program executes an infinite loop since it asserts a new (John Smith) 
  197. after retracting the old ?bachelor.  Note that to make a new (John 
  198.  Smith) you must assert the individual atoms such as ?first and ?second.  CLIPS 
  199. is not designed to allow assertions of entire facts with statements 
  200.  like (assert (?bachelor)).  After the new (John Smith) is asserted, the rule 
  201. then fires on the new (John Smith).
  202.    The only way to stop an infinite loop like this is by interrupting CLIPS.  
  203. Use a Control C or appropriate interrupt command for your computer. 
  204.   You'll have to restart CLIPS again.
  205.    Will the program still produce an infinite loop if you remove the (retract) 
  206. statement?  The answer is no since the new attempted assertions 
  207.  are duplicates of the fact in memory.
  208.  
  209.  
  210. Who's Eligible
  211.  
  212.  
  213. Rather than having to specify a certain fact to trigger a rule, you can just 
  214. specify a general conditional element using a wildcard.  For example, 
  215.  suppose you're running a dating service and a woman specifies that she only 
  216. dates men whose first name is John.  There are really two criteria 
  217.  in this specification since there is an implication that the man must have 
  218. more than one name.  So a plain (John) will not do because there 
  219.  is only one name in the fact.
  220.    This type of situation in which only part of the fact is specified is very 
  221. common and very important.  To solve this problem, a wildcard can 
  222.  be used to fire a rule to print out the John's.
  223.    The simplest form of wildcard is called a single-field wildcard and is shown 
  224. by a question mark, "?".  A single-field wildcard stands for 
  225.  one atom.  The following rule and deffacts show how a wildcard can be used.  
  226. Enter and run.
  227.  
  228. (defrule eligible
  229.    (John ?)
  230. =>
  231.    (printout "There is an eligible John" crlf))
  232.  
  233. (deffacts bachelors
  234.    (Tom)
  235.    (John)
  236.    (John Smith)
  237.    (John Henry)
  238.    (John Henry Smith))
  239.  
  240.    The conditional element includes a wildcard to indicate that John's last 
  241. name is not important.  So long as his first name is John, the rule 
  242.  will be satisfied and fire.  Because the wildcard is in the second field, that 
  243. is, the position of the second atom of a fact, only facts of 
  244.  two atoms can possibly satisfy the rule.  In other words, only John's with 
  245. exactly two names need apply.
  246.    Suppose you want to specify John's with exactly three names?  All you'd have 
  247. to do is write a conditional element like
  248.  
  249. (John ? ?)
  250.  
  251. or if only persons with three names whose middle name was John
  252.  
  253. (? John ?)
  254.  
  255. or if only the last name was John
  256.  
  257. (? ? John)
  258.  
  259.    Another interesting possibility is if the the John must be the first name, 
  260. but only those with two or three names are acceptable.  One way 
  261.  of solving this problem is to write two rules.  For example
  262.  
  263. (defrule eligible
  264.    (John ?)
  265. =>
  266.    (printout "There is an eligible John" crlf))
  267.  
  268. (defrule eligible-three-names
  269.    (John ? ?)
  270. =>
  271.    (printout "There is an eligible John" crlf))
  272.  
  273. Enter and run this and you'll see that both the John's with two and three names 
  274. are printed.
  275.  
  276.  
  277. Going Wild
  278.  
  279.  
  280. Rather than writing separate rules to handle each field, it's much easier to 
  281. use the multi-field wildcard.  The multi-field wildcard is a dollar 
  282.  sign followed by a question mark, "$?", and represents zero or more occurences 
  283. of an atom.  The two rules for eligibility can now be written 
  284.  in a single rule as follows.  Also shown is the deffacts of eligible bachelors.
  285.  
  286. (defrule eligible
  287.    (John $?)
  288. =>
  289.    (printout "There is an eligible John" crlf))
  290.  
  291. (deffacts bachelors
  292.    (Tom)
  293.    (John)
  294.    (John Smith)
  295.    (John Henry)
  296.    (John Henry Smith))
  297.  
  298. When you enter and run, you'll see that the rule fires four times since there 
  299. are four (John) facts.
  300.    Wildcards have another important use because they can be attached to a 
  301. symbolic atom to create a variable such as ?x, $?x, ?name, $?name. 
  302.   You've already seen examples of single-field variables at the beginning of 
  303. this chapter.  Now you can understand why the variables had a "?" 
  304.  in front.  The attached variable will be equated to either a single-field 
  305. wildcard if only the "?" is used or a multi-field wildcard, "$?", 
  306.  if that is used.
  307.    As example of a multi-field variable, the following version of the rule also 
  308. prints out the name of the matching fact because a variable is 
  309.  equated to the name that matches.
  310.  
  311. (defrule eligible
  312.    (John $?name)
  313. =>
  314.    (printout "There is an eligible John " $?name crlf))
  315.  
  316. When you enter and run, you'll see the names of all the eligible John's.  The 
  317. multi-field wildcard takes care of any number of atoms.  No matter 
  318.  how long John's other names are, the multi-field wildcard will take care of it.
  319.    What do you think the matches would be if the conditional element was 
  320. ($?name) alone?  Try it and you'll see that the rule matches to every 
  321.  fact, even (Tom).
  322.    Suppose you wanted a match of all people who had a John somewhere in their 
  323. name, not necessarily as their first name.  Notice that this requirement 
  324.  is not the same as in the previous rule.  Some possible matches would be
  325.  
  326. (John)
  327. (Tom John)
  328. (Tom Henry John)
  329. (Tom John Henry)
  330. (Tom Henry John Smith)
  331.  
  332.    The following version of the rule would match all facts with a John in them 
  333. and print out the names.
  334.  
  335. (defrule eligible
  336.    ($?first John $?last)
  337. =>
  338.    (printout "There is an eligible " $?first " John " $?last crlf))
  339.  
  340. Enter and run this rule and you'll see all the matching John's.  The 
  341. conditional element matches any names that have a John anywhere in them.
  342.    Single and multi-field wildcards can be combined.  For example, the 
  343. conditional element
  344.  
  345. (? $? John ?)
  346.  
  347. means that the first and last names can be anything, and that the name just 
  348. before the last must be John.  For example,
  349.  
  350.            Name                   Match
  351.    (John)                          No
  352.    (John Smith)                    No
  353.    (Tom John Smith)                Yes
  354.    (Tom John Henry Smith)          No
  355.    (Tom Henry John Smith)          Yes
  356.  
  357. Note that the "$?" can match zero or more occurences of an atom.  Matching zero 
  358. occurences means that there can be a match with no atom.  So 
  359.  a conditional element like ($?name) will match any fact.  In contrast, the "?" 
  360. requires an atom to match.
  361. .PA
  362.                             Problems
  363.  
  364.  
  365. 1.  A factory has different bars in stock.  The ID and dimensions of the stock 
  366. are given as follows.
  367.  
  368.                    ID     Length   Width   Height
  369.                   Fe-1      10       10      10
  370.                   Cu-2      20       10      10
  371.                   Cu-3      20       10      20
  372.                   Pt-4      10       20      10
  373.                   Fe-5      30       30      10
  374.                   Fe-6      30       20      10
  375.                   Fe-7      10       30      20
  376.                   Cu-8      10       20      30
  377.                   Pt-9      30       20      10
  378.                   Pt-10     20       20      20
  379.                              Table 4.1
  380.  
  381.    Write a program that will classify the bar stock according to the following 
  382. definitions. 
  383.  
  384.    square cross section - length=width
  385.    square side - width=height
  386.    cubes - length=width=height
  387.  
  388.  The program should print out the stock ID and all the dimensions of stock that 
  389. matches the definitions.  Objects may be in more than one category. 
  390.   For example, a cube will also be listed as having square cross section and 
  391. square side.
  392.    The priority of printing should be all the cubes, then all square cross 
  393. section, and then all those with square sides.  Finally the program 
  394.  should print out the complete inventory exactly as shown in Table 4.1.
  395.  
  396. 2.  Write a program to print all permutations of the facts (John), (Henry), and 
  397. (Smith).  That is the program should print all the possible combinations 
  398.  of the three facts, such as
  399.  
  400. John Henry Smith
  401. John Smith Henry
  402. Henry John Smith
  403.  
  404. and so forth.
  405.  
  406.  
  407.