home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource4 / 241_01 / rulecomp.cr < prev    next >
Text File  |  1987-08-31  |  11KB  |  406 lines

  1. /*
  2. HEADER:         CUG241;
  3. TITLE:          Rule-Based Compiler for Expert System;
  4. DATE:           12/30/85;
  5. VERSION:
  6. DESCRIPTION:   "Source code for rule-based compiler for an Expert System.  
  7.                 Main Program";
  8. KEYWORDS:       Artificial Intelligence, expert systems, rule-based compiler;
  9. SYSTEM:         MS-DOS or UNIX System V;
  10. FILENAME:       RULECOMP.C;
  11. WARNINGS:      "User-supported, author requests non-commercial use"
  12. AUTHORS:        George Hageman - Softman Enterprizes; 
  13. COMPILERS:      Microsoft C V3.00 or UNIX System V Portable C Compiler;
  14. REFERENCES:     AUTHOR:   William F. Clocksin, Christopher S. Mellish;
  15.                 TITLE:    "Programming in Prolog";
  16.  
  17.                 AUTHOR:   Mitch Derick, Linda Derick;
  18.                 TITLE:    "MVP-FORTH Expert-2 Tutorial";
  19.  
  20.                 AUTHOR:   Jack Park;
  21.                 TITLE:    "Expert Systems & the Weather - Dr. Dobb's Journal";
  22.                 CITATION:  "April 1984, pp. 24-28."
  23.  
  24.                 AUTHOR:   Jack Park;
  25.                 TITLE:    "MVP-FORTH Expert System Toolkit";
  26.  
  27.                 AUTHOR:   C. H. Ting;
  28.                 TITLE:    "Inside F83";
  29.  
  30.                 AUTHOR:   Patrick H. Winston, Berthold Klaus, Paul Horn;
  31.                 TITLE:    "LISP"
  32. ENDREF
  33. */
  34.  
  35. /*****************************************************************
  36. **                                **
  37. **      Inference -- (C) Copyright 1985 George Hageman    **
  38. **                                **
  39. **        user-supported software:                **
  40. **                                **
  41. **            George Hageman                **
  42. **            P.O. Box 11234                **
  43. **            Boulder, Colorado 80302            **
  44. **                                **
  45. *****************************************************************/
  46.  
  47. /*****************************************************************
  48. **    Expert system rule compiler
  49. **
  50. **    This compiler produces a file of the form:
  51. **
  52. **    Number_of_bytes_in_hypstack_section
  53. **    Hypstack_section
  54. **    Number_of_bytes_in_rule_section
  55. **    Rule base section
  56. **    Number_of_bytes_in_string_section
  57. **    String section
  58. **    EOF
  59. **    
  60. **    The rule section consits of integer flags and long-integer
  61. **    pointers to strings in the string section.
  62. **    
  63. **    All strings in the string section will be unique nomatter how
  64. **    many times they are repeated in the rules which are compiled
  65. **    into the rule base by this compiler.
  66. **
  67. **
  68. **    Usage:
  69. **
  70. **    rulecomp rule.file object.file
  71. **
  72. *****************************************************************/
  73.  
  74. /*****************************************************************
  75. **
  76. **    rule compiler main routine
  77. **
  78. *******************************************************************/
  79.  
  80. #include <stdio.h>
  81. #include <string.h>
  82.  
  83. #include "expert.h"
  84. #include "keywords.h"
  85.  
  86. int    main(argc,argv)
  87. int argc ;
  88. char **argv ;
  89.  
  90. {
  91. int    i ;
  92. int    state ;
  93. int    strAddr;
  94. int    numHypot, hypStack[MAX_HYPS],strBuffOfst ;
  95. char    strBuff[MAX_STRING_BUFF],c ;
  96. int    ruleBuffOfst ;
  97. int    keyWrdNum ;
  98. int    getKewWord() ;
  99. int    putString() ;
  100. int    lineNum ;
  101.  
  102. struct  rule_statement_r ruleBuff[MAX_RULE_STATEMENTS] ;
  103.  
  104. int    done ;
  105. FILE    *infile, *outfile ;
  106.  
  107. for( done = 0; done < MAX_STRING_BUFF; done ++ )
  108.     strBuff[done] = 0 ;
  109. for( done = 0; done < MAX_HYPS ; done++ )
  110.     hypStack[done]=0 ;
  111. done = FALSE ;
  112.  
  113. #ifdef    DEBUG
  114.     fprintf(stdout,"\nDEBUG-RULECOMP argc=%d ",argc) ;
  115. #endif
  116.  
  117. if(argc != 3 )
  118.     {
  119.     fprintf(stdout, "\n\n Usage: rulecomp in.file out.file\n\n" ) ;
  120.     exit() ;
  121.     }
  122. infile = fopen( argv[1], "r" );
  123. if(infile == NULL)
  124.     {
  125.     fprintf(stdout,"\n\n Cannot open input file %s ", argv[1]);
  126.     exit() ;
  127.     }
  128. outfile = fopen(argv[2], "wb" ) ;
  129. if(outfile == NULL)
  130.     {
  131.     fprintf(stdout,"\n\n Cannot open output file %s ",argv[2]);
  132.     exit() ;
  133.     }
  134. done = FALSE ;
  135.  
  136. numHypot = 0 ;                /* number of hypothesis is zero */
  137. strBuffOfst = 0 ;            /* pointer in buffer is zero */
  138. ruleBuffOfst = 0 ;            /* rule buffer offset is zero */
  139.  
  140.  
  141. state = ANTECEDENT ;
  142.  
  143. /* Compilation states:
  144. **
  145. **    Antecedent group in progress -- 1
  146. **    Consequent group in progress -- 2
  147. **
  148. **    If state 1 and you get a consequent then output group barrier.
  149. **        change state to 2.
  150. **    If state 2 and you get an antecedent then output group barrier.
  151. **        change state to 1.
  152. */
  153. lineNum = 1 ;
  154. printf("\n") ;
  155. while( !done )
  156.     {
  157.  
  158. /*
  159. **       get the key word number from the
  160. **    input file
  161. */
  162.     printf("%04d  ",lineNum++) ;
  163.     keyWrdNum = getKeyWord(infile,keyWords,&lineNum);
  164. /*
  165. **    error occured on line clear the line and
  166. **    start over.
  167. */
  168.     if(keyWrdNum == KEY_EOF)
  169.         {
  170.         done = TRUE ;
  171.         continue ;
  172.         }
  173.     if(keyWrdNum == KEY_WORD_ERROR)
  174.         {
  175.         while( ( (c = getc(infile))) != EOL && (c != EOF) )
  176.             putchar(c) ;
  177.         fprintf(stdout," **** KEY WORD not found on line " );
  178.         if(c == EOF)
  179.             {
  180.             done = TRUE ;
  181.             break ;
  182.             }
  183.         putchar(c) ;
  184.         continue;
  185.         }
  186. #ifdef    DEBUG
  187.     fprintf(stdout,"\nDEBUG-RULECOMP keyWrdNum = %d",keyWrdNum ) ;
  188. #endif
  189. /*
  190. **    based on the key Word build the
  191. **    rule files
  192. */
  193.  
  194.     switch(keyWrdNum)
  195.         {
  196.         case AND_N :
  197.         case ANDIF_N :
  198.         case IF_N :
  199. #ifdef    DEBUG
  200.     fprintf(stdout,"\nDEBUG-RULECOMP case AND_N, ANDIF_N, IF_N ") ;
  201. #endif
  202.             if(state == CONSEQUENT)
  203.                 {
  204.                 state = ANTECEDENT ;
  205.                 ruleBuff[ruleBuffOfst].flag = NULL ;
  206.                 ruleBuff[ruleBuffOfst++].string = NULL ;
  207.                 }
  208.             ruleBuff[ruleBuffOfst].flag = STRING_TRUE ;
  209.             strAddr=putString(infile,strBuff,&strBuffOfst) ;
  210.             ruleBuff[ruleBuffOfst++].string = strAddr ;
  211. #ifdef    DEBUG
  212.     fprintf(stdout,"\nDEBUG-RULECOMP strAddr= %d",strAddr ) ;
  213. #endif
  214.             break ;
  215.         case ANDRUN_N :
  216.         case ANDIFRUN_N :
  217.         case IFRUN_N :
  218. #ifdef    DEBUG
  219.     fprintf(stdout,"\nDEBUG-RULECOMP case AND_N, ANDIF_N, IF_N ") ;
  220. #endif
  221.             if(state == CONSEQUENT)
  222.                 {
  223.                 state = ANTECEDENT ;
  224.                 ruleBuff[ruleBuffOfst].flag = NULL ;
  225.                 ruleBuff[ruleBuffOfst++].string = NULL ;
  226.                 }
  227.             ruleBuff[ruleBuffOfst].flag = ROUTINE_TRUE ;
  228.             strAddr=putString(infile,strBuff,&strBuffOfst) ;
  229.             ruleBuff[ruleBuffOfst++].string = strAddr ;
  230. #ifdef    DEBUG
  231.     fprintf(stdout,"\nDEBUG-RULECOMP strAddr= %d",strAddr ) ;
  232. #endif
  233.             break ;
  234.         case ANDNOT_N :
  235.         case IFNOT_N  :
  236. #ifdef    DEBUG
  237.     fprintf(stdout,"\nDEBUG-RULECOMP case ANDNOT_N, IFNOT_N    ") ;
  238. #endif
  239.             if(state == CONSEQUENT)
  240.                 {
  241.                 state = ANTECEDENT ;
  242.                 ruleBuff[ruleBuffOfst].flag = NULL ;
  243.                 ruleBuff[ruleBuffOfst++].string = NULL ;
  244.                 }
  245.             ruleBuff[ruleBuffOfst].flag = STRING_FALSE ;
  246.             strAddr=putString(infile,strBuff,&strBuffOfst) ;
  247.             ruleBuff[ruleBuffOfst++].string = strAddr ;
  248. #ifdef    DEBUG
  249.     fprintf(stdout,"\nDEBUG-RULECOMP strAddr=%d",strAddr) ;
  250. #endif
  251.             break ;
  252.         case ANDNOTRUN_N :
  253.         case IFNOTRUN_N  :
  254. #ifdef    DEBUG
  255.     fprintf(stdout,"\nDEBUG-RULECOMP case ANDNOT_N, IFNOT_N    ") ;
  256. #endif
  257.             if(state == CONSEQUENT)
  258.                 {
  259.                 state = ANTECEDENT ;
  260.                 ruleBuff[ruleBuffOfst].flag = NULL ;
  261.                 ruleBuff[ruleBuffOfst++].string = NULL ;
  262.                 }
  263.             ruleBuff[ruleBuffOfst].flag = ROUTINE_FALSE ;
  264.             strAddr=putString(infile,strBuff,&strBuffOfst) ;
  265.             ruleBuff[ruleBuffOfst++].string = strAddr ;
  266. #ifdef    DEBUG
  267.     fprintf(stdout,"\nDEBUG-RULECOMP strAddr=%d",strAddr) ;
  268. #endif
  269.             break ;
  270.         case ANDTHEN_N :
  271.         case THEN_N :
  272.         case THENHYP_N :
  273.         case ANDTHENHYP :
  274. #ifdef    DEBUG
  275.     fprintf(stdout,"\nDEBUG-RULECOMP case ANDTHEN_N,THEN_N,THENHYP_N");
  276. #endif
  277.             if(state == ANTECEDENT)
  278.                 {
  279.                 state = CONSEQUENT ;
  280.                 ruleBuff[ruleBuffOfst].flag = NULL ;
  281.                 ruleBuff[ruleBuffOfst++].string = NULL ;
  282.                 }
  283.  
  284.             if( (keyWrdNum == THENHYP_N) || (keyWrdNum == ANDTHENHYP) )
  285.                 ruleBuff[ruleBuffOfst].flag = STRING_TRUE_HYP ;
  286.             else
  287.                 ruleBuff[ruleBuffOfst].flag = STRING_TRUE ;
  288.  
  289.             strAddr=putString(infile,strBuff,&strBuffOfst) ;
  290.             hypStack[numHypot++] = ruleBuffOfst ;
  291.             ruleBuff[ruleBuffOfst++].string = strAddr ;
  292. #ifdef    DEBUG
  293.     fprintf(stdout,"\nDEBUG-RULECOMP strAddr=%d",strAddr) ;
  294. #endif
  295.             break ;
  296.         case ANDTHENRUN_N :
  297.         case THENRUN_N :
  298.         case THENRUNHYP_N :
  299.         case ANDTHENRUNHYP_N :
  300. #ifdef    DEBUG
  301.     fprintf(stdout,"\nDEBUG-RULECOMP case ANDTHEN_N,THEN_N,THENHYP_N");
  302. #endif
  303.             if(state == ANTECEDENT)
  304.                 {
  305.                 state = CONSEQUENT ;
  306.                 ruleBuff[ruleBuffOfst].flag = NULL ;
  307.                 ruleBuff[ruleBuffOfst++].string = NULL ;
  308.                 }
  309.  
  310.             if( (keyWrdNu