home *** CD-ROM | disk | FTP | other *** search
- Chapter 12 The Great Expansion
-
-
-
-
- In the preceeding chapters of this book, you've learned the syntax of CLIPS.
- However, CLIPS has an additional feature that greatly extends its
- capabilities by allowing you to define your own functions. If you are an
- experienced C programmer, you can learn from this chapter how to make
- your own customized version of CLIPS.
-
-
- Random Problems
-
-
- In order to make your own user defined functions, you should have knowledge of
- C, since CLIPS is written in C. The following description of
- how to add a function assumes you know the C language and how to compile
- programs in C. The description is for an implementation on an IBM
- personal computer using the Lattice C compiler, and also for a UNIX based
- system. However, it should be understandable for other C implementations
- also.
- If you are using an IBM personal computer, you will probably not be able to
- compile CLIPS on a floppy disk system because the object code
- files are so large. Even using RAM disks and a 640 K machine will still give
- trouble in compiling. A hard disk is really necessary.
- The user defined function to be added to CLIPS is a random number generator.
- There are many cases in which a random number generator is of
- use. Since a random number generator is not provided in the CLIPS syntax or
- in the math library, let's write a user defined function and add
- it to CLIPS.
- As a first step in adding the random function, create a file called rand.c
- or a name appropriate to your system. The random number generator
- used will be the simple random number function provided by the Lattice C
- compiler, rand.
-
- #include <math.h>
- #include <stdio.h>
- #include "clips.h"
-
- float my_rand()
- {
- extern int rand();
- return ((float) rand());
- }
-
- The name "my_rand()" can be any name you want. The rand function must be
- declared extern because it is not defined in the rand.c file. Normally,
- the rand function returns integers. But since CLIPS only uses floating point
- numbers, it is cast as a float in the return statement.
- The second step in adding the random function is to modify the main.c file.
- The statements which have been modified are shown with comments
- that include an "!" as in "/***!" in the USRFUNCS() section at the end.
-
- /* CLIPS: main.c (V3.01) Last modified 7/21/86 */
-
- #include <stdio.h>
-
- /***************************************************************/
- /* MAIN: Start execution of CLIPS. This function must be */
- /* redefined in order to embed CLIPS within another program. */
- /* Example of redefined main: */
- /* main() */
- /* { */
- /* init_clips(); */
- /* . */
- /* . */
- /* . */
- /* process_data(); */
- /* run(-1); */
- /* evaluate_data(); */
- /* . */
- /* . */
- /* . */
- /* final_results(); */
- /* } */
- /***************************************************************/
- main()
- {
- printf(" CLIPS (V3.01 7/21/86)\n");
- init_clips();
- command_loop();
- }
-
- /*************************************************************/
- /* USRFUNCS: The function which informs CLIPS of any user */
- /* defined functions. In the default case, there are no */
- /* user defined functions. To define functions, either */
- /* this function must be replaced by a function with the */
- /* same name within this file, or this function can be */
- /* deleted from this file and included in another file. */
- /* User defined functions may be included in this file or */
- /* other files. */
- /* Example of redefined usrfctns: */
- /* usrfuncs() */
- /* { */
- /* define_function("fun1",'i',fun1); */
- /* define_function("other",'f',other); */
- /* } */
- /*************************************************************/
-
- /***! THESE STATEMENTS ARE ADDED FOR THE RANDOM FUNCTION !***/
-
- usrfuncs()
- {
- extern mathfctns(); /***! includes the math library !***/
- extern float my_rand(); /***! add random function !***/
-
- mathfctns(); /***! includes the math library !***/
-
- define_function("rand",'f',my_rand); /***! add random !***/
- }
-
- The above changes also add the math library functions called mathfctns().
- Strictly speaking, it's not necessary to add the math library in
- this example for the random function. However, it's most likely you'll want
- to use both the math library and the random function generator
- and so both are shown.
-
-
- Lotta Links
-
-
- Once you have these two files created, it's time to compile them. On a UNIX
- system, enter
-
- cc -c rand.c
-
- To compile the rand.c file on a Lattice C compiler, you will have to enter a
- command specific to the directory storage of your files. The
- general form of the command is
-
- lcl =4096 rand.c -ml -n
- -i { Lattice include files }
- -i { CLIPS include files }
-
- where
- 4096 increases the stack size for the compiler
- -ml is for the large memory model option
- -n allows long variable names, greater than nine characters
-
-
- Depending on your directory structure, the Lattice include files "i option"
- may be
-
- -ic:\lattice\includes\
-
- if they are on drive c: in the directory \lattice\includes\.
-
- Likewise, if the CLIPS include files are on drive c: in the directory
- \clips\source\, then the "i option" command is
-
- -ic:\clips\source\
-
- Compile the main.c file in the same manner. The output of the compiler is an
- object code file which is then linked to the other CLIPS object
- files. Note that it is not neccessary to re-compile the other object files
- such as parser.o, clips.o, and so forth since they have not been
- changed.
- In a UNIX system, you should first copy all object versions of CLIPS files
- to your directory. This is a precaustion in case your linker cannot
- follow the path names to object files in other directories. The UNIX command
- to link the object modules is
-
- ld -o myclips rand,clips,main,math,sysdep,npsr,parser,usrint
-
- where myclips is the name of your customized version of CLIPS with the random
- function.
- The command for the linking with the Lattice C compiler will depend on the
- directories your object files are stored in. The general form
- of the link command is
-
- link { Lattice large memory link originator }
-
- The files to be linked are
-
- clips.o,rand.o,main.o,math.o,sysdep.o,npsr.o,
- parser.o,usrint.o,myclips,null,
-
- where myclips is the name of your customized version of CLIPS, and null is an
- option to the linker which says not to create a memory map. Note
- that the comma after the null is required. If you do not specify a name for
- the executable code, for example myclips, the linker will use the
- first argument, clips, as the name.
- In addition, you will also need to link the
-
- { Lattice large memory math library }
- +
- { Lattice large memory function library }
-
- The output should be the new CLIPS with the user defined random function.
-
-
- A Good Execution
-
-
- To test out the random function, start up CLIPS and enter this test program.
-
- (defrule random-test
- (initial-fact)
- =>
- (bind ?count 0)
- (while (< ?count 10)
- (bind ?rnd (rand)) ; call the random number function, rand
- (printout ?rnd crlf)
- (bind ?count (+ ?count 1))))
-
- When you run this program, it will generate 10 random numbers.
- Notice that a separate file was created for the random number function.
- Although you could add the appropriate statements to the math library
- file, math.c, it is definitely not a good idea. As new releases of CLIPS are
- given out, the math.c file will be updated and so you would have
- to modify it again. There is also the danger of your having a non-standard
- version of the math library. It is preferable to keep your functions
- in a separate personal math library file.
- The math.c file has some routines for testing the number of arguments to a
- function that you may find useful if you add functions with arguments
- to your personal math library. Note that the random function does not use
- arguments and so no testing is really neccessary. However, you may
- want to include argument testing in other functions.
-
-
-