;;==========================================================================
;;
;; STARTER FILE FOR CSC 4240/5240 PROGRAM #1: Eliza
;;
;;==========================================================================
;;----------------------------------------------------------------------------
;;
;; eliza: top-level function which, when given a sentence (no
;; punctuation, please!), comes back with a response like you would.
( defun eliza ( sentence )
( respond ( change-pros sentence ) database ) )
;;----------------------------------------------------------------------------
;; change-pros: changes the pronouns of the sentence so that Eliza can
;; come back with the appropriately switched first and second person
;; references.
( defun change-pros ( sentence )
( cond
( ( null sentence ) nil )
( ( equal ( car sentence ) 'you )
( cons 'I ( change-pros ( cdr sentence ) ) ) )
( ( equal ( car sentence ) 'I )
( cons 'you ( change-pros ( cdr sentence ) ) ) )
;; CHANGE THIS: add more cases here of pronouns or other words
;; that should flip in order for this to work well
( ( equal ( car sentence ) 'am )
( cons 'are ( change-pros ( cdr sentence ) ) ) )
( ( equal ( car sentence ) 'are )
( cons 'am ( change-pros ( cdr sentence ) ) ) )
( ( equal ( car sentence ) 'me )
( cons 'you ( change-pros ( cdr sentence ) ) ) )
( ( equal ( car sentence ) 'you )
( cons 'me ( change-pros ( cdr sentence ) ) ) )
( ( equal ( car sentence ) 'my )
( cons 'your ( change-pros ( cdr sentence ) ) ) )
( ( equal ( car sentence ) 'your )
( cons 'my ( change-pros ( cdr sentence ) ) ) )
( ( equal ( car sentence ) 'messed )
( cons 'mess ( change-pros ( cdr sentence ) ) ) )
( ( equal ( car sentence ) 'mess )
( cons 'messed ( change-pros ( cdr sentence ) ) ) )
( t ( cons ( car sentence ) ( change-pros ( cdr sentence ) ) ) ) ) )
;;----------------------------------------------------------------------------
;; respond: given a sentence, looks through the database in search of
;; a matching pattern and the response; given the database response,
;; uses 'instantiate' to fill in the blanks, and returns the completed
;; response
( defun respond ( sentence db )
( cond
;; end of DB, return nil - should never really happen
( ( null db ) nil )
;; if the result of matching the sentence against the current
;; pattern is a success, produce this response
( ( success ( setq result ( match sentence ( first ( car db ) ) ) ) )
;;( instantiate result ( second ( car db ) ) ) )
;; Random response function for catch-alls
(instantiate result (random-pick (second (car db)))))
;; otherwise, keep looking through the DB
( t ( respond sentence ( cdr db ) ) ) ) )
( defun random-pick (variable-response-list)
(nth (random (length variable-response-list)) variable-response-list))
;;----------------------------------------------------------------------------
;; match: if there is not a match between this pattern and this data,
;; returns 'fail;' otherwise, returns the sentence in partitioned
;; format
( defun match ( data pattern )
( cond
;; end of both data and pattern; a match
( ( and ( null data ) ( null pattern ) ) nil )
;; end of pattern, but not end of data; no match
( ( null pattern ) fail )
;; end of data, but not end of pattern; if the pattern starts with
;; a variable, eat it and try and match the rest of the pattern to
;; the null sentence (will only work if all variables); otherwise,
;; fail
( ( null data )
( cond
( ( variablep ( car pattern ) )
( if ( success ( setq result ( match data ( cdr pattern ) ) ) )
result
fail ) )
( t fail ) ) )
;; first item of data and pattern are identical; if the rest of it
;; matched, return the first item cons'ed with the rest of the
;; partitioned sentence; otherwise, fail
( ( equal ( car data ) ( car pattern ) )
( if ( success ( setq result ( match ( cdr data ) ( cdr pattern ) ) ) )
( cons ( list ( car data ) ) result )
fail ) )
;; first item of pattern is a variable; if the rest of the data
;; (minus the first word, matched to the variable) is a match with
;; all of the pattern, return the appropriate stuff; if all of the
;; data (variable eats nothing) matches the rest of the pattern,
;; return appropriate stuff; else, fail.
( ( variablep ( car pattern ) )
( cond
;; variable eats nothing; () is put in partitioned sentence
( ( success ( setq result ( match data ( cdr pattern ) ) ) )
( cons () result ) )
;; variable eats one word; word is cons'ed into the first
;; element of the partitioned sentence, assuming that the step
;; before an actual match word would be a ()
( ( success ( setq result ( match ( cdr data ) pattern ) ) )
( cons ( cons ( car data ) ( car result ) ) ( cdr result ) ) )
;; otherwise, fail
( t fail ) ) )
( t fail ) ) )
;;----------------------------------------------------------------------------
;; instantiate: takes a partitioned sentence and the response it has
;; been matched to and generates the appropriated completed response
( defun instantiate ( partitioned response )
( cond
( ( null response ) nil )
;; numbers indicate what part of the partitioned sentence to
;; insert into the response
( ( numberp ( car response ) )
( setq index ( - ( car response ) 1 ) )
( append ( nth index partitioned )
( instantiate partitioned ( cdr response ) ) ) )
( t ( cons ( car response )
( instantiate partitioned ( cdr response ) ) ) ) ) )
;;---------------------------------------------------------------------------
;;
;; helping functions
;;
;;---------------------------------------------------------------------------
( setq fail '-1 )
( defun success ( result )
( not ( equal result fail ) ) )
( defun variablep ( word )
( equal word '0 ) )
;;---------------------------------------------------------------------------
;;
;; database
;;
;;---------------------------------------------------------------------------
;; CHANGE THIS: add more to this database so that the interaction is
;; more interesting and communicative and so that Eliza sounds like you
;; would sound in the same conversation!
;;---------------------------------------------------------------------------
( setq database '(
;; example greetings/farewells -- change them to sound like you
( (Hello 0)
((Heyyy - how are you feeling today?) ))
( (0 you came here because 0)
((Many times we simply need to talk things out so I am here for you. Talk to me.) ))
( (0 Goodbye 0)
((Goodbye - I hope you are feeling better. I am here for you anytime.) ))
( (0 Sad 0)
((Why do you feel sad?) ))
( (0 Mad 0)
((What has caused you to be mad ?) ))
( (0 Yes 0)
((You have to keep trying and move forward!)) )
( (0 a little bit 0)
((You have to keep trying and move forward!) ))
( (0 No 0)
((Try harder!) ))
( (0 Not really 0)
((But why? Do better!) ))
( (0 can be 0)
((In what way ?) ))
( (0 and 0)
((So how do you think you can resolve that ?) ))
( (0 maybe 0)
((There is a possibility.) ))
( (0 Thanks 0)
((Anytime friend. Is there anything else you want to talk about ?) ))
( (0 im okay 0)
((Sounds good. Have a good rest of your day!) ))
;; feelings
( (0 you think you 0)
((why do you think you 5 ?) ))
( (0 you want to 0)
(T(ake one step at a time but start somewhere and 5) ))
;; trying to find a solution
( (0 because you 0)
(( have you tried to not 4 ?) ))
( (0 because the 0)
(( what makes you feel like the 4 ?) ))
( (0 but 0)
(( but what if it isn't that bad 4 ?) ))
;;the catch-alls
((0)
((Okay. Help me understand your feelings better. Tell me more.)
(Can you elaborate on that ?)
(Thats interesting! Expand on that.)
(Im starting to understand. Please continue) ))
))
;; response input
(format t "~a~%" (eliza '(hello)))
(format t "~a~%" (eliza '(i dont know)))
(format t "~a~%" (eliza '(i think i am failing at life)))
(format t "~a~%" (eliza '(because i messed up)))
(format t "~a~%" (eliza '(not really but i didnt mean to)))
(format t "~a~%" (eliza '(but life is so hard)))
(format t "~a~%" (eliza '(i want to improve)))
(format t "~a~%" (eliza '(People can be really mean)))
(format t "~a~%" (eliza '(They are mean and then expect me to be nice all the time)))
(format t "~a~%" (eliza '(Maybe i can ask them to be nicer)))
(format t "~a~%" (eliza '(Thanks)))
(format t "~a~%" (eliza '(I think Im okay)))
(format t "~a~%" (eliza '(Goodbye)))