(in-package :cl-user) (defpackage chatikbot.eliza (:use :cl :chatikbot.patmatch :chatikbot.utils :alexandria) (:export :?is :?or :?and :?not :?* :?+ :?? :?if :eliza :read-from-string-no-punct)) (in-package :chatikbot.eliza) (defun punctuation-p (char) (find char ".,;:'!?#-()\\\"")) (defun read-from-string-no-punct (input) "Read from an input string, ignoring punctuation." (read-from-string (concatenate 'string "(" (substitute-if #\space #'punctuation-p input) ")"))) (defun switch-viewpoint (words) "Change I to you and vice versa, and so on." (sublis '((I . you) (you . I) (me . you) (am . are) (я ты) (ты я) (меня тебя) (тебя меня)) words)) (defun use-eliza-rules (input rules) "Find some rule with which to transform the input." (rule-based-translator input rules :action #'(lambda (bindings responses) (sublis (switch-viewpoint bindings) (random-elt responses))))) (defun eliza (input rules) (let ((r (use-eliza-rules input rules))) (cond ((null r) nil) ((and (consp (car r)) (eq 'function (caar r))) (apply (cadar r) (cdr r))) ((keywordp (car r)) r) (t (print-with-spaces (flatten r))))))