/* Simple ELIZA -- a natural language misunderstander -- Alan Bundy 15-Nov-79, Richard O'Keefe 17-Feb-81 Peter Ross 5-Nov-81 */ :-(['ecmi25.util_readin']). % load read_in + necessary support. /* The top level: call liza (so named 'cos it's a mini-version of ELIZA) to get going. The predicate read_in reads in sentences, currently ending with a full stop, exclamation mark or question mark. Thus read_in(X) will read in hello there. as X = [hello,there,.] NOTE: use lower-case letters at the front of words, this is a simple beast! */ liza :- read_in(Input), make_swaps(Input, Clean), Clean \== [bye,.], rule(Given, Yield), match(Given, Clean), reply(Yield), nl, !, liza. liza :- write('I hope I have helped you.'), nl. /* How it works: imagine typing in "do you like me?". The read_in sets Input = [do,you,like,me,?] then make_swaps(Input,Clean) sets Clean = [do,I,like,you,.] (note the question mark vanished, 'cos make_swaps([?],Rest_of_yield) matched make_swaps([Period],[.]) ). Then rule(Given,Yield) will come up with Given = [you,are,X,.] Yield = [how,long,have,you,been,X,?] and match(Given,Clean) will fail (see below), backtracking to rule(Given,Yield) which comes up with Given = [X,i,Y,you,.] Yield = [what,makes,you,think,i,Y,you,?] whereupon match(Given,Clean) can now succeed, in the process instantiating X to 'do' and Y to 'like', so that Yield is now instantiated to [what,makes,you,think,i,like,you,?] . The predicate reply prints this out.... Exercise: follow through the input "i am fed up." Exercise 2: what are the cuts in make_swaps, match and append for? Exercise 3: copy this file into one of your own, and extend the range of responses it can make. */ make_swaps(Given, Yield) :- swap(Phrase, Translation), append(Phrase, Rest_of_Given, Given), append(Translation, Rest_of_Yield, Yield), !, make_swaps(Rest_of_Given, Rest_of_Yield). make_swaps([Period], [.]) :- !. make_swaps([Word|Rest_of_Given], [Word|Rest_of_Yield]) :- !, make_swaps(Rest_of_Given, Rest_of_Yield). swap([i], [you]). swap([me], [you]). swap([we], [you]). swap([us], [you]). swap([you], [i]). swap([my], [your]). swap([mine], [yours]). swap([our], [your]). swap([ours], [yours]). swap([your], [my]). swap([yours], [mine]). swap([am], [are]). swap([you,are],[i,am]). swap([stop], [bye]). swap([quit], [bye]). swap([goodbye],[bye]). swap([please], []). match([Head|Rest], Fragment) :- append(Head, Leftover, Fragment), match(Rest, Leftover). match([Head|Rest], [Head|Leftover]) :- !, match(Rest, Leftover). match([], []). append([], List, List). append([Head|Tail], List, [Head|Rest]) :- !, append(Tail, List, Rest). reply([Head|Tail]) :- reply(Head), !, reply(Tail). reply([]). reply(Proper_Word) :- tab(1), write(Proper_Word). rule([you,are,X,.], [how,long,have,you,been,X,?]). rule([X,i,Y,you,.], [what,makes,you,think,i,Y,you,?]). rule([you,like,Y,.], [does,anyone,else,in,your,family,like,Y,?]). rule([you,feel,X,.], [do,you,often,feel,that,way,?]). rule([X], [please,go,on,.]).