home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / VRAC / CUJJUN93.ZIP / SUER01.C < prev    next >
C/C++ Source or Header  |  1993-04-12  |  27KB  |  813 lines

  1.  
  2. /*****************************************************/
  3. /* NATURAL.C   Copyright (c) 1993 Russell Suereth    */
  4. /*****************************************************/
  5.  
  6. /*****************************************************/
  7. /* This is the original natural language processor   */
  8. /* code plus expansions for tense and number.        */
  9. /*****************************************************/
  10.  
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <ctype.h>
  15. #include "natural.h"
  16.  
  17. void initialize(void);
  18. void reset_sentence(void);
  19. void get_record(char *);
  20. char *extract_word(void);
  21. int  match_record(char *, int);
  22. char *extract_root(void);
  23. int  check_underlying(void);
  24. int  check_type(char *,int);
  25. void get_aux(void);
  26. int  match_aux(void);
  27. void check_subject(void);
  28. void check_action(void);
  29. void check_place(void);
  30. void check_aux_verb(void);
  31. void check_number(void);
  32. void make_response(void);
  33. void make_answer(int);
  34. void get_verb(char, char, char);
  35. int  match_verb(char, char, char);
  36.  
  37. FILE *infile;
  38. char dic_record[80];
  39. int  sentence;
  40. int  word_ct;
  41. char word_array[10][25];
  42. char root_array[10][25];
  43. char prime_types[10][11];
  44. char phrases[10][11];
  45. char type_array[10][5][11];
  46. char subjects[20][25];
  47. char actions[20][25];
  48. char places[20][31];
  49. char response[200];
  50. unsigned char verb_tense[5];
  51. unsigned char verb_number[5];
  52. unsigned char verb_usage;
  53. unsigned char aux_tense[5];
  54. unsigned char aux_number[5];
  55. unsigned char aux_usage;
  56. unsigned char subject_number;
  57. unsigned char tenses[20];
  58. unsigned char numbers[20];
  59. unsigned char usages[20];
  60. unsigned char subjects_type[20];
  61. unsigned char aux_meaning[20][5];
  62. char auxiliaries[20][25];
  63.  
  64. void main()
  65. {
  66.     char  *cur_word;
  67.     char  in_sentence[80];
  68.  
  69.     initialize();
  70.     if ((infile = fopen("diction", "r+")) == NULL) {
  71.         printf ("\nError opening dictionary\n");
  72.         exit(0);
  73.     }
  74.     printf("\nSentence: ");
  75.  
  76.     while(gets(in_sentence)) {
  77.         if (in_sentence[0] == '\0') break;
  78.         reset_sentence();
  79.  
  80.         cur_word = strtok(in_sentence, " ");
  81.         while(cur_word != NULL) {
  82.             get_record(cur_word);
  83.             cur_word = strtok(NULL, " ");
  84.             if (++word_ct > 9) break;
  85.         }
  86.  
  87.         if (check_underlying() == 0) {
  88.             check_subject();
  89.             check_action();
  90.             check_place();
  91.             check_aux_verb();
  92.             check_number();
  93.         }
  94.  
  95.         make_response();
  96.  
  97.         printf("Response: %s\n\nSentence: ", response);
  98.  
  99.         if (++sentence > 19) break;
  100.     }   /*  end while  */
  101.  
  102.     fclose(infile);
  103.     return;
  104. }
  105.  
  106. /*****************************************************/
  107. /* Initialize variables.                             */
  108. /*****************************************************/
  109. void initialize()
  110. {
  111.     sentence              = 0;
  112.     memset(subjects,      '\0', 500);
  113.     memset(actions,       '\0', 500);
  114.     memset(places,        '\0', 620);
  115.     memset(tenses,        '\0',  20);
  116.     memset(numbers,       '\0',  20);
  117.     memset(usages,        '\0',  20);
  118.     memset(subjects_type, '\0',  20);
  119.     memset(aux_meaning,   '\0', 100);
  120.     memset(auxiliaries,   '\0', 500);
  121.     return;
  122. }
  123.  
  124. /*****************************************************/
  125. /* These variables are initialized for each new      */
  126. /* input sentence.                                   */
  127. /*****************************************************/
  128. void reset_sentence()
  129. {
  130.     word_ct                      = 0;
  131.     memset(word_array,    '\0', 250);
  132.     memset(root_array,    '\0', 250);
  133.     memset(prime_types,   '\0', 110);
  134.     memset(phrases,       '\0', 110);
  135.     memset(type_array,    '\0', 550);
  136.     response[0]               = '\0';
  137.     return;
  138. }
  139.  
  140. /*****************************************************/
  141. /* Get all the records from the dictionary. If the   */
  142. /* passed word is not in the dictionary, then the    */
  143. /* word could be a name.                             */
  144. /*****************************************************/
  145. void get_record(char *pass_word)
  146. {
  147.     int types = 0;
  148.     rewind (infile);
  149.     fgets(dic_record, 80, infile);
  150.     while (! feof(infile)) {
  151.         if (match_record(pass_word, types) == 0)
  152.             types++;
  153.         fgets(dic_record, 80, infile);
  154.     }
  155.     if (types == 0) {
  156.         if (isupper( (int) pass_word[0]))
  157.             strcpy(type_array[word_ct][types], "NAME");
  158.         else
  159.             strcpy(type_array[word_ct][types],
  160.                    "NOTFOUND");
  161.     }
  162.     strcpy(word_array[word_ct], pass_word);
  163.     return;
  164. }
  165.  
  166. /*****************************************************/
  167. /* Compare the passed word with the word in the      */
  168. /* current dictionary record. If they are the same,  */
  169. /* then extract the type (NOUN, VERB, etc.). If the  */
  170. /* type is PRON, then extract pronoun information.   */
  171. /* If the type is VERB, then extract verb            */
  172. /* information.                                      */
  173. /*****************************************************/
  174. int  match_record(char *pass_word, int types)
  175. {
  176.     int i, j;
  177.     char *root;
  178.     char *dic_word;
  179.     dic_word = extract_word();
  180.     /* Check if passed word equals dictionary word   */
  181.     if (strcmpi(pass_word, dic_word) != 0) return(1);
  182.  
  183.     /* Word found, get the type                      */
  184.     for (i=24,j=0; i<28; i++) {
  185.        if (isspace(dic_record[i])) break;
  186.        type_array[word_ct][types][j++] = dic_record[i];
  187.     }
  188.     /* Trim the type                                 */
  189.     type_array[word_ct][types][j] = '\0';
  190.  
  191.     if (strcmp(type_array[word_ct][types],
  192.                 "PRON") == 0)
  193.         subject_number = dic_record[41];
  194.  
  195.     if (strcmp(type_array[word_ct][types],
  196.                 "VERB") == 0) {
  197.         root = extract_root();
  198.         strcpy(root_array[word_ct], root);
  199.         verb_usage  = dic_record[29];
  200.         for (i=30,j=0; i<34; i++,j++) {
  201.            if (isspace(dic_record[i])) break;
  202.            verb_tense[j] = dic_record[i];
  203.         }
  204.         verb_tense[j] = '\0';
  205.         for (i=41,j=0; i<43; i++,j++) {
  206.            if (isspace(dic_record[i])) break;
  207.            verb_number[j] = dic_record[i];
  208.         }
  209.         verb_number[j] = '\0';
  210.     }
  211.  
  212.     return(0);
  213. }
  214.  
  215. /*****************************************************/
  216. /* Extract the word from the dictionary. The word is */
  217. /* 24 characters in length and starts in column 1.   */
  218. /*****************************************************/
  219. char *extract_word()
  220. {
  221.     int i;
  222.     char dic_word[25];
  223.     strncpy(dic_word, dic_record, 24);
  224.     for (i=23; i>=0; i--) {
  225.         if (isspace(dic_word[i])) {
  226.             dic_word[i] = '\0';
  227.             continue;
  228.         }
  229.         break;
  230.     }
  231.     return(dic_word);
  232. }
  233.  
  234. /*****************************************************/
  235. /* Extract the root from the dictionary. It          */
  236. /* identifies a group of similar words (the root for */
  237. /* run, ran, runs and running is run). It is 14      */
  238. /* characters in length and starts in column 47.     */
  239. /*****************************************************/
  240. char *extract_root()
  241. {
  242.     int i, j;
  243.     char root[15];
  244.     for (i=46,j=0; i<60; i++) {
  245.         if (isspace(dic_record[i])) break;
  246.         root[j++] = dic_record[i];
  247.     }
  248.     /* Trim the root                                 */
  249.     root[j] = '\0';
  250.     return(root);
  251. }
  252.  
  253. /*****************************************************/
  254. /* Determine if the input sentence contains a known, */
  255. /* underlying structure. If it does, then assign the */
  256. /* correct types and phrases for the words.          */
  257. /*****************************************************/
  258. int  check_underlying()
  259. {
  260.     int i = 0;
  261.  
  262.     /* Structure WH-AUX-PRON-VERB                    */
  263.     if ( (check_type("WH",     i) == 0) &&
  264.          (check_type("AUX",  i+1) == 0) &&
  265.          (check_type("PRON", i+2) == 0) &&
  266.          (check_type("VERB", i+3) == 0) ) {
  267.         strcpy(prime_types[i],   "WH");
  268.         strcpy(prime_types[i+1], "AUX");
  269.         strcpy(prime_types[i+2], "PRON");
  270.         strcpy(prime_types[i+3], "VERB");
  271.         strcpy(phrases[i],   "WHQUESTION");
  272.         strcpy(phrases[i+1], "VERBPHRASE");
  273.         strcpy(phrases[i+2], "NOUNPHRASE");
  274.         strcpy(phrases[i+3], "VERBPHRASE");
  275.         strcpy(auxiliaries[sentence], word_array[i+1]);
  276.         get_aux();
  277.         return(0);
  278.     }
  279.  
  280.     /* Structure PRON-AUX-VERB-PREP-DET-NOUN         */
  281.     if ( (check_type("PRON",   i) == 0) &&
  282.          (check_type("AUX",  i+1) == 0) &&
  283.          (check_type("VERB", i+2) == 0) &&
  284.          (check_type("PREP", i+3) == 0) &&
  285.          (check_type("DET",  i+4) == 0) &&
  286.          (check_type("NOUN", i+5) == 0) ) {
  287.         strcpy(prime_types[i],   "PRON");
  288.         strcpy(prime_types[i+1], "AUX");
  289.         strcpy(prime_types[i+2], "VERB");
  290.         strcpy(prime_types[i+3], "PREP");
  291.         strcpy(prime_types[i+4], "DET");
  292.         strcpy(prime_types[i+5], "NOUN");
  293.         strcpy(phrases[i],   "NOUNPHRASE");
  294.         strcpy(phrases[i+1], "VERBPHRASE");
  295.         strcpy(phrases[i+2], "VERBPHRASE");
  296.         strcpy(phrases[i+3], "PREPPHRASE");
  297.         strcpy(phrases[i+4], "PREPPHRASE");
  298.         strcpy(phrases[i+5], "PREPPHRASE");
  299.         strcpy(auxiliaries[sentence], word_array[i+1]);
  300.         get_aux();
  301.         return(0);
  302.     }
  303.  
  304.     /* Structure WH-AUX-NAME-VERB                    */
  305.     if ( (check_type("WH",     i) == 0) &&
  306.          (check_type("AUX",  i+1) == 0) &&
  307.          (check_type("NAME", i+2) == 0) &&
  308.          (check_type("VERB", i+3) == 0) ) {
  309.         strcpy(prime_types[i],   "WH");
  310.         strcpy(prime_types[i+1], "AUX");
  311.         strcpy(prime_types[i+2], "NAME");
  312.         strcpy(prime_types[i+3], "VERB");
  313.         strcpy(phrases[i],   "WHQUESTION");
  314.         strcpy(phrases[i+1], "VERBPHRASE");
  315.         strcpy(phrases[i+2], "NOUNPHRASE");
  316.         strcpy(phrases[i+3], "VERBPHRASE");
  317.         strcpy(auxiliaries[sentence], word_array[i+1]);
  318.         get_aux();
  319.         return(0);
  320.     }
  321.  
  322.     /* Structure NAME-AUX-AUX-AUX-VERB-PREP-DET-NOUN */
  323.     if ( (check_type("NAME",   i) == 0) &&
  324.          (check_type("AUX",  i+1) == 0) &&
  325.          (check_type("AUX",  i+2) == 0) &&
  326.          (check_type("AUX",  i+3) == 0) &&
  327.          (check_type("VERB", i+4) == 0) &&
  328.          (check_type("PREP", i+5) == 0) &&
  329.          (check_type("DET",  i+6) == 0) &&
  330.          (check_type("NOUN", i+7) == 0) ) {
  331.         strcpy(prime_types[i],   "NAME");
  332.         strcpy(prime_types[i+1], "AUX");
  333.         strcpy(prime_types[i+2], "AUX");
  334.         strcpy(prime_types[i+3], "AUX");
  335.         strcpy(prime_types[i+4], "VERB");
  336.         strcpy(prime_types[i+5], "PREP");
  337.         strcpy(prime_types[i+6], "DET");
  338.         strcpy(prime_types[i+7], "NOUN");
  339.         strcpy(phrases[i],   "NOUNPHRASE");
  340.         strcpy(phrases[i+1], "VERBPHRASE");
  341.         strcpy(phrases[i+2], "VERBPHRASE");
  342.         strcpy(phrases[i+3], "VERBPHRASE");
  343.         strcpy(phrases[i+4], "VERBPHRASE");
  344.         strcpy(phrases[i+5], "PREPPHRASE");
  345.         strcpy(phrases[i+6], "PREPPHRASE");
  346.         strcpy(phrases[i+7], "PREPPHRASE");
  347.         strcpy(auxiliaries[sentence], word_array[i+1]);
  348.         strcat(auxiliaries[sentence], " ");
  349.         strcat(auxiliaries[sentence], word_array[i+2]);
  350.         strcat(auxiliaries[sentence], " ");
  351.         strcat(auxiliaries[sentence], word_array[i+3]);
  352.         get_aux();
  353.         return(0);
  354.     }
  355.  
  356.     /* Structure NAME-AUX-AUX-VERB-PREP-DET-NOUN     */
  357.     if ( (check_type("NAME",   i) == 0) &&
  358.          (check_type("AUX",  i+1) == 0) &&
  359.          (check_type("AUX",  i+2) == 0) &&
  360.          (check_type("VERB", i+3) == 0) &&
  361.          (check_type("PREP", i+4) == 0) &&
  362.          (check_type("DET",  i+5) == 0) &&
  363.          (check_type("NOUN", i+6) == 0) ) {
  364.         strcpy(prime_types[i],   "NAME");
  365.         strcpy(prime_types[i+1], "AUX");
  366.         strcpy(prime_types[i+2], "AUX");
  367.         strcpy(prime_types[i+3], "VERB");
  368.         strcpy(prime_types[i+4], "PREP");
  369.         strcpy(prime_types[i+5], "DET");
  370.         strcpy(prime_types[i+6], "NOUN");
  371.         strcpy(phrases[i],   "NOUNPHRASE");
  372.         strcpy(phrases[i+1], "VERBPHRASE");
  373.         strcpy(phrases[i+2], "VERBPHRASE");
  374.         strcpy(phrases[i+3], "VERBPHRASE");
  375.         strcpy(phrases[i+4], "PREPPHRASE");
  376.         strcpy(phrases[i+5], "PREPPHRASE");
  377.         strcpy(phrases[i+6], "PREPPHRASE");
  378.         strcpy(auxiliaries[sentence], word_array[i+1]);
  379.         strcat(auxiliaries[sentence], " ");
  380.         strcat(auxiliaries[sentence], word_array[i+2]);
  381.         get_aux();
  382.         return(0);
  383.     }
  384.  
  385.     /* Structure NAME-AUX-VERB-PREP-DET-NOUN         */
  386.     if ( (check_type("NAME",   i) == 0) &&
  387.          (check_type("AUX",  i+1) == 0) &&
  388.          (check_type("VERB", i+2) == 0) &&
  389.          (check_type("PREP", i+3) == 0) &&
  390.          (check_type("DET",  i+4) == 0) &&
  391.          (check_type("NOUN", i+5) == 0) ) {
  392.         strcpy(prime_types[i],   "NAME");
  393.         strcpy(prime_types[i+1], "AUX");
  394.         strcpy(prime_types[i+2], "VERB");
  395.         strcpy(prime_types[i+3], "PREP");
  396.         strcpy(prime_types[i+4], "DET");
  397.         strcpy(prime_types[i+5], "NOUN");
  398.         strcpy(phrases[i],   "NOUNPHRASE");
  399.         strcpy(phrases[i+1], "VERBPHRASE");
  400.         strcpy(phrases[i+2], "VERBPHRASE");
  401.         strcpy(phrases[i+3], "PREPPHRASE");
  402.         strcpy(phrases[i+4], "PREPPHRASE");
  403.         strcpy(phrases[i+5], "PREPPHRASE");
  404.         strcpy(auxiliaries[sentence], word_array[i+1]);
  405.         get_aux();
  406.         return(0);
  407.     }
  408.  
  409.     /* Structure NAME-VERB-PREP-DET-NOUN             */
  410.     if ( (check_type("NAME",   i) == 0) &&
  411.          (check_type("VERB", i+1) == 0) &&
  412.          (check_type("PREP", i+2) == 0) &&
  413.          (check_type("DET",  i+3) == 0) &&
  414.          (check_type("NOUN", i+4) == 0) ) {
  415.         strcpy(prime_types[i],   "NAME");
  416.         strcpy(prime_types[i+1], "VERB");
  417.         strcpy(prime_types[i+2], "PREP");
  418.         strcpy(prime_types[i+3], "DET");
  419.         strcpy(prime_types[i+4], "NOUN");
  420.         strcpy(phrases[i],   "NOUNPHRASE");
  421.         strcpy(phrases[i+1], "VERBPHRASE");
  422.         strcpy(phrases[i+2], "PREPPHRASE");
  423.         strcpy(phrases[i+3], "PREPPHRASE");
  424.         strcpy(phrases[i+4], "PREPPHRASE");
  425.         return(0);
  426.     }
  427.     return(1);
  428. }
  429.  
  430. /*****************************************************/
  431. /* Compare the passed type with all the types for    */
  432. /* this word in the type_array. If the type is       */
  433. /* found, then return 0. The pass_number parameter   */
  434. /* identifies the word in the input sentence.        */
  435. /*****************************************************/
  436. int check_type(char *pass_type, int pass_number)
  437. {
  438.     int i;
  439.     for (i=0; type_array[pass_number][i][0]; i++) {
  440.         if (strcmp(type_array[pass_number][i],
  441.                     pass_type) == 0)
  442.             /*  Passed type is found in array        */
  443.             return(0);
  444.     }
  445.     /*  Passed type is not found in array            */
  446.     return(1);
  447. }
  448.  
  449. /*****************************************************/
  450. /* If the correct type is "NAME" or "PRON" then the  */
  451. /* word refers to a subject so copy the word to the  */
  452. /* subjects array.                                   */
  453. /*****************************************************/
  454. void check_subject()
  455. {
  456.     int i;
  457.     for (i=0; i<word_ct; i++) {
  458.         if (strcmp(prime_types[i], "NAME") == 0) {
  459.             strcpy(subjects[sentence], word_array[i]);
  460.             subject_number = SINGULAR;
  461.             subjects_type[sentence] = NAME;
  462.             break;
  463.         }
  464.         if (strcmp(prime_types[i], "PRON") == 0) {
  465.             strcpy(subjects[sentence], word_array[i]);
  466.             subjects_type[sentence] = PRONOUN;
  467.             break;
  468.         }
  469.     }
  470.     return;
  471. }
  472.  
  473. /*****************************************************/
  474. /* If the correct type is "VERB", then the word      */
  475. /* refers to an action so copy the word's root from  */
  476. /* the root array to the actions array.              */
  477. /*****************************************************/
  478. void check_action()
  479. {
  480.     int i;
  481.     for (i=0; i<word_ct; i++) {
  482.         if (strcmp(prime_types[i], "VERB") == 0) {
  483.             strcpy(actions[sentence], root_array[i]);
  484.             break;
  485.         }
  486.     }
  487.     return;
  488. }
  489.  
  490. /*****************************************************/
  491. /* If the phrase is a "PREPPHRASE", then all the     */
  492. /* words in the phrase refer to a place. Concatenate */
  493. /* these words to the places array.                  */
  494. /*****************************************************/
  495. void check_place()
  496. {
  497.     int i;
  498.     for (i=0; i<word_ct; i++) {
  499.         if (strcmp(phrases[i], "PREPPHRASE") == 0) {
  500.             strcat(places[sentence], " ");
  501.             strcat(places[sentence], word_array[i]);
  502.         }
  503.     }
  504.     return;
  505. }
  506.  
  507. /*****************************************************/
  508. /* Determine the sentence tense and usage by         */
  509. /* matching auxiliary and verb information, or by    */
  510. /* matching previous sentence information.           */
  511. /*****************************************************/
  512. void check_aux_verb()
  513. {
  514.    int  i, j, matches;
  515.    char *result;
  516.    char temp_tenses[5];
  517.  
  518.    /**************************************************/
  519.    /* Auxiliary in sentence                          */
  520.    /**************************************************/
  521.    if (strlen(auxiliaries[sentence]) > 0) {
  522.        if (aux_usage != verb_usage) {
  523.            tenses[sentence]  = UNKNOWN;
  524.            usages[sentence]  = UNKNOWN;
  525.            return;
  526.        }
  527.        for (i=0,j=0,matches=0; aux_tense[i]; i++) {
  528.          if ((result = strchr(verb_tense,aux_tense[i]))
  529.                                              != NULL) {
  530.              temp_tenses[j++] = *result;
  531.              matches++;
  532.          }
  533.        }
  534.        temp_tenses[j] = '\0';
  535.        if (matches == 0) {
  536.            tenses[sentence]  = UNKNOWN;
  537.            usages[sentence]  = UNKNOWN;
  538.            return;
  539.        }
  540.        usages[sentence]   = aux_usage;
  541.        if (matches == 1) {
  542.            tenses[sentence]  = temp_tenses[0];
  543.            return;
  544.        }
  545.        for (i=sentence-1; i>=0 && i>=sentence-3; i--) {
  546.            if ((strcmpi(subjects[i],
  547.                         subjects[sentence]) == 0)   &&
  548.                (strcmpi(actions[i],
  549.                         actions[sentence]) == 0)    &&
  550.                (strchr(temp_tenses, tenses[i])
  551.                                            != NULL) &&
  552.                (strlen(places[i]) > 0)) {
  553.                tenses[sentence]    = tenses[i];
  554.                return;
  555.            }
  556.        }
  557.        tenses[sentence]    = PRESENT;
  558.        return;
  559.    }
  560.  
  561.    /**************************************************/
  562.    /* No auxiliary in sentence                       */
  563.    /**************************************************/
  564.    usages[sentence]     = verb_usage;
  565.    if (strchr(verb_tense, PAST) != NULL) {
  566.        tenses[sentence]    = PAST;
  567.        return;
  568.    }
  569.  
  570.    /**************************************************/
  571.    /* No auxiliary, verb tense is present or future  */
  572.    /**************************************************/
  573.    for (i=sentence-1; i>=0 && i>=sentence-3; i--) {
  574.        if ((strcmpi(subjects[i],
  575.                     subjects[sentence]) == 0)       &&
  576.            (strcmpi(actions[i],
  577.                     actions[sentence]) == 0)        &&
  578.            (strchr(verb_tense, tenses[i]) != NULL) &&
  579.            (strlen(places[i]) > 0)) {
  580.            tenses[sentence]    = tenses[i];
  581.            return;
  582.        }
  583.    }
  584.    tenses[sentence]    = PRESENT;
  585.    return;
  586. }
  587.  
  588. /*****************************************************/
  589. /* Match the subject, verb, and auxiliary number.    */
  590. /* If the match is successful, then the sentence     */
  591. /* number is the matched number.                     */
  592. /*****************************************************/
  593. void check_number()
  594. {
  595.    if (strchr(verb_number, subject_number) == NULL) {
  596.        numbers[sentence] = UNKNOWN;
  597.        return;
  598.    }
  599.    if ((strlen(auxiliaries[sentence]) > 0) &&
  600.        (strchr(aux_number, subject_number) == NULL)) {
  601.        numbers[sentence] = UNKNOWN;
  602.        return;
  603.    }
  604.    numbers[sentence] = subject_number;
  605.    return;
  606. }
  607.  
  608. /*****************************************************/
  609. /* Read the dictionary to extract the auxiliary      */
  610. /* information.                                      */
  611. /*****************************************************/
  612. void get_aux()
  613. {
  614.    rewind(infile);
  615.    fgets(dic_record, 80, infile);
  616.    while (! feof(infile)) {
  617.        if (match_aux() == 0)
  618.            return;
  619.        fgets(dic_record, 80, infile);
  620.    }
  621.    return;
  622. }
  623.  
  624. /*****************************************************/
  625. /* If the sentence auxiliary matches the word in the */
  626. /* current dictionary record, then extract the       */
  627. /* auxiliary information from the dictionary.        */
  628. /*****************************************************/
  629. int  match_aux()
  630. {
  631.    int i,j;
  632.    char *dic_word;
  633.    dic_word = extract_word();
  634.    if (strcmpi(auxiliaries[sentence], dic_word) != 0)
  635.        return(1);
  636.  
  637.    aux_usage = dic_record[29];
  638.    for (i=30,j=0; i<34; i++,j++) {
  639.       if (isspace(dic_record[i])) break;
  640.       aux_tense[j] = dic_record[i];
  641.    }
  642.    /* Trim the tense                                 */
  643.    aux_tense[j] = '\0';
  644.    for (i=41,j=0; i<43; i++,j++) {
  645.       if (isspace(dic_record[i])) break;
  646.       aux_number[j] = dic_record[i];
  647.    }
  648.    /* Trim the number                                */
  649.    aux_number[j] = '\0';
  650.    for (i=44,j=0; i<47; i++,j++) {
  651.       if (isspace(dic_record[i])) break;
  652.       aux_meaning[sentence][j] = dic_record[i];
  653.    }
  654.    return(0);
  655. }
  656.  
  657. /*****************************************************/
  658. /* Generate a response with information from a       */
  659. /* matching, previous sentence.                      */
  660. /*****************************************************/
  661. void make_response()
  662. {
  663.   int i;
  664.  
  665.   /***************************************************/
  666.   /* Input sentence is not asking for information.   */
  667.   /***************************************************/
  668.   if (strcmpi(word_array[0], "where") != 0) {
  669.     strcpy(response, "OK");
  670.     return;
  671.   }
  672.  
  673.   /***************************************************/
  674.   /* Match subject, action, tense, and meaning.      */
  675.   /***************************************************/
  676.   for (i=sentence-1; i>=0; i--) {
  677.     if ((strcmpi(subjects[i],subjects[sentence])==0) &&
  678.         (strcmpi(actions[i], actions[sentence]) ==0) &&
  679.         (strlen(places[i])                      > 0) &&
  680.         (tenses[i]              == tenses[sentence]) &&
  681.         (strpbrk(aux_meaning[i],aux_meaning[sentence])
  682.                                             != NULL)) {
  683.        make_answer(i);
  684.        return;
  685.     }
  686.   }
  687.   /***************************************************/
  688.   /* Match subject, action, and tense.               */
  689.   /***************************************************/
  690.   for (i=sentence-1; i>=0; i--) {
  691.     if ((strcmpi(subjects[i],subjects[sentence])==0) &&
  692.         (strcmpi(actions[i], actions[sentence]) ==0) &&
  693.         (strlen(places[i])                      > 0) &&
  694.         (tenses[i]              == tenses[sentence])) {
  695.        make_answer(i);
  696.        return;
  697.     }
  698.   }
  699.   /***************************************************/
  700.   /* Match subject, action, and meaning.             */
  701.   /***************************************************/
  702.   for (i=sentence-1; i>=0; i--) {
  703.     if ((strcmpi(subjects[i],subjects[sentence])==0) &&
  704.         (strcmpi(actions[i], actions[sentence]) ==0) &&
  705.         (strlen(places[i])                      > 0) &&
  706.         (strpbrk(aux_meaning[i],aux_meaning[sentence])
  707.                                             != NULL)) {
  708.         strcpy(response, "I'm not sure, but ");
  709.        make_answer(i);
  710.        return;
  711.     }
  712.   }
  713.   /***************************************************/
  714.   /* Match subject and action.                       */
  715.   /***************************************************/
  716.   for (i=sentence-1; i>=0; i--) {
  717.     if ((strcmpi(subjects[i],subjects[sentence])==0) &&
  718.         (strcmpi(actions[i], actions[sentence]) ==0) &&
  719.         (strlen(places[i])                      > 0)) {
  720.        strcpy(response, "I'm not sure, but ");
  721.        make_answer(i);
  722.        return;
  723.     }
  724.   }
  725.   strcpy(response, "I don't know");
  726.   return;
  727. }
  728.  
  729. /*****************************************************/
  730. /* Move information from a previous sentence to the  */
  731. /* response.                                         */
  732. /*****************************************************/
  733. void make_answer(int prev_sentence)
  734. {
  735.    if (subjects_type[prev_sentence] == PRONOUN) {
  736.        if (strlen(response) == 0) {
  737.           subjects[prev_sentence][0] =
  738.             (char) toupper(subjects[prev_sentence][0]);
  739.        }
  740.        else {
  741.           subjects[prev_sentence][0] =
  742.             (char) tolower(subjects[prev_sentence][0]);
  743.        }
  744.    }
  745.    strcat(response, subjects[prev_sentence]);
  746.    strcat(response, " ");
  747.    if (strlen(auxiliaries[prev_sentence]) > 0) {
  748.        strcat(response, auxiliaries[prev_sentence]);
  749.        strcat(response, " ");
  750.    }
  751.    get_verb(tenses[prev_sentence],
  752.             numbers[prev_sentence],
  753.             usages[prev_sentence]);
  754.    strcat(response, places[prev_sentence]);
  755.    return;
  756. }
  757.  
  758. /*****************************************************/
  759. /* Get the correct verb from the dictionary.         */
  760. /*****************************************************/
  761. void get_verb(char pass_tense,
  762.               char pass_number, char pass_usage)
  763. {
  764.    rewind(infile);
  765.    fgets(dic_record, 80, infile);
  766.    while (! feof(infile)) {
  767.        if (match_verb(pass_tense,
  768.                       pass_number, pass_usage) == 0)
  769.            break;
  770.        fgets(dic_record, 80, infile);
  771.    }
  772.    return;
  773. }
  774.  
  775. /*****************************************************/
  776. /* If the verb information in the current record     */
  777. /* matches the passed information, then move the     */
  778. /* correct verb to the response.                     */
  779. /*****************************************************/
  780. int  match_verb(char pass_tense,
  781.                 char pass_number, char pass_usage)
  782. {
  783.    int  i;
  784.    char *root;
  785.    char *dic_word;
  786.    root = extract_root();
  787.  
  788.    /* Match verb with root                           */
  789.    if (strcmpi(actions[sentence], root) == 0) {
  790.        /* Match verb with tense                      */
  791.        for (i=30; i<34; i++) {
  792.           if (isspace(dic_record[i])) return(1);
  793.           if (dic_record[i] == pass_tense) break;
  794.        }
  795.        /* Match verb with number                     */
  796.        for (i=41; i<43; i++) {
  797.           if (isspace(dic_record[i])) return(1);
  798.           if (dic_record[i] == pass_number) break;
  799.        }
  800.        /* Match verb with usage                      */
  801.        if (dic_record[29] == pass_usage) {
  802.           dic_word = extract_word();
  803.           strcat(response, dic_word);
  804.           return(0);
  805.        }
  806.    }
  807.    return(1);
  808. }
  809.  
  810. /* End of file                                       */
  811.  
  812.  
  813.