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.