Pattern matching and transformation rules occur frequently in symbolic computati
ID: 3818084 • Letter: P
Question
Pattern matching and transformation rules occur frequently in symbolic computation. The following patterns and corresponding response templates can be used to generate "conversations" like these below(responses arc in italics): well my friend made me come here tell me about your friend he says I am depressed i am sorry to hear you are depressed i think i need help in what way oh am I making sense at all do you believe you are making sense at all you are making fun of me why do you think I are making fun of you The blank spaces in a pattern, denoted by subscripted dashes, can be filled in with any sequence of words. A single word is filled in for single. Write a Dr. Racket program that uses patterns and response templates to simulate a conversation. Include the above 5 pattern/response templates, plus at least 5 more of your own choosing. One of your new patterns should result in returning a greeting (e.g., hello or good morning)that first comes from the patient: another one of your new patterns should end the session(e.g., have a nice day or hope to see you again soon)at some appropriate time. Test your LISP program with inputs that might lead one to believe your program is "intelligent." This exercise is based on a program called Eliza due to Weizenbaum in 1966. Eliza conversed by simply rearranging the sentences that were presented to it. Weizenbaum "was startled to see how quickly and how deeply people conversing with Eliza became emotionally involved" in the interchange. They talked to Eliza as if it were a person, even when they knew it to be a program.Explanation / Answer
/* Including Files */
# include<iostream.h>
# include<conio.h>
# include<string.h>
# include<time.h>
# include<math.h>
# include<stdlib.h>
# include<dos.h>
# include<stdio.h>
# include<fstream.h>
/* Defining Costants*/
// Max. length in characters of any automated reply ( Keyword only)
# define MAX_RESP_LEN 65
// Max. number of responses for any keyword
# define MAX_RESP_NO 20
// Max. number of keywords
# define MAX_KEY 13
// Max. number of Transpositions
# define TRANSPOSE 12
// Max. Size Of User Input
# define MAX_USER_INPUT 100
// Max. Length of Keyword
# define MAX_KWD_LEN 20
// Delay involved in typing (in ms)
# define DELAY 20
/* Defining Global Variables */
// for getting the user name
char user[30];
// for word transpositions
char wordin[TRANSPOSE][MAX_RESP_LEN];
char wordout[TRANSPOSE][MAX_RESP_LEN];
int RanNum(int max);
void initialize_global();
class patterntest
{
public:
char userip[MAX_USER_INPUT];
char keyword[30];
int keyfound;
int keyno;
int nullip;
// constructor
progstr()
{
keyno=-1;
nullip=0;
}
}ip;
class resp
{
int tot_resp;
int last_resp;
char replys[MAX_RESP_NO][MAX_RESP_LEN];
char word[MAX_KWD_LEN];
public:
// constructor
resp()
{
tot_resp=0;
last_resp=-1;
}
int getcount()
{
return last_resp;
}
void addword(char str[MAX_KWD_LEN])
{
strcpy(word,str);
}
char * getword()
{
return word;
}
void addresp(char str[MAX_RESP_LEN])
{
strcpy(replys[++last_resp],str);
}
void display_resp(int num);
void quit_display_resp(int num);
};
void display_logo()
{
cout<<" "<<endl;
delay(DELAY);
cout<<" "<<endl;
}
void display_line()
{
int width=80;
int i=0;
int x=wherex();
int y=wherey()+1;
x=40;
for(int k=0;k<40;k++)
{
delay(DELAY);
gotoxy(x+k,y);
cout<<(char)240;
gotoxy(x-k,y);
delay(DELAY);
cout<<(char)240;
}
cout<<" ";
}
void resp :: display_resp(int num)
{
cout<<"Monali > ";
for(int i=0;i<strlen(replys[num]);i++)
{
// for deliberate typing errors
if(RanNum(6)==0)
{ char c=RanNum(100);
if(c==' ' || c=='' || c==13)
cout<<"w";
else
cout<<c;
delay(RanNum(DELAY));
cout<<"";
}
if(replys[num][i]=='*')
{
char * s1=ip.userip+strlen(ip.keyword);
short int flag=0;
for(int m=0;m<TRANSPOSE;m++)
{
char * s2=wordin[m];
char *ptr=NULL;
ptr=strstr(s1,s2);
if(ptr!=NULL)
{
// transposition word found in the
// user input
flag=1;
// printing text before wordin[m]
int times=ptr-s1;
for(int i=0;i<times;i++)
{
delay(DELAY);
cout<<ip.userip[strlen(ip.keyword)+i];
}
// printing the wordout
cout<<wordout[m];
// printing the left overs
char c;
c=*(ptr+strlen(wordin[m]));
int t=0;
while(c!='')
{
cout<<*(ptr+strlen(wordin[m])+t);
t++;
c=*(ptr+strlen(wordin[m])+t);
}
}
} // end of for
// if flag is still zero , this means no transpose.
if(0==flag)
{
char c;
c=*(s1+strlen(ip.keyword));
int t=0;
while(c!='')
{
cout<<*(s1+t);
t++;
c=*(s1+t);
}
} // end of if
break;
}
else
{
cout<<replys[num][i];
delay(RanNum(DELAY));
}
} // end of for
cout<<" "<<user<<" > ";
}
void resp :: quit_display_resp(int num)
{
cout<<"ELIZA > ";
for(int i=0;i<strlen(replys[num]);i++)
{
// for deliberate typing errors
if(RanNum(6)==0)
{ char c=RanNum(100);
if(c==' ' || c=='' || c==13)
cout<<"w";
else
cout<<c;
delay(RanNum(DELAY));
cout<<"";
}
cout<<replys[num][i];
delay(RanNum(DELAY));
} // end of for
}
resp keys[MAX_KEY];
int RanNum(int max)
{
randomize();
return rand() % max;
}
void find_keyword()
{
int len=0;
int lenkey=0;
int key_no=0;
char teststr[50];
while((ip.keyfound==0) &&(key_no!=MAX_KEY))
{
// getting the length of the keyword
lenkey=strlen(keys[key_no].getword());
char *ptr=NULL;
ptr=strstr(ip.userip,keys[key_no].getword());
if (ptr!=NULL)
{
// keyword found !
ip.keyfound=1;
ip.keyno=key_no;
strcpy(ip.keyword,keys[key_no].getword());
break;
}
key_no++;
}
}
void read_from_file()
{
ifstream fin;
int index=-1;
fin.open("monali.dat");
char line[MAX_RESP_LEN];
while(fin)
{
fin.getline(line,MAX_RESP_LEN);
char *ptr=NULL;
ptr=strstr("@Wrd@",line);
if(strlen(line)<1)
{
break;
}
else if(ptr!=NULL)
{
// the next line is a keyword
fin.getline(line,MAX_RESP_LEN);
keys[++index].addword(line);
}
else
{
// it is a response
keys[index].addresp(line);
}
} // end of while
} // end of function
void main()
{
clrscr();
display_line();
display_logo();
display_line();
// for initializing the global variables
initialize_global();
// for no response by the user.
resp null_resp;
null_resp.addresp("Hello ?");
null_resp.addresp("GoodMorning ?");
null_resp.addresp("COME AGAIN ?");
null_resp.addresp("HOW I AM SUPPOSED TO TALK IF YOU DON'T SAY ANYTHING ?");
// upon logging in
resp signon;
signon.addresp("HI, I'M Monali. WHAT DO YOU WANT TO TALK ABOUT ?");
signon.addresp("HELLO ?");
signon.addresp("GOOD MORNING?");
// when no key found
resp no_key;
no_key.addresp("PLEASE GO ON...");
no_key.addresp("WHAT DOES THAT SUGGEST TO YOU ?");
no_key.addresp("I SEE");
no_key.addresp("I'M NOT SURE I KNOW WHAT YOU ARE TALKING ABOUT ");
no_key.addresp("WHAT'S THAT SUPPOSED TO MEAN ?");
no_key.addresp("CAN YOU CLARIFY THAT A BIT ?");
no_key.addresp("THAT'S INTERESTING...");
no_key.addresp("AND ????");
resp bye;
bye.addresp("have a nice day");
bye.addresp("hope to see you again soon...");
// reading data from dictionary
read_from_file();
cout<<"Monali > (PLEASE TYPE IN ALL CAPS) WHAT'S YOUR NAME DEAR ? ";
cin>>user;
signon.display_resp(RanNum(signon.getcount()));
fflush(stdin);
gets(ip.userip);
strcpy(ip.userip,strupr(ip.userip));
while(strcmp(ip.userip,"BYE")!=0)
{
find_keyword();
if(strlen(ip.userip)<1)
{
null_resp.display_resp(RanNum(null_resp.getcount()));
}
else if(ip.keyfound==1)
{
keys[ip.keyno].display_resp(RanNum(keys[ip.keyno].getcount()));
}
else
{
no_key.display_resp(RanNum(no_key.getcount()));
}
// again returning to normal values of the data items
strcpy(ip.userip," ");
ip.keyno=-1;
ip.keyfound=0;
fflush(stdin);
gets(ip.userip);
strcpy(ip.userip,strupr(ip.userip));
} // end of while
bye.quit_display_resp(RanNum(null_resp.getcount()));
cout<<endl;
display_line();
cout<<" IMPORTANT Please note that the current functionality and
features of this program are very limited and they are just for
accompanying the article that I posted on Planet Source Code. If you want
to make this program more intelligent, make entries in Eliza.Dat file.
You can also increase the string manipulation power of the program,
like considering multiple lines from the user, etc. I had written this code in 1 1/2 hr.
just to make it more easier for the readers of my article about what is
happening. HOW SMART YOU MAKE YOUR ELIZA DEPENDS ON HOW FAR YOU EXTEND
THIS PROGRAM. THERE IS PRACTICALLY NO LIMIT !
THIS CODE IS THE MINIMAL WORKING SKELETON !! ";
display_line();
getch();
}
void initialize_global()
{
strcpy(wordin[0],"ARE");
strcpy(wordout[0],"AM");
strcpy(wordin[1],"AM");
strcpy(wordout[1],"ARE");
strcpy(wordin[2],"WERE");
strcpy(wordout[2],"WAS");
strcpy(wordin[3],"WAS");
strcpy(wordout[3],"WERE");
strcpy(wordin[4],"YOU");
strcpy(wordout[4],"ME");
strcpy(wordin[5]," I ");
strcpy(wordout[5],"YOU");
strcpy(wordin[6],"YOUR");
strcpy(wordout[6],"MY");
strcpy(wordin[7],"MY");
strcpy(wordout[7],"YOUR");
strcpy(wordin[8],"I'VE");
strcpy(wordout[8],"YOU'VE");
strcpy(wordin[9],"YOU'VE");
strcpy(wordout[9],"I'VE");
strcpy(wordin[10],"I'M");
strcpy(wordout[10],"YOU'RE");
strcpy(wordin[11],"YOU'RE");
strcpy(wordout[11],"I'M");
strcpy(wordin[12],"ME");
strcpy(wordout[12],"YOU");
strcpy(wordin[13],"YOU");
strcpy(wordout[13],"ME");
}
2. Create a monali.dat file with yours input format and patterns.