アットウィキロゴ

Using the Same Data for Several Programs

宣言的な形式における表現情報のもう一つの優位点は、Lisp関数よりもルールや事実は、対象のとりあつかいのための情報を使うのが簡単にすることができます。センテンスのをwordのlistを生成できない関数を欲しがったとすると、センテンスの構文の完全な表現をしなくてはいけなくなります。たとえば、(a woman took a ball)のlistのかわりにnested listを使うとすると
(SENTENSE (NOUN-PHRASE (ARTICLE A) (NOUN WOMAN)0
  (VERB-PHRASE (VERB TOOK)
               (NOUN-PHRASE (ARTICLE A) (NOUN BALL))))
これは図2のようにTreeであらわすことができます。
(図2)
"straight forward function"を使ったアプローチではいきづまってしまうでしょう。構造を追加するごとに、新しく関数を生成しなおさないとならないからです。"新しい表記法"のアプローチを維持しつつ、新規にnested listを生成する関数を書きます。それぞれのrewriteにconsを使用するのと、結果をappendではなくmapcarにするという変更をしました

(defun generate-tree (phrase)
  "ランダムセンテンスとフレーズの生成を完全なTreeのparseで行う"
  (cond ((listp phrase)
         (mapcar #'generate-tree phrase))
 ((rewrites phrase)
  (cons phrase
               (generate-tree (random-elt (rewrites phrase)))))
 (t (list phrase))))
 (generate-tree 'Sentence)
 (略)

もう一つの例として 一つのデータ/複数のプログラムのアプローチがあり、これはすべてのフレーズのrewritesを可能にする関数を開発します。その関数generate-allは一つのphraseのlistを返します。そしてもう一つ補助関数として結果の組合を管理するcombine-allを定義します。今までの3つのケースのかわりに4つのケースのはnil checkが厳密になったせいです。完全なプログラムはとてもシンプルです
(defun generate-all (phrase)
  "このフレーズにおけるすべての可能な拡張のlistの生成"
  (cond ((null phrase) (list nil))
        ((listp phrase)
         (combine-all (generate-all (first phrase))
                      (generate-all (rest phrase))))
        ((rewrites phrase)
         (mappend #'generate-all (rewrites phrase)))
        (t (list (list phrase)))))
(defun combine-all(xlist ylist)
  "append a y to an xとして作成したlistのlistを返す
   E.g.. (combine-all '((a) (b)) '((1)) (2)) -> ((A 1) (B 1) (A 2) (B 2))"
  (mappend #'(lambda(y) (mapcar #'(lambda (x) (append x y)) xlist))
             ylist))

generate-allでオリジナルの小さな文法をテストしてみましょう。*big-grammar*にあるような"Adj* => Adj + Adj*"のような再帰を含む文法だと無限にアウトプットしてしまうという深刻な障害があります。しかし、*simple-grammar*のような限られた文法でなら上手くいくでしょう。
(generate-all 'Article) ...
(略)
(length (generate-all 'sentence)) => 256

この言語のすべてのセンテンスはArticle-Verb-Article-Nounの形式であり、2つのArticleと4つのnounと4つのverbがあるので(2 * 4 * 4 * 2 * 4 = 256)となります。
最終更新:2008年01月09日 05:09
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。