単語の並び方について:生成文法入門 I
生成文法というのが何なのかはさておき、単語の列について考えてみます。
例として、「食べた」「肉」「を」の3つの単語を並べ替えてみましょう。3つ単語があるので、原理的には6種類の並びが可能ですね。
肉を食べた
食べた肉を
を肉食べた
肉食べたを
食べたを肉
を食べた肉
1と2はアリな気がしますね。3の「を肉」って何ですか?無理ですね。4も5も6もダメですね。もしかしたら「私はいつも を肉 食べている」という方はいるかも知れませんが、1と2がアリで、3〜6はダメだとしましょう。
単語の列にはアリなやつとダメなやつがある、そういう感じです。その2種類です。アリなやつとダメなやつの中間があるんじゃないか。。。あるかもしれません。奇数と偶数の間には小数があったりしますね。
そういえば、自然数って、奇数か偶数のどちらかじゃないですか。
で表されるんでしたね。自然数はこのどちらかです。
単語の列も同じように、アリなやつとダメなやつを記述できないか?(アリなやつだけでもいいので)というので生成文法ってやつが始まりました。
生成文法がどうとかはどうでもいいんです。「アリ」な単語の順序の性質とは何か。それを記述したいだけです。できれば 2n+1 みたいな感じで。
「食べた」「肉」「を」の例の場合に戻ってみましょう。1と2のありな場合はどちらも「肉を」の語順になっていて、それ以外の場合はこの語順が守られていません。なので、これさえ記述すればよいのです。
どっちが先に来てもいいという意味で「<->」という記号を今私が作りました。世の中にこの3つしか単語がなければこの作業はこれで終了です。お疲れさまでした。
しかし、単語はいっぱいあります。その組み合わせも無数にあります。アリな単語の列を示すことはできるでしょうか?
奇数はいっぱいあります。無限(広義)にあります。でも、奇数は 2n-1 で書き示すことができますよね。アリな単語の列も同様にできないのでしょうか?
奇数、に比べれば遥かに複雑な規則性なので、それを記述するのが複雑になるのは火を見るより明らかですね。
文字の列の規則を記述する方法というのはいくつか知られています。最も単純なものとして、正規文法というのが知られています。とはいえ、同じ文字を繰り返すとか何の文字でもいい、みたいな感じです。フローチャートで記述できそうな文字列(笑)しか扱えません。単純すぎて、「(肉 を) <-> (食べた) 」すら扱うことができません。フローチャートを使って「(肉 を) <-> (食べた)」を記述することはできないんです。嘘だと思うならやってみましょう。「肉を食べた」と「食べた肉を」以外を生成し、それ以外を生成しないフローチャートって描けないんです。(もし描けたら教えて下さい。)
とりあえず、「食べた」「肉」「を」の3つの単語を並べ替えてアリな順番を記述するにはその正規文法というやつでは無理らしく、それよりももう少し複雑なことができるやつに、文脈自由文法というのがあります。難しい話をすると、正規文法で記述できる文というのは文脈自由文法で記述される文の真部分集合だというのが証明されていて、まあ要するに、正規文法よりいろんな事ができる、という話です。
(肉 を) <-> (食べた)
を文脈自由文法で書くと、以下のようになります。
SはスタートのSで、ここから始めるという記号です。Sが2つあるのでどちらかを選びます。1つ目を選ぶと、XYという列を得ることができます。3行目にXが「食べた」に書きかわることが示されていて、4行目にはYが「肉を」に書きかわることが示されています。そうすると「食べた肉を」が最終的に得られます。
2つ目のSから始めると、Yの「肉を」が先に来て、Xの「食べた」が次に来て、「肉を食べた」を最終的に得ることになります。
Y --> 肉を で「肉」と「を」は別々の単語なのに一つにくくっちゃってますが、厳密にはダメだと思いますが、「肉を食べた」と「食べた肉を」以外を生成し、それ以外を生成しないという目標を果たしてなるべくシンプルにしておきました。
実際、これは単語が3つしか無い例ですが、現在4つしか無い規則を増やせばより多くの単語や文の形に対応できるので、文脈自由文法はなかなか優秀です。自然言語の記述に関して、文脈自由文法でかなりのことができます。最終的には降参して文脈依存文法という、もう少し複雑なことができる仕組みを記述に取り入れる必要が出てくるのは確かですが。
やたら長いあとがき
今回の入門では「アリ」な文を記述してみよう、というところに焦点を当てました。これは1950年代に生成文法というものが生み出された頃からの目的・目標です。その目標が完全に達成されたとは聞いてないので(笑)、その目標は変わってないはずです。
70年近い歴史があるので、多くのことが成し遂げられています。特に1990年頃までの間に。過去30年はほとんど進歩してないかもしれません。
「最新」と称される「理論」では上でやったように、文全体の S から始めるのではなく、単語の側から始めて行って、Sのところまで登っていく形だったりします。
実は、上から始める文脈自由文法も下から始める範疇文法も等価であることが1960年代に証明されていて、どっちから始めても同じことです。現在の生成文法の競技者たちはその違いを大切にしているようですが、数学的に同じであることが証明されています。こういうのを Notational Variant と呼んでまして、言い方の違いってだけの話です。現在の生成文法競技では、言い方を変えていろいろカッコよさを競っているというのが私の個人的な理解です。
この生成文法入門シリーズでは、「最新の理論」などと称するNotational Variantとかではなく、「アリ」の線をどうやって引いていくかに注目していきす。
生成文法を知る上で、歴史的な経緯を知っておくと良いかと思います。1950年頃に、コンピュータで言語を扱えるようにするため、形式的に(=プログラム可能な)言語を記述したいという動機がある時代でした。そういう意味でこの「アリ」の線というのは大事だったわけです。コンピュータに「アリ」な文だけ生成させたりしたい、みたいな背景でした。
その後、目的が変わったとは聞いてません。同じ目的だけど、脳がアリだと判断する文の性質が分かるとか、そういう付加価値がいろいろ主張されたというのは確かだと思います。文字の列として「アリ」であるかを決めるのは脳みそなので、これは脳の研究であるという主張もあったりするようです。何かを食べて美味しいかを決めるのは舌からの情報を得た脳みそが決めることなので、美味しい料理を研究するというのも脳の研究という事になりますね。
コンピュータ科学においては、自然言語を記述する云々という分野もあるんですが、コンパイラの設計においてこの文脈自由文法、そして文脈依存文法というのは大事というか根幹なので、笑えません。自然言語を題材とした生成文法という競技は今日でも続いているようですが、プログラミング言語の設計に文脈自由文法&文脈依存文法は必須ですし、今、あなたが読んでいるこの文字も、誰かが書いたプログラムを文脈自由文法&文脈依存文法に基づいてコンパイルされたバイナリを実行しているからこそこれをあなたが読んでいるのですきっと。
自然言語を記述しようとして設計された形式言語(正規表現、文脈自由文法、文脈依存文法)が、人工の言語であるコンピュータ言語の設計の根幹になってしまったという話で、個人的には人類の歴史を根本的に変えるなにかだったと理解しています。
「普遍文法」というのを耳にされたことがあるかもしれません。今回見た文脈自由文法とか今度見る文脈依存文法が実はそれです。「どの言語にも共通の文法」のような意味合いで豪快に勘違いされているのが普通ですが、どの言語もアリとナシの境界性って文脈自由文法とか文脈依存文法で記述できる範囲だろう、というのが「普遍文法」が指すところでしょう。「文法」っていう用語がちょっと誤解を生みやすいのですが、ここで言う文法というのは数学的な記述の方法に過ぎません。
普遍性がどれくらいのレベルかはもう少し進めないと説明しにくいのですが、極端な例を考えてみるとよいと思います。例えば、同時に2つの単語を言わないといけない言語とか無いですよね。「肉を」が「食べた」の目的語になるためには「肉を」と」「食べた」を同時に発声する。それはないでしょ。無理ですから。そんな言語きっと無いですよね。それを排除しただけで、今ここに何らかの普遍文法があるということです。単語同士はどちらかが先にくる。こっちが先にこないといけない言語、あっちが先じゃないといけない言語、どっちでも良い言語、色々あるかもしれませんが、「単語を順に並べないといけない」ことには変わりないので、これがもう普遍文法の外堀ですね。
今回は「食べた」「肉」「を」で日本語の例を取りましたが、もともと英語の記述で始められたので、この先は英語の記述を扱っていきたいと思います。長い目ではいろんな言語を扱うことになると思います。英語ではこういうふうに見られるやつって、中国語では見られないとされていたけど、こういうふうな比べ方をすると、英語と中国語はすごく似ている、みたいな話とかまでたどり着ければ良いかなと思っています。生成文法入門 II に続きます。