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

  1.            Chapter 5   A Little Math
  2.  
  3.  
  4.  
  5.  
  6. Besides dealing with symbolic facts, CLIPS can also perform calculations.  
  7. Although CLIPS was not designed for efficiency in number crunching, 
  8.  it can do a wide variety of math operations.  You'll find the computational 
  9. capability of CLIPS useful in many applications.
  10.  
  11.  
  12. Two Packages
  13.  
  14.  
  15. CLIPS is available in different packages so that you can customize it to fit 
  16. your needs.  The standard CLIPS kernal provides only the basic arithmetic 
  17.  operations such as addition, subtraction, multiplication and division.
  18.    The CLIPS source disk has both the kernal as well as a math library of C 
  19. routines.  You can link and compile this library with the kernal 
  20.  to produce an enhanced CLIPS with a very powerful library of math functions.  
  21. The math library is included as an example of how users can enhance 
  22.  CLIPS to suit their needs.  The disadvantage of the math library version of 
  23. CLIPS is that it adds to the size of CLIPS.  The amount of extra 
  24.  memory required will depend on your compiler.
  25.    An expert system language like CLIPS is not designed to produce application 
  26. programs that do a lot of calculations.  Although the math functions 
  27.  of CLIPS are very powerful, they are primarily meant for modification of 
  28. numbers that are being reasoned about by the application program.  
  29.  Other languages such as FORTRAN are better for number crunching in which 
  30. little or no reasoning about the numbers is done. 
  31.  
  32.  
  33. Let's Be Precise
  34.  
  35.  
  36. Since CLIPS is designed for portability, it can be put on many different models 
  37. of computers.  However, different models usually treat numbers 
  38.  in different forms.  You should work through the examples in this chapter 
  39. carefully on your computer and note any differences.
  40.    In particular, any rules which depend on a numeric value in a conditional 
  41. element may lead to problems in portability of CLIPS code from one 
  42.  model of computer to another.  All of the examples in this book were done on 
  43. an IBM PC XT and should be fairly close to what you'll see on other 
  44.  computers using single-precision, floating point arithmetic.
  45.    As an example of the way CLIPS displays numbers, enter the following 
  46. (deffacts) or just (assert) the numbers.
  47.  
  48. (deffacts math
  49.    (0)
  50.    (1)
  51.    (-5)
  52.    (1.5)
  53.    (-.000123456)
  54.    (123456)
  55.    (1.33e7)
  56.    (2.5e+4)
  57.    (-6.924e-10)
  58.    (1e50)
  59.    (1e-50))
  60.  
  61.    After you do a (reset), check (facts) and you'll see facts like the 
  62. following.  Brief comments have been inserted to explain the facts while 
  63.  a more detailed discussion follows.
  64.  
  65. f-1     (0)
  66. f-2     (1)   ;really floating point, just appearance of integer
  67. f-3     (-5)  ;see note for f-2
  68. f-4     (1.5) ;unchanged appearance from asserted fact
  69. f-5     (-0.00012346) ;note round-off to five significant digits
  70. f-6     (1.2346E+05)  ;see note for f-5,also exponential notation
  71. f-7     (1.3300E+07)  ;false precision displayed
  72. f-8     (25000)       ;see note for f-2,also now fixed notation
  73. f-9     (-6.9240E-10) ;see note for f-7
  74. f-10    (3.4028E+38)  ;this fact and
  75. f-11    (0)           ;this one are not correct because they exceed the numeric 
  76. limits of the compiler used for CLIPS.  Different compilers will 
  77.  have different limits.
  78.  
  79.    Even the appearance of facts can be deceptive if the numbers 
  80. exceed the range allowed by the compiler you used for CLIPS.  For example, on 
  81. some compilers, the asserted fact (1e-50) might be really stored 
  82.  as 0 if it's smaller than the smallest number allowed by the compiler.  On 
  83. other compilers, it might really be stored as 1e-50.
  84.    Numbers whose absolute magnitude are smaller than 0.0001 or greater than or 
  85. equal to 100000 will be expressed in exponential notation.  Numbers 
  86.  with absolute magnitude from 0.0001 to less than 100000 will be expressed in 
  87. fixed form, even if entered in exponential notation.
  88.    The precision of a number refers to how many significant digits it has.  For 
  89. example, the numbers 1.23e-3 and 0.000123 both have three significant 
  90.  digits.  Leading zeroes do not count in determining the number of significant 
  91. digits.
  92.    The accuracy of a number refers to the truth of the number.  For example, 
  93. suppose the height of a chair is measured with a ruler which has 
  94.  divisions to a millimeter as 0.712 meters.  Then suppose the same chair is 
  95. measured with another ruler which has rulings of only tenths of a 
  96.  meter as 0.4 meters.  Notice that the measurements are quite different.  Which 
  97. is correct?  At first you might say that the 0.712 reading is 
  98.  correct since it has more significant digits.  But that is not necessarily so. 
  99.  It could be that the first ruler was incorrectly calibrated. 
  100.   While 0.712 is certainly more precise it may not be more accurate.
  101.    The precision and range of numbers in CLIPS will depend on the compiler that 
  102. you use to compile it.  CLIPS will normally show five significant 
  103.  digits and this should be the same in all implementations.  However, the 
  104. internal precision in which numbers are represented may vary from one 
  105.  compiler to another and this can affect the triggering of rules.
  106.    Sometimes a false precision can be shown, as in the case of f-7.  Note that 
  107. the asserted fact (1.33e7) has only three significant digits and 
  108.  yet CLIPS shows five significant digits.  Although leading zeroes are not 
  109. significant, trailing zeroes are significant.  So 1.3300E+07 is shown 
  110.  as if it was known more precisely.  All we really know is that the original 
  111. asserted fact of 1.33e7 was within the range 1.334e7 to 1.330e7. 
  112.   A number greater than 1.334e7 would have been expressed as 1.35e7 while a 
  113. number smaller than 1.330e7 would have been written as 1.29e7.   
  114.    The appearance of false precision arises because CLIPS is designed to always 
  115. show five significant digits.  However, the false precision will 
  116.  not hurt your calculations since it is just the displayed appearance.  It's 
  117. only important that when you interpret the final results that you 
  118.  realize they cannot be more precise than the most imprecise number.
  119.    As an example of how the precision of numbers affects rule firing, enter the 
  120. following.
  121.  
  122. (defrule num-check
  123.    (1.5)
  124. =>
  125.    (printout "valid number" crlf))
  126.  
  127. When you (assert (1.5)) the rule will fire.  Now retract the fact and assert 
  128. 1.5000001.  On an IBM PC where CLIPS was compiled with the Lattice 
  129.  C Compiler, the fact was stored as (1.50000012) as shown by a (facts).  In 
  130. this case the rule would not fire.  However, if the fact 1.50000001 
  131.  was asserted, the fact was stored as 1.5 and so the rule did fire.
  132.    Depending on your implementation of CLIPS, you may need more zeroes to make 
  133. the rule fire.  But eventually, the number that you assert will 
  134.  be less than the precision of CLIPS and the rule will fire.  So if you design 
  135. a program with conditional elements which include numbers, you 
  136.  should consider the precision and range of numbers that will cause erroneous 
  137. rule firings.  Conditional elements which depend on numbers should 
  138.  be examined very carefully, especially if you plan to run the program on a 
  139. different model of computer later.
  140.    If you need a lot of precision with decimal numbers, be careful since most 
  141. compilers produce code using binary number representation.  This 
  142.  can lead to inaccurracy and imprecision.  For more details on binary numbers 
  143. and imprecision, see BASIC: Advanced Concepts by J. Giarratano, 
  144.  published by Howard W. Sams, Inc. 
  145.  
  146.  
  147. It's Elementary
  148.  
  149.  
  150. CLIPS provides the elementary arithmetic operators as shown in the following 
  151. table.
  152.  
  153.        CLIPS Operators
  154.    +    addition
  155.    -    subtraction
  156.    *    multiplication
  157.    /    division
  158.    **   exponentiation
  159.  
  160. All arithmetic and numbers are in floating point.
  161.    Numeric expressions are represented in CLIPS according to the style of LISP. 
  162.  In LISP and CLIPS, a numeric expression that you would customarily 
  163.  write as 2 + 3 must be written in the LISP and CLIPS prefix form, (+ 2 3).  
  164. The customary way of writing numeric expressions is called infix 
  165.  form because the math operators are in between the operands or arguments.  In 
  166. the prefix form of CLIPS, the operator must go before the operands 
  167.  and parentheses must surround the numeric expression.
  168.    One way of evaluating a numeric expression in CLIPS is using the = 
  169. comparison function in an (assert) action.  The general form of an arithmetic 
  170.  calculation in CLIPS with two arguments is
  171.  
  172. (operator arg arg)
  173.  
  174. where "operator" can be any of the arithmetic operators and "arg" stands for 
  175. the argument used by the operator.
  176.    To see how these arithmetic operations perform on your computer, enter the 
  177. following rules, then assert (numbers 2 3) and run.  Also shown 
  178.  by each rule is a comment describing what each rule does.  Note that the 
  179. comment is in infix notation for your information only.  Infix cannot 
  180.  be used in a rule.
  181.  
  182. (defrule addition
  183.    (numbers ?x ?y)
  184. =>
  185.    (assert (=(+ ?x ?y))))   ; ?x + ?y
  186.  
  187. (defrule subtraction
  188.    (numbers ?x ?y)
  189. =>
  190.    (assert (=(- ?x ?y))))   ; ?x - ?y
  191.  
  192. (defrule multiplication
  193.    (numbers ?x ?y)
  194. =>
  195.    (assert (=(* ?x ?y))))   ; ?x * ?y
  196.  
  197. (defrule division
  198.    (numbers ?x ?y)
  199. =>
  200.    (assert (=(/ ?x ?y))))   ; ?x / ?y
  201.  
  202. (defrule exponentiation
  203.    (numbers ?x ?y)
  204. =>
  205.    (assert (=(** ?x ?y))))  ; ?x ** ?y
  206.  
  207. After you run, check the facts.  The answer for division will probably show a 
  208. round-off error in the last digit.
  209.    At the present time, CLIPS is not designed to evaluate numeric expressions 
  210. at the top-level.  So you cannot assert a top-level command like 
  211.  (assert (=(+ 2 3))).  Numeric evaluation must be done within a rule.
  212.    In a rule, you can assert other atoms along with a numeric expression.  For 
  213. example, the addition rule could be
  214.  
  215. (defrule addition
  216.    (numbers ?x ?y)
  217. =>
  218.    (assert (sum =(+ ?x ?y))))
  219.  
  220. Be sure to put a space between the atom "sum" and the following "=".  Remember 
  221. that a space must separate atoms in a fact.  The "=" tells CLIPS 
  222.  to evaluate the following fact before asserting it.  So "=(+ ?x ?y)" is 
  223. evaluated as 2 + 3 = 5 and the resulting atom of 5 is used for the assertion 
  224.  (sum 5).  Run this version of the rule and you'll see the fact (sum 5).
  225.  
  226.  
  227. Extensive Arguments
  228.  
  229.  
  230. The arguments in a numeric expression can be extended beyond two for all 
  231. operators except exponentiation.  The same sequence of arithmetic calculations 
  232.  is performed for more than two arguments.  The following example shows how 
  233. three arguments are used.  Evaluation proceeds from left to right.
  234.  
  235. (defrule addition
  236.    (numbers ?x ?y ?z)
  237. =>
  238.    (assert (=(+ ?x ?y ?z))))  ; ?x + ?y + ?z
  239.  
  240. (defrule subtraction
  241.    (numbers ?x ?y ?z)
  242. =>
  243.    (assert (=(- ?x ?y ?z))))  ; ?x - ?y - ?z
  244.  
  245. (defrule multiplication
  246.    (numbers ?x ?y ?z)
  247. =>
  248.    (assert (=(* ?x ?y ?z))))  ; ?x * ?y * ?z
  249.  
  250. (defrule division
  251.    (numbers ?x ?y ?z)
  252. =>
  253.    (assert (=(/ ?x ?y ?z))))  ; ?x / ?y / ?z
  254.  
  255.    Enter the above program and assert (numbers 2 3 4).  After you run the 
  256. program, you'll see the following facts.  Note that the division fact, 
  257.  f-5, may be different on your computer because of the compiler you used for 
  258. CLIPS.
  259.  
  260. f-2     (9)
  261. f-3     (-5)
  262. f-4     (24)
  263. f-5     (0.16666667)
  264.  
  265.    The infix equivalent of a multiple argument CLIPS expression can be 
  266. expressed in the following general way.
  267.  
  268. arg operator arg operator arg operator arg ...
  269.  
  270. where the dots, "...", symbolize the pattern repeated.  Another way of 
  271. symbolizing this is
  272.  
  273. arg [operator arg]
  274.  
  275. where the square brackets mean that there can be multiple terms.  Note that you 
  276. cannot write a CLIPS expression with dots or square brackets. 
  277.   The dots and brackets are just a shorthand notation. 
  278.  
  279. Mixed Results
  280.  
  281.  
  282. Mixed calculations can also be done in the prefix notation.  For example, 
  283. suppose you want to evaluate the infix expression
  284.  
  285. ?x + ?y * ?z
  286.  
  287. One important fact about CLIPS and LISP calculations is that there is no 
  288. built-in precedence of arithmetic operations.  That is, in other computer 
  289.  languages, multiplication and division rank higher than addition and 
  290. subtraction and the computer does the higher ranked operations first.  
  291.  However, in LISP and CLIPS, there is no built-in precedence.  Everything is 
  292. simply evaluated from left to right with parentheses determining 
  293.  precedence.
  294.    In the example of ?x + ?y * ?z, the customary way to evaluate it is to 
  295. multiply ?y by ?z and then add the result to ?x.  However, in CLIPS, 
  296.  you must explicitly write the precedence.  The example would be written in the 
  297. following rule.
  298.  
  299. (defrule mixed-calc1
  300.    (numbers ?x ?y ?z)
  301. =>
  302.    (assert (result =(+ ?x (* ?y ?z)))))  ; ?x * ?y + ?z
  303.  
  304. In this rule, the innermost parentheses is evaluated first and so ?y is 
  305. multiplied by ?z.  The result is then added to ?x.  Also, note that you 
  306.  don't need an "=" function until the final atom is to be asserted.  That is, 
  307. you don't need to put an "=" in front of every operation in parentheses.
  308.    If you wanted ?x + ?y * ?z, where again multiplication is done first, the 
  309. rule would be
  310.  
  311. (defrule mixed-calc2
  312.    (numbers ?x ?y ?z)
  313. =>
  314.    (assert (result =(+ (* ?x ?y) ?z))))  ; ?x * ?y + ?z
  315.  
  316. Enter and run these rules for the (numbers 2 3 4) and see if the results are as 
  317. expected.
  318.  
  319.  
  320. Binding Things Up
  321.  
  322.  
  323. In order to print out the value of a math calculation, the result must first be 
  324. bound to a variable using the bind function.  The bound variable 
  325.  can then be printed out.  For example,
  326.  
  327. (defrule addition
  328.    (numbers ?x ?y)
  329. =>
  330.    (assert (answer (=(+ ?x ?y))))
  331.    (bind ?answer (+ ?x ?y))
  332.    (printout "answer is " ?answer crlf))
  333.  
  334. Enter and run this and you'll see that the answer is printed out as well as 
  335. asserted.
  336.    Notice the difference in syntax between the (assert) with its "=" function 
  337. and the bind which does not use the "=".  The bind function does 
  338.  not use the "=" because CLIPS assumes that whatever follows the variable 
  339. argument in a bind should be evaluated.  In contrast, when CLIPS encounters 
  340.  an (assert), it does not know at first if an argument is to be evaluated.  So 
  341. an "=" is necessary to tell CLIPS that the argument in the (assert) 
  342.  should be evaluated.
  343.  
  344.  
  345. What's At The Root
  346.  
  347.  
  348. The math functions can return a value if they are bound to a variable using the 
  349. bind function.  The following example shows how the square root 
  350.  function is first bound and then printed out.
  351.  
  352. (defrule square-root
  353.    (number ?value)
  354. =>
  355.    (bind ?answer (sqrt ?value))
  356.    (printout "square root of " ?value " is " ?answer crlf))
  357.  
  358. To run, first assert a fact such as (number 4).
  359.    The bind function can be used to bind any atom to a variable.  For example,
  360.  
  361. (defrule bind-test
  362.    (number ?value)
  363. =>
  364.    (bind ?answer ?value)
  365.    (printout "answer is " ?answer crlf))
  366.  
  367. will bind ?answer to ?value.  Try running this after asserting (number 4) and 
  368. you'll see the answer of 4.
  369.    Math functions can be included in arithmetic expressions using prefix 
  370. notation as shown following.
  371.  
  372. (defrule square-root
  373.    (number ?value)
  374. =>
  375.    (bind ?answer (+ 4 (sqrt ?value)))
  376.    (printout "square root of " ?value " is " ?answer crlf))
  377.  
  378. If you assert (number 4) and run, you'll see the answer of 6 printed out from 
  379. ?answer.  Math functions are treated just like any other argument 
  380.  in a numeric expression, except that they require parentheses around them.
  381.  
  382.  
  383. Math Functions
  384.  
  385.  
  386. Following is a list of the math functions in the math library.  To access these 
  387. functions, you must first link the library to the CLIPS kernal 
  388.  and compile it to produce the math version of CLIPS.  The math version will 
  389. execute just like CLIPS with the added enhancement that you can 
  390.  access all of the following math functions. 
  391.  
  392.    Note: all trig functions are expressed in radians.
  393.          <fun> stands for a function.
  394.          <arg> stands for the one argument of the function.
  395.         
  396.  
  397.                   Trig And Hyperbolic Functions
  398.  
  399.         Format : (<fun> <arg>)
  400.  
  401.         Example:    (defrule trigtest
  402.                        (number ?value)
  403.                     =>
  404.                        (bind ?z (sin ?value)))
  405.  
  406.                     (assert (number 1))
  407.  
  408.         In the above example, ?z will be bound to the sine of 1.
  409.  
  410.  
  411.                 Standard Trigonometric Functions
  412.  
  413.                                sin
  414.                                cos
  415.                                tan
  416.                                sec
  417.                                csc
  418.                                cot
  419.  
  420.  
  421.                  Inverse Trigonometric Functions
  422.  
  423.                               acos
  424.                               asin
  425.                               atan
  426.                               asec
  427.                               acsc
  428.                               acot
  429.  
  430.  
  431.                       Hyperbolic Functions
  432.  
  433.                               cosh
  434.                               sinh
  435.                               tanh
  436.                               sech
  437.                               csch
  438.                               coth
  439.  
  440.  
  441.                   Inverse Hyperbolic Functions
  442.  
  443.                               acosh
  444.                               asinh
  445.                               atanh
  446.                               asech
  447.                               acsch
  448.                               acoth
  449.  
  450.  
  451.                   Maximum And Minimum Functions
  452.  
  453. The following functions return the minimum and maximum of a set of numbers.  
  454. The double angles, "<<" and ">>", around the arguments indicate 
  455.  one or more arguments are allowed.
  456.  
  457.         Format : (<fun> <<arg>>)
  458.  
  459.         min    : returns the minimum argument
  460.  
  461.         max    : returns the maximum argument
  462.  
  463.         Example:    (defrule test
  464.                        (numbers ?x ?y)
  465.                     =>
  466.                        (bind ?z (min ?x ?y)
  467.                        (bind ?w (max ?x ?y)))
  468.  
  469.                     (assert (numbers 2 3))
  470.  
  471.                     In the above example, ?z will be bound to 2.                
  472.                           ?w will be bound to 3.
  473.  
  474.  
  475.                         Modulus Function
  476.  
  477. The modulus function returns the modulus of the first argument by the second 
  478. argument.  The modulus is defined as the integer result of division 
  479.  of the first argument by the second.  Since CLIPS deals only with floating 
  480. point numbers, the modulus is returned as a floating point number 
  481.  instead of the standard integer.
  482.  
  483.         Format : (mod <arg> <arg>)
  484.  
  485.         Example:    (defrule modtest
  486.                        (numbers ?x ?y)
  487.                     =>
  488.                        (bind ?z (mod ?x ?y))
  489.  
  490.                     (assert (numbers 3 2))
  491.  
  492.         In the above example, ?z is bound to 1.
  493.  
  494.  
  495.                           Log Functions
  496.  
  497.         log   : returns the log to base e
  498.  
  499.         log10 : returns the log to base 10
  500.  
  501.         Format : (<fun> <arg>)
  502.  
  503.         Example:    (defrule logtest
  504.                        (number ?value)
  505.                     =>
  506.                        (bind ?z (log ?value))
  507.                        (bind ?w (log10 ?value)))
  508.  
  509.                     (assert (number 5))
  510.              
  511.         In the above example, ?z will be bound to the log of 5         while ?w 
  512. will be bound to the log to base 10 of 5.
  513.  
  514.  
  515.                       Exponential Function
  516.  
  517.         exp    : returns e raised to the power of the argument,                
  518. that is, e**arg
  519.  
  520.         Format : (exp <arg>)
  521.         
  522.         Example:    (defrule exptest
  523.                        (number ?value)
  524.                     =>
  525.                        (bind ?z (exp ?value)))
  526.  
  527.                     (assert (number 1))
  528.         
  529.         In the above rule, ?z is bound to exp of 1.
  530.  
  531.  
  532.                            Square Root
  533.  
  534.         sqrt   : returns the square root of the argument
  535.                                                                     
  536.         Format : (sqrt <arg>)
  537.  
  538.         Example:    (defrule sqrtest
  539.                        (number ?value)
  540.                     =>
  541.                        (bind ?z (sqr ?value)))
  542.  
  543.                     (assert (number 4))
  544.  
  545.         In the above example, ?z is bound to the square root of         4.
  546.                             Problems
  547.  
  548.  
  549. 1.  Check the limits of accuracy on your computer.  Assert 
  550. (number 1e-38)
  551. (number 1e-50)
  552. (number 1e-70)
  553.  
  554. and see how often the rule
  555.  
  556. (defrule test-limit
  557.    (number 0)
  558. =>
  559.    (printout "Rule fires" crlf))
  560.  
  561. fires.  Use (watch rules) and (watch facts) commands to see which facts are 
  562. triggering the rules.  Assert other numbers to narrow down the limit 
  563.  of the largest number that will be interpreted as 0.
  564.  
  565.  
  566. 2.  Write a program to calculate the area of various geometric shapes.  If the 
  567. user asserts one of the following facts, the program will calculate 
  568.  and print out the area.  If something is asserted that is not one of the 
  569. shapes shown, the program should print out an error message.  Run for 
  570.  the examples shown.  For Pi, assert (Pi 3.14159).
  571.  
  572.   Examples                   Meaning               Area
  573. (square 10)           (square side)             S * S
  574. (triangle 6 20)       (triangle base height)    1 / 2 * B * H
  575. (rectangle 5 3)       (rectangle length width)  L * W
  576. (circle 3)            (circle radius)           Pi * R * R
  577.  
  578.  
  579.