Ex2.2 終端記号と非終端記号を明に区別するgenerate
以前のgenerateは、rewriteの戻り値を分岐条件としていたけど、それだと分かりにくいよね、ちゃんと述語を作ろう。という問題。
PAIPの答えでは、non-terminal-pを定義していたので、自分はterminal-symbol-pを定義して解いてみる。当然、あまり変わらない。
;;; Exercise 2.2 [m] Write a version of generate that explicitly differentiates between ;;; terminal symbols (those with no rewrite rules) and non-terminal symbols. (defun rule-find (category) "Find rule of specified category." (assoc category *grammar*)) (defun rewrites (category) "Return a list of the possible rewrites for this category." (rule-rhs (rule-find category))) (defun terminal-symbol-p (symbol) "True if this symbol is not a category in the grammar." (not (rule-find symbol))) (defun generate (phrase) "Generate a random sentence or phrase" (cond ((listp phrase) (mappend #'generate phrase)) ((not (terminal-symbol-p phrase)) (generate (random-elt (rewrites phrase)))) (t (list phrase)))) (generate 'sentence) ;; => (THE BALL LIKED A BALL)