Ex5.4〜Ex5.6 ELIZAの改良問題
ELIZAの改良問題を3つ
;; Exercise 5.4 [s] We mentioned that our version of ELIZA cannot ;; handle commas or double quote makes in the input. However, it seems ;; to handle the apostrophe in both input and patterns, Explain.
commaやdouble quoteが扱えないのは、readに特殊文字として解釈されてしまうからですね。 '(アポストロフィー)を扱えているのは、これもreadがquoteに置き換えているからです。
Ex5.4を受けて、Ex5.5,Ex5.6では以下の4つの改良をします。
- 区切り文字を入力出来るようにする
- ()を入力しないですむ様にする
- Abortしないで終了出来るようにする
- 出力から()をとる
;; Exercise 5.5 [h] Alter the input mechanism to handle commas and ;; other punctuation characters. Also arrange so that the user doesn't ;; have to type parentheses around the whole input expression. (Hint: ;; this can only be done using some Lisp functions we have not seen ;; yet. Look at read-line and read-from-string.) ;; Exercise 5.6 [m] Modify ELIZA to have an explicit exit. Also ;; arrange so that the output is not printed in parentheses either. (in-package :eliza) (defparameter *eliza-punctuation-char* '(#\{ #\} #\( #\) #\, #\. #\' #\` #\" #\' #\# #\\ #\;)) ;" (defun eliza-escape-punctuation-char (string) (substitute-if #\space #'(lambda (c) (member c *eliza-punctuation-char*)) string)) (defun eliza-read () (let ((s (make-string-output-stream))) (write-string "(" s) (write-string (eliza-escape-punctuation-char (read-line)) s) (write-string ")" s) (read-from-string (get-output-stream-string s)))) (defun eliza-print (list &rest rest) (declare (ignore rest)) (format t "~@(~{~s ~}~)~%" list)) (defun eliza () "パターンマッチを使って、ユーザのインプットに答える。" (loop (print 'eliza>) (let ((input (eliza-read))) (cond ((eq (car input) 'quit) (return)) (t (eliza-print (flatten (use-eliza-rules input))))))))
上記のように作ってみましたが、PAIPのAnswersの方が綺麗です。
Answersを見て学習したこと。
- 文字列(というかシーケンスならなんでも)の結合にはconcatenateが使える
- 文字列に対してもfindできる
シーケンスに適用できる関数は汎用性が高いですね。更なる学習が必要です。