Symbolic AI

(ACS 1995 Solution F)

/******************************************************************************************************************************************************************************************************************************************************************************************************


 *    ACS Computing competition July 1995.
 *    
 *    C solution to 
 *    Problem F: Symbolic AI   
 *


 *    Brendan Humphreys.
 *    brendan@cssa.anu.edu.au
 *


 */


#include <stdio.h>

#define FACT  256
#define IDENT 257
#define QUEST 258
#define UNKNOWN -1


struct Sident {
    char name[40];
    int type;
};

struct Snouns {
    char name[40];
};

struct Sverbs {
    char name[40];
};

struct Sfacts {
    int a, v, b;
};


struct Sident ident[100];    /* the identity table      */
struct Snouns nouns[100];    /* the noun table          */
struct Sverbs verbs[100];    /* the verb table          */
struct Sfacts facts[100];    /* fact/relationship table */


char input[100];
char s1[40];
char s2[40];
char s3[40];
char s4[40];

int nounindex, identindex, verbindex, factindex = 0;


int gettype()
{
    
    int strs;
    
    
    strs = sscanf(input,"%s %s %s %s",s1,s2,s3,s4);
    if (strs == 3)
        
        {
            s1[strlen(s1)-1] = '\0';  /* strip 's' */
            s3[strlen(s3)-2] = '\0';  /* strip 's.' */
            return FACT;
        }
    
    else if ((strs == 4) &&
             (strchr(input,'?') != NULL ))
        {
            s4[strlen(s4)-1] = '\0'; /* strip '?' */
            return QUEST;
        }
    else
        {
            s4[strlen(s4)-1] = '\0';
            return IDENT;
        }
    
    
}


int insertnoun(const char s[])
/* if unique, inserts noun into nountable.
   returns index
 */
{
    int i;
    
    
 for ( i = 0; i <= nounindex; i++)
     {
         if ((strcmp(nouns[i].name,s) == 0))
             return i;
     }
    nounindex++;
    strcpy(nouns[nounindex].name,s);
    return nounindex;
}


int insertverb(const char s[])
/* if unique, inserts verb into verb table.
   returns index
*/
{
    int i;
    for (i = 0; i <= verbindex; i++)
        {
            if (( strcmp(verbs[i].name,s) == 0))
                return i;
        }
    verbindex++;   
    strcpy(verbs[verbindex].name,s);
    return verbindex;

}


int insertident(const char s[], const char t[])
/* if unique, inserts ident into ident table.
   returns index.
*/
{
    int i;
    for (i = 0; i <= identindex; i++)
        {
            if (( strcmp(ident[i].name,s) == 0))
                return i;
        }
    
    identindex++;
    strcpy(ident[identindex].name,s);
    ident[identindex].type = insertnoun(t);
    return identindex;
    
}


void makelower(char *s)
/* convert a string to lower case */
{
    int i;
    for (i = 0; s[i] != '\0'; i++)
        s[i] = tolower(s[i]);
}


void main()
{
    char c;
    int i,t;
    int f1,f2,f3;
    

    
    while (1) {
        /* get a line of input */
        i = 0;
        while ((c = getchar()) != '\n' )
            {
                input[i] = c;
                i = i + 1;
            }
        input[i++] ='\0';
        if (input[0] == '#')   /* catch the terminating condition */
            exit(1);
        t = gettype();  /* determine the type of input, fill global strings  */
        makelower(s1);  /* convert all global strings to lower case */
        makelower(s2);
        makelower(s3);
        makelower(s4);
        
        switch ( t ) {
            
        case FACT: 
            f1 = insertnoun(s1);     /* fill up tables */
            f2 = insertverb(s2);
            f3 = insertnoun(s3);
            factindex++;             
            facts[factindex].a = f1; /* add 'fact' to fact table */
            facts[factindex].v = f2;
            facts[factindex].b = f3;
            break;
          
        case IDENT:
            insertident(s1,s4);
            break;
            
        case QUEST:
            f1 = insertident(s2,s3); /* get individuals index in ident table */
            f1 = ident[f1].type;     /* use this to get its type   */
            f2 = insertverb(s3);     /* get verb index */
            f3 = insertident(s4,s3); 
            f3 = ident[f3].type;
            /* check fact table to see if the entry f1,f2,f3 is present */
            for (i = 1; i <= factindex; i++)
                {
                    if ((facts[i].a == f1) &&
                        (facts[i].v == f2) &&
                        (facts[i].b == f3) )
                        {   /* found it. The answer is Yes  */
                            printf("Yes.\n");
                            break;
                        }
                   }
            if ( i > factindex) /* didn't find it, the answer is No */
                printf("No.\n");
            break;

        default:
          printf(" $ ERROR $ \n");
          
      }
      
  }
}


1995 ACS Australian Programming Competition.