blog.ryota-ka.me

『形式意味論入門』をHaskellに書き下す(前編)

一昨年のゴールデンウィークに池袋のジュンク堂を訪れた際,『形式意味論入門』という表題の本に目が止まり,数学や論理学を用いて自然言語表現の意味を形式的に考察する学問分野があることを知った*1.また,その道具立てとして単純型付きラムダ計算が用いられていることが,なおのこと私の興味を惹いた.ラムダ計算といえば,読者の多くが計算機科学分野での応用を思い浮かべると思うが,Richard Montague*2が自然言語分野に応用して以来,そちらの方面でも道具立てとして用いられているようである.

この本は,Irene HeimとAngelika KratzerによるSemantics in Generative Grammar(以下Heim and Kratzer)をベースに書かれているのだが,Heim and Kratzerで用いられる意味計算規則のうち,実質的に用いられるものはたった4つであるとし,前半で4つの意味計算規則の導入を行い,後半ではその他の自然言語現象に対して形式的な意味を与えていく,という構成になっている.また,統語論を学んだ人文学系の学生を対象読者として書かれているため.序盤では集合論やラムダ計算に関する非形式的な説明に文量が割かれている.

この記事は,私が『形式意味論入門』の内容の習得を試みる際に,自分の理解が正しいかを確かめるため,Haskellのコードとして書き下した内容を下地に書かれている.言語表現及びそれらの外延をプログラム,とりわけHaskellのプログラムにエンコードするメリットとしては,

  • 意味計算を自力で行う必要がない
  • 型の整合性がGHCの型検査機によって自動的に保証される

などが挙げられるだろう.

この記事は前後編に分かれている.前編では,事前知識の導入の後,4つの意味計算規則のうち最初の2つを導入する.後編では,更なる準備の後,残る2つの意味計算規則を導入する.

§1 文の「意味」#

ここでいう「文」は平叙文のことだと思われる.たぶん元を辿ると"Satz"の訳なので,「命題」と訳してもよいのかもしれない.

合成意味論の祖であるGottlob Frege*3によれば,文の意味(de: Bedeutung, en: reference)は真理値(de: Wahrheitswerth, en: truth value)である*4.形式意味論の分野では真理値は0,10, 1で表されることが多いようだが,後編で導入する指標(index)との混乱を避けるため,本記事ではそれぞれFalse,True\text{False}, \text{True}と表記する.

形式意味論の研究は Richard Montagueをもって嚆矢とするが,彼の思想はDonald Davidson*5が提唱した真理条件的意味論——すなわち,ある文の意味とは,その言語表現が真となるような状況であるとする——の流れを汲んでおり,これは現在でも形式意味論の標準的な立場となっている*6.しかし,計算機を用いてそのような条件を得ることは難しいため,本記事ではFregeに倣い,文の意味は真理値であるという立場を取ることにする.

例として,

Socrates is mortal.\textit{Socrates is mortal.}

という文の意味を考えてみよう.この主張は伝統的に正しいとされている*7ので,この文の意味は真となるはずである.この事実を

Socrates is mortal.=True\llbracket \textit{Socrates is mortal.} \rrbracket = \text{True}

と書く.\llbracket \cdot \rrbracket外延割当関数(denotation assignment function)と呼ばれ,言語表現(対象言語の項)をその意味に写す関数である.『形式意味論入門』によれば,「意味」とは

「自然言語表現」と「世界のあり方」の対応関係

として定義される*8.また,このような定義に基づき「記号と対応する実際の存在物・概念」という意味で「意味」を捉えるとき,「外延」と呼ぶ*9.以下この記事中では,「意味」と「外延」を区別せず用いる.

続いて,固有名詞Socrates\textit{Socrates}の意味Socrates\llbracket \textit{Socrates} \rrbracketを考えてみよう.これはもちろん古代ギリシアはアテナイの哲学者Socrates\text{Socrates}のことを指す.この事実を

Socrates=Socrates(という人物)\llbracket \textit{Socrates} \rrbracket = \text{Socrates(という人物)}

と書く.左辺の外延割当関数の中にあるSocrates\textit{Socrates}がイタリック体になっていることに注意されたい.形式意味論では,言語を用いて言語を説明するという構造を取らざるを得ないため,説明の対象となる言語と,説明のために用いる言語とを区別しておく必要がある.これらをそれぞれ対象言語(object language)とメタ言語(meta language)と呼ぶ.また,混同を避けるため,対象言語はイタリック体で記述する.左辺のSocrates\textit{Socrates}は単なる対象言語内の記号であり,右辺のSocrates\text{Socrates}は,実在する歴史上の人物としてのソクラテスである.また,地の文で書かれているものはメタ言語である.

ところで,合成性原理(principle of compositionality)によれば,Socrates is mortal.\textit{Socrates is mortal.}という文の意味は,その文中の語彙の意味

  • Socrates=Socrates\llbracket \textit{Socrates} \rrbracket = \text{Socrates}
  • is=?\llbracket \textit{is} \rrbracket = \text{?}
  • mortal=?\llbracket \textit{mortal} \rrbracket = \text{?}

と,それらの組み合わせ方によって,またそれらによってのみ計算されるはずである.この語彙の組み合わせ方を意味計算規則と呼ぶ.

では,語彙と意味計算規則について見ていくことにしよう.

§1のまとめ#

  • 「意味」とは「自然言語表現」と「世界のあり方」の対応関係である.
  • 文の意味は真理値である.
  • 外延割当関数 \llbracket \cdot \rrbracket は,言語表現をその意味に写す.
    • Socrates=Socrates(という人物)\llbracket \textit{Socrates} \rrbracket = \text{Socrates(という人物)}
    • Socrates is mortal.=True\llbracket \textit{Socrates is mortal.} \rrbracket = \text{True}
  • 文の意味は,文中の語彙の意味と,それらの組み合わせ方(意味計算規則)によって,またそれらによってのみ計算される.

§2 意味タイプ#

例えばSocrates\textit{Socrates}mortal\textit{mortal}では,それぞれ固有名詞と形容詞であるから,それらの単語が属するカテゴリは異なることが予想される.ある単語が属する意味論上のカテゴリを意味タイプ(semantic type)と呼ぶ.混乱を生じない限り,この記事中では単にと呼ぶ場合がある.

意味タイプは以下のように再帰的に定義される*10.ただしeeは個体を表す型,ttは真理値を表す型,,\langle \cdot, \cdot \rangleは順序対である.

  • a) eettは意味タイプである.
  • b) σ\sigmaおよびτ\tauが意味タイプならば,σ,τ\langle\sigma, \tau\rangleも意味タイプである.
  • c) 意味タイプは以上に限られる.

意味タイプを導入する目的は,項を類別することにある*11.2つの項が,外延割当関数で移した先で同じ集合に属するならば,それらの項は同じ型をもつようにしたい.型と集合は一対一に対応する.型τ\tauに対応する集合をDτD_\tauと書くことにすると,

  • De={xx is an individual}D_e = \lbrace x \mid x \text{ is an individual} \rbrace
  • Dt={False,True}D_t = \lbrace \text{False}, \text{True} \rbrace
  • Dσ,τ={ff is a function from Dσ to Dτ}D_{\langle \sigma, \tau \rangle} = \lbrace f \mid f \text{ is a function from } D_\sigma \text{ to } D_\tau \rbrace

となる.早い話,意味タイプとは,基底型(ground type)e,te, tとその上の関数型を考えたものである.読者に馴染み深い記法を用いた方が理解の助けになるであろうし,Haskellのソースコードとの対応が取れるため,この記事ではσ,τ\langle \sigma, \tau\rangleστ\sigma \to \tauと表記することにする.また,この記事では,項xxが型eeを持つことをx:ex : eと表記する.

『形式意味論入門』から読み取るのは難しかったのだが,おそらく型は対象言語の項に付けられるものであって,メタ言語の項に付けられるものではない*12.したがって,

Socrates:e\textit{Socrates} : e

という記述は妥当であり,「Socrates\textit{Socrates}という語はee型を持つ」という主張になるが,

Socrates:e\llbracket \textit{Socrates} \rrbracket : e

という記述は妥当でない(と思う)*13.一方,

SocratesDe\llbracket \textit{Socrates} \rrbracket \in D_e

はメタ言語のレイヤにおける妥当な記述である.

§2のまとめ#

  • 対象言語の項を類別するため,項は型(意味タイプ)をもつ.
  • 意味タイプは,個体の型eeと真理値の型ttおよびその上の関数型\toからなる.
  • τ\tauをもつ項の外延が属する集合をDτD_\tauと書く.
    • 特にDe={xx is an individual}D_e = \lbrace x \mid x \text{ is an individual} \rbrace(個体全部の集合),Dt={False,True}D_t = \lbrace \text{False}, \text{True} \rbrace(真理値の集合)である.

§3 様々な語彙とその意味タイプ#

§1において,文の意味は真理値であることを見た.これはすなわち,文はtt型を持つことを意味する.では,文以外の項はどのような型をもつのだろうか.

3.1 Socrates\textit{Socrates}の外延#

Socrates\textit{Socrates}という語の意味,すなわちSocrates\llbracket Socrates \rrbracketは,前述の通り,古代ギリシアの哲学者であるソクラテスのことを指している.このように,固有名詞が与えられたとき,その外延は,DeD_e(個体全部の集合)の要素として一意に定まる.ゆえに,固有名詞はee型をもつ.

3.2 applebeautifulrun\textit{apple} \cdot \textit{beautiful} \cdot \textit{run}の外延#

続いてapple\textit{apple}という語彙の外延apple\llbracket apple \rrbracketを考えてみよう.ある個体xDex \in D_eを与えられたとき,我々はxxがリンゴであるかどうかを見分けることができる*14.ゆえに,apple\llbracket apple \rrbracketDeD_eの部分集合で,リンゴであるような個体だけを集めてきた集合

{xDex is an apple}\lbrace x \in D_e \mid x\text{ is an apple}\rbrace

と言える.

あるいは,apple\textit{apple}の外延を次のように定義してもよい.

χapple(x)={True (if x is an apple)False (otherwise)\chi_\text{apple}(x) = \begin{cases} \text{True} & \text{ (if } x \text{ is an apple)} \\ \text{False} & \text{ (otherwise)} \end{cases}

この関数χapple(x)\chi_\text{apple}(x)は,定義域をDeD_eとして,引数xxがリンゴであればTrue\text{True}を,そうでなれけばFalse\text{False}を返す,いわゆる特性関数(characteristic function)である.両者の定義間には自然な対応関係があるので,どちらを採用しても差し支えないが,Haskellで表現するに当たって特性関数の方が扱いやすいので,以後こちらの定義を用いることにする.また,

λx.x is an apple\lambda x. x \text{ is an apple}

と簡単に表記する.

次に,自動詞run\textit{run}の外延run\llbracket run \rrbracketを考えてみよう.これも先程と同じように,すべての個体の中から,走っているもののみを選んできた部分集合

{xDex runs}\lbrace x \in D_e \mid x \text{ runs} \rbrace

あるいは,走っている個体に対してTrue\text{True}を,それ以外に対してFalse\text{False}を割り当てる特性関数

χrun(x)={True (if x runs)False (otherwise)\chi_\text{run}(x) = \begin{cases} \text{True} & \text{ (if } x \text{ runs)} \\ \text{False} & \text{ (otherwise)} \\ \end{cases}

run\textit{run}の外延となる.また,apple\textit{apple}の場合と同様に,

λx.x runs\lambda x. x \text{ runs}

とも表記する.

同様に,形容詞beautiful\textit{beautiful}の外延beautiful\llbracket \textit{beautiful} \rrbracket

λx.x is beautiful\lambda x. x \text{ is beautiful}

である.

以上をまとめると,一般名詞・形容詞・自動詞の外延はDeD_eからDtD_tへの関数だと思ってよさそうである.同じことだが,対象言語のレイヤでは,一般名詞・形容詞・自動詞はete \to t型をもつ.

3.3 love\textit{love}の外延#

他動詞love\textit{love}の外延love\llbracket love \rrbracketを考えてみよう.love\textit{love}を用いた例文としてPlato loves Socrates.\textit{Plato loves Socrates.}というものを考えてみる.

前節で自動詞run\textit{run}の意味を考える際,Prun(x)=x runsP_\text{run} (x) = x \text{ runs}という述語について,項xDex \in D_eを探してきてはガチャガチャと当てはめてみて,Prun(x)P_\text{run} (x)を真にするものとそうでないものに分類したのだった.同じようにlove\textit{love}の意味を考えてみると,Plove(x,y)=x loves yP_\text{love} (x, y) = x \text{ loves } yという命題に対し,x,yDex, y \in D_eを探してきてはガチャガチャと当てはめてみて,Plove(x,y)P_\text{love} (x, y)を真にする組とそうでない組に分類してみるとよさそうだ.ここで,x,y=Plato,Socrates\langle x, y \rangle = \langle \text{Plato}, \text{Socrates} \rangleという組はPlove(x,y)P_\text{love} (x, y)を真にする,といった具合である.

love\llbracket love \rrbracketを,Plove(x,y)P_\text{love} (x, y)を真にするようなDe×DeD_e \times D_eの部分集合,つまりDeD_e上の二項関係*15と捉えると,love\llbracket love \rrbracketは以下のように定義できる.

{x,yDe×Dex loves y}\lbrace \langle x, y \rangle \in D_e \times D_e \mid x \text{ loves } y \rbrace

ところが,自然言語表現においては,x,y\langle x, y \rangleのような順序対を一語で表す機能は一般的ではなく,自然言語の構造に乗せるためには,2つの要素を1つずつ別々に渡せる方が便利である.そこで,De×DeDtD_e \times D_e \to D_tなる関数をDe(DeDt)D_e \to (D_e \to D_t)なる関数に対応付けるSchönfinkelization*16という操作を施す*17.結局の所love\textit{love}eete \to e \to tという型を持つことになる*18

また,ラムダ抽象の形では以下のように書ける.

λxy.y loves x\lambda x y. y \text{ loves } x

ここでλxy.x loves y\lambda x y. x \text{ loves } yではないことに注意されたい.統語構造を考えてみれば明らかだが,love\textit{love}と先に併合するのは主語yyではなく目的語xxの方である.

§3のまとめ#

  • Socrates is mortal.\textit{Socrates is mortal.}のようなtt型をもつ.
  • Socrates\textit{Socrates}のような固有名詞ee型をもつ.
  • apple\textit{apple}のような一般名詞ete \to t型をもつ.
  • run\textit{run}のような自動詞ete \to t型をもつ.
  • beautiful\textit{beautiful}のような形容詞ete \to t型をもつ.
  • love\textit{love}のような他動詞eete \to e \to t型をもつ.

§4 モデル世界意味論#

序盤で「意味」を,

「自然言語表現」と「世界のあり方」の対応関係

と定義した.しかし,この定義を愚直に採用すると,「世界」というものが曖昧である,大きすぎて取り扱いが難しい,などいった不都合が生じる*19.そこで,意味計算に差し障りのない範囲で,箱庭のような小さな世界を考えて,この箱庭世界のあり方と自然言語表現の対応関係を考える.この「箱庭のような小さな世界」をモデルと呼ぶ.

『形式意味論入門』ではModel PEANUTS\text{Model PEANUTS}というモデルが想定されている.これはCharles Monroe Schulzの代表作である漫画作品『Peanuts』に由来する.以下この記事中では専らModel PEANUTS\text{Model PEANUTS}のみを考える.

Model PEANUTS\text{Model PEANUTS}#

Model PEANUTS\text{Model PEANUTS}には,以下の8つ(のみ)の個体が存在する.それぞれに対応する言語表現と合わせて示す.

  • Snoopy=Snoopy\llbracket \textit{Snoopy} \rrbracket = \text{Snoopy}
  • Woodstock=Woodstock\llbracket \textit{Woodstock} \rrbracket = \text{Woodstock}
  • Charlie=Charlie\llbracket \textit{Charlie} \rrbracket = \text{Charlie}
  • Sally=Sally\llbracket \textit{Sally} \rrbracket = \text{Sally}
  • Lucy=Lucy\llbracket \textit{Lucy} \rrbracket = \text{Lucy}
  • Linus=Linus\llbracket \textit{Linus} \rrbracket = \text{Linus}
  • Patty=Patty\llbracket \textit{Patty} \rrbracket = \text{Patty}
  • Schroeder=Schroeder\llbracket \textit{Schroeder} \rrbracket = \text{Schroeder}

また,boy\textit{boy}という語が存在する.この語の外延は以下の通りである.

χboy(x)={True(if x is Charlie)True(if x is Linus)True(if x is Schroeder)False(otherwise)\chi_{boy}(x) = \begin{cases} \text{True} & (\text{if } x \text{ is Charlie}) \\ \text{True} & (\text{if } x \text{ is Linus}) \\ \text{True} & (\text{if } x \text{ is Schroeder}) \\ \text{False} & (\text{otherwise}) \end{cases}

これ以外の語彙は必要に応じて適宜導入する.

§4のまとめ#

  • 「世界」は取り扱いづらいので,「モデル」と呼ばれる小さな世界を考え,その中で意味計算を行う.
  • この章以降では専らModel PEANUTS\text{Model PEANUTS}についてのみ考える.

§5 対象言語をHaskellに埋め込む#

前置きが長くなったが,いよいよ意味計算をHaskellの上で行っていく.まずは準備として,対象言語をHaskellに埋め込んだeDSLであるModel言語を導入する.

対象言語における意味タイプは,個体の型eeと真理値の型ttおよびその上の関数型であった.tt型と関数型をHaskellに落とし込むには,考えるモデルによらずそれぞれBool(->)を採用すればいいが,ee型はモデルによって異なってくる.そこで,ee型を表す型変数entityを取るようにしておく.

対象言語 Model言語
ee entity(型変数)
tt Bool
関数型 (->)
{-# LANGUAGE GADTs #-}

-- | 対象言語をHaskellに埋め込んだeDSL
data Model entity a where
    Entity     :: entity   -> Model entity entity   -- ^ e型の値(個体)に相当
    TruthValue :: Bool     -> Model entity Bool     -- ^ t型の値(文)に相当
    Function   :: (a -> b) -> Model entity (a -> b) -- ^ a -> b型の値に相当

また,Model PEANUTS\text{Model PEANUTS}における個体を表すデータ型であるPEANUTS型を以下のように定義しておく.

data PEANUTS
    = Snoopy
    | Woodstock
    | Charlie
    | Sally
    | Lucy
    | Linus
    | Patty
    | Schroeder
    deriving (Show)

これらを組み合わせることで,Model PEANUTS\text{Model PEANUTS}をHaskellに埋め込んだModel PEANUTS言語が得られる.ここで,対象言語内の記号Snoopy\textit{Snoopy}Entity Snoopy :: Model PEANUTS PEANUTSと表され,その外延Snoopy\llbracket \textit{Snoopy} \rrbracketSnoopy :: PEANUTSと表される.

また,外延割当関数を以下のように与える*20

eval :: Model entity a -> a
eval (Entity e)     = e
eval (TruthValue t) = t
eval (Function f)   = f

evalを用いると,Snoopy=Snoopy\llbracket \textit{Snoopy} \rrbracket = \text{Snoopy}という関係はeval (Entity Snoopy) = Snoopyと書くことができる.

4つの意味計算規則#

『形式意味論入門』で挙げられている4つの計算規則は以下の通りである.

  • Functional Application (FA)
  • Predicate Modification (PM)
  • Traces and Pronouns Rule (T&P)
  • Predicate Abstraction (PA)

以降の章では,これらの意味計算規則に対応するModel言語のコンストラクタを増やすことによって,文の表現力を豊かにしていくという構成を取る.

§5のまとめ#

  • Model言語は,対象言語をHaskellに埋め込んだeDSLである.
  • 外延としてHaskellの「地の文」を割り当てる.
  • evalは外延割当関数であり,Model言語の項をHaskellの項に写す.

§6 Functional Application (FA)#

§4においてboy\textit{boy}の意味を以下のように定義した.

χboy(x)={True(if x is Charlie)True(if x is Linus)True(if x is Schroeder)False(otherwise)\chi_{boy}(x) = \begin{cases} \text{True} & (\text{if } x \text{ is Charlie}) \\ \text{True} & (\text{if } x \text{ is Linus}) \\ \text{True} & (\text{if } x \text{ is Schroeder}) \\ \text{False} & (\text{otherwise}) \end{cases}

これをHaskellに書き直すと以下のようになる.

boy :: Model PEANUTS (PEANUTS -> Bool)
boy = Function \case
    Charlie   -> True
    Linus     -> True
    Schroeder -> True
    _         -> False

さて,手始めにLinus is a boy.\textit{Linus is a boy.}という文の意味計算を行いたい.まず,この文は以下のような統語構造を持つ.

ここでis\textit{is}a\textit{a}は「語彙的に空虚」であると考える*21.すると,合成性原理に従えば,この文の意味Linus is a boy.\llbracket \textit{Linus is a boy.} \rrbracket——これは前述の通り真理値になる——はLinus\llbracket \textit{Linus} \rrbracket及びboy\llbracket \textit{boy} \rrbracketその合成の仕方によって,またそれらによってのみ計算されるはずである.

実際のところ,どのような合成を行えばよいのだろうか.ここで第一の意味計算規則であるFunctional Application (FA)が導入される.Linus:e\textit{Linus} : eであり,かつboy:et\textit{boy} : e \to tであるから,文の意味が真理値であったことを思い出すと,直観に従って,関数適用を施したboy(Linus)Dt\llbracket \textit{boy} \rrbracket(\llbracket \textit{Linus} \rrbracket) \in D_tを意味としたいと思うのが人間の性であろう.

FAを形式的に書くと以下のようになる*22

α\alphaが,β\betaγ\gammaを娘に持つ枝分かれ節点(branching node)で,β\llbracket \beta \rrbracketγ\llbracket \gamma \rrbracketを定義域に含む関数であるとき,α=β(γ)\llbracket \alpha \rrbracket = \llbracket \beta \rrbracket(\llbracket \gamma \rrbracket)である.

言い換えれば次のようになる.α\alphaが枝分かれ節点であり,β\betaおよびγ\gammaを娘に持つとする.ここでβ\betaの意味は関数であり,どのような関数かというと,定義域にγ\llbracket \gamma \rrbracketを含んでいる.このとき,α\alphaの意味はどのように計算されるだろうか.その答えは,γ\gammaの意味である項γ\llbracket \gamma \rrbracketに,β\betaの意味たる関数β\llbracket \beta \rrbracketを適用した値β(γ)\llbracket \beta \rrbracket(\llbracket \gamma \rrbracket)となる.

α\alphaのような節点をModel言語に追加してみよう.left-to-rightな適用とright-to-leftな適用の2種類が考えられるため,それぞれに対応するコンストラクタを用意する.

data Model entity a where
    -- ...

    -- ^ left-to-rightな関数適用
    FunApp_l2r :: Model entity (a -> b) -> Model entity a        -> Model entity b
    -- ^ right-to-leftな関数適用
    FunApp_r2l :: Model entity a        -> Model entity (a -> b) -> Model entity b

また,eval関数を次のように拡張する.

eval :: Model entity a -> a
-- ...
eval (FunApp_l2r l r) = eval l $ eval r
eval (FunApp_r2l l r) = eval l & eval r

is\textit{is}a\textit{a}は語彙的に空虚であるとしたので,以下のようなユーティリティ関数is_aを用意しておこう.

is_a :: Model entity a -> Model entity (a -> b) -> Model entity b
is_a = FunApp_r2l

is_a関数を使えば,文Linus is a boy.\textit{Linus is a boy.}は以下のようにHaskellに埋め込むことができる.

sentence :: Model PEANUTS Bool
sentence = Entity Linus `is_a` boy

さて,それでは実際に意味計算を行ってみよう.

main :: IO ()
main = hspec do
    describe "Linus is a boy." do
        let sentence = Entity Linus `is_a` boy

        it "is true" do
            eval sentence `shouldBe` True -- passes

同じように,Lucy loves Charlie\textit{Lucy loves Charlie}の外延を計算してみる.統語構造は以下のような形である.

"Lucy loves Charlie."の統語構造

Model PEANUTS\textit{Model PEANUTS}においてlove\textit{love}の意味を以下のように定義する.

love :: Model PEANUTS (PEANUTS -> PEANUTS -> Bool)
love = Function $ \object subject -> case (subject, object) of
  (Lucy , Schroeder) -> True
  (Sally, Linus    ) -> True
  (Patty, Charlie  ) -> True
  _                  -> False

この上で意味計算を行うと以下のようになる.

main :: IO ()
main = hspec do
    describe "Lucy loves Charlie." do
        let sentence = FunApp_r2l (Entity Lucy) (FunApp_l2r love (Entity Charlie))

        it "is false" do
            eval sentence `shouldBe` False -- passes

§6のまとめ#

  • FAという意味計算規則が導入された.
    • α\alphaが,β\betaγ\gammaを娘に持つ枝分かれ節点で,β\llbracket \beta \rrbracketγ\llbracket \gamma \rrbracketを定義域に含む関数であるとき,α=β(γ)\llbracket \alpha \rrbracket = \llbracket \beta \rrbracket(\llbracket \gamma \rrbracket)である.

§7 Predicate Modification (PM)#

Snoopy is a cute dog.\textit{Snoopy is a cute dog.}という文の意味を計算したい.統語構造は次のとおりである.

"Snoopy is a cute dog."の統語構造

ここで,cute\textit{cute}dog\textit{dog}を娘に持つ節点に注目したい.cute:etcute : e \to tであり,かつdog:etdog : e \to tなので,FAでは型が合わない.このような節点の意味を計算するための規則としてPredicate Modification (PM)を導入する*23

α\alphaが枝分かれ節点で,β,γ\beta, \gammaがともにα\alphaの娘であり,βDet\llbracket \beta \rrbracket \in D _ {e \to t}かつγDet\llbracket \gamma \rrbracket \in D_{e \to t}であるとき,α=λxDe.β(x)γ(x)\llbracket \alpha \rrbracket = \lambda x \in D_e. \llbracket \beta \rrbracket(x) \land \llbracket \gamma \rrbracket(x)である.

xDex \in D _ eに関する2つの述語β=λx.P(x)\llbracket \beta \rrbracket = \lambda x.P(x)γ=λx.Q(x)\llbracket \gamma \rrbracket = \lambda x.Q(x)が与えられたならば,それらの論理積を取った新しい述語λx.P(x)Q(x)\lambda x. P(x) \land Q(x)として取り扱おう,というアイディアである.

PMをModel言語に追加してみよう

data Model entity a where
    -- ...
    PredicateModification
        :: Model entity (entity -> Bool) -- λx.P(x)
        -> Model entity (entity -> Bool) -- λx.Q(x)
        -> Model entity (entity -> Bool) -- α = λx.P(x)∧Q(x)

eval :: Model entity a -> a
-- ...
eval (PredicateModification p q) = \x -> eval p x && eval q x

PMとFAを用いてSnoopy is a cute dog.\textit{Snoopy is a cute dog.}の意味を計算すると,(λx.cute(x)dog(x))(Snoopy)(\lambda x. \llbracket \textit{cute} \rrbracket(x) \land \llbracket \textit{dog} \rrbracket(x))(\llbracket Snoopy \rrbracket),すなわちcute(Snoopy)dog(Snoopy)\llbracket \textit{cute} \rrbracket(\text{Snoopy}) \land \llbracket \textit{dog} \rrbracket(\text{Snoopy})となる.

Model PEANUTS\text{Model PEANUTS}においてcute\textit{cute}dog\textit{dog}の意味を次のように定義する.

cute :: Model PEANUTS (PEANUTS -> Bool)
cute = Function \case
    Lucy  -> True
    Patty -> True
    Sally -> True
    _     -> False

dog :: Model PEANUTS (PEANUTS -> Bool)
dog = Function \case
    Snoopy -> True
    _      -> False

この上で意味計算を行ってみよう.

-- | 'PredicateModification'を表すヘルパー関数
(/\) :: Model entity (entity -> Bool) -> Model entity (entity -> Bool) -> Model entity (entity -> Bool)
(/\) = PredicateModification

main :: IO ()
main = do
    describe "Snoopy is a cute dog." do
        let sentence = Entity Snoopy `is_a` (cute /\ dog)

        it "is false" do
            eval sentence `shouldBe` False -- passes

Snoopyがcuteであるかどうかについては議論が分かれるところだと思うが,少なくともModel PEANUTS\text{Model PEANUTS}におけるcute\textit{cute}の定義に照らし合わせれば,Snoopy is a cute dog.\llbracket \textit{Snoopy is a cute dog.} \rrbracketは偽ということになる.

§7のまとめ#

  • PMという意味計算規則が導入された.
    • α\alphaが枝分かれ節点で,β,γ\beta, \gammaがともにα\alphaの娘であり,βDet\llbracket \beta \rrbracket \in D_{e \to t}かつγDet\llbracket \gamma \rrbracket \in D_{e \to t}であるとき,α=λxDe.β(x)γ(x)\llbracket \alpha \rrbracket = \lambda x \in D_e. \llbracket \beta \rrbracket(x) \land \llbracket \gamma \rrbracket(x)である.

後編に向けて#

続く第3・第4の意味計算規則である"Traces and Pronouns Rule (T&P)"および"Predicate Abstraction (PA)"を取り扱うためには,変項割当(variable assignment)という概念を導入せねばならず,Model言語を大きく拡張しなければならない.変項割当は,She4\textit{She}_4のような,指標(index)の付いた代名詞などを扱うための仕組みである.44という指標に対応する個体が何であるかは文脈によって規定されるのだが,私にはこれは計算的効果(computational effect)に見える.後編では,変項割当を扱うための仕組みを用意したのち,残りの意味計算規則を見ていくこととしよう.

コード全文#

#!/usr/bin/env stack
-- stack --install-ghc runghc --package hspec

{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}

import Data.Function ((&))
import Test.Hspec (describe, hspec, it, shouldBe)

-- | 対象言語Haskellに埋め込んだeDSL
data Model entity a where
    Entity     :: entity -> Model entity entity   -- ^ e型の値に相当
    TruthValue :: Bool -> Model entity Bool     -- ^ t型の値 (文) に相当
    Function   :: (a -> b) -> Model entity (a -> b) -- ^ a-> b型の値に相当

    FunApp_l2r :: Model entity (a -> b) -> Model entity a -> Model entity b
    FunApp_r2l :: Model entity a -> Model entity (a -> b) -> Model entity b

    PredicateModification
        :: Model entity (entity -> Bool) -- ^ λx.P(x)
        -> Model entity (entity -> Bool) -- ^ λx.Q(x)
        -> Model entity (entity -> Bool) -- ^ λx.P(x)∧Q(x)

-- | 外延割当関数
eval :: Model entity a -> a
eval (Entity e)                  = e
eval (TruthValue t)              = t
eval (Function f)                = f
eval (FunApp_l2r l r)            = eval l $ eval r
eval (FunApp_r2l l r)            = eval l & eval r
eval (PredicateModification p q) = \x -> eval p x && eval q x

data PEANUTS
    = Snoopy
    | Woodstock
    | Charlie
    | Sally
    | Lucy
    | Linus
    | Patty
    | Schroeder
    deriving (Show)

boy :: Model PEANUTS (PEANUTS -> Bool)
boy = Function \case
    Charlie   -> True
    Linus     -> True
    Schroeder -> True
    _         -> False

cute :: Model PEANUTS (PEANUTS -> Bool)
cute = Function \case
    Lucy  -> True
    Patty -> True
    Sally -> True
    _     -> False

dog :: Model PEANUTS (PEANUTS -> Bool)
dog = Function \case
    Snoopy -> True
    _      -> False

is_a :: Model entity a -> Model entity (a -> b) -> Model entity b
is_a = FunApp_r2l

(/\) :: Model entity (entity -> Bool) -> Model entity (entity -> Bool) -> Model entity (entity -> Bool)
(/\) = PredicateModification

main :: IO ()
main = hspec do
    describe "Linus is a boy." do
        let sentence = Entity Linus `is_a` boy

        it "is true" do
            eval sentence `shouldBe` True -- passes

    describe "Lucy loves Charlie." do
        let sentence = FunApp_r2l (Entity Lucy) (FunApp_l2r love (Entity Charlie))

        it "is false" do
            eval sentence `shouldBe` False -- passes

    describe "Snoopy is a cute dog." do
        let sentence = Entity Snoopy `is_a` (cute /\ dog)

        it "is false" do
            eval sentence `shouldBe` False -- passes

脚注#

*1: ちなみに,意味論を研究する研究室に所属する友人に聞いたところ,形式意味論の入門に当たっては,Elements of Formal Semanticsがおすすめだそうである.

*2: アメリカの数学者・哲学者.博士課程時代にはBanach-Tarskiのパラドクスで知られるAlfred Tarskiの門下で公理的集合論を研究.その後,Tarskiより学んだ数理論理学におけるモデル意味論を自然言語の意味論に応用する研究に着手し,今日の形式意味論の草分け的存在となった.

*3: ドイツの哲学者・論理学者・数学者.アリストテレス以来2,000年以上に渡って用いられていた論理学を再定義し,形式的な記号を用いて議論することを可能にした.今日の数理論理学の祖として知られる.

*4: ちなみに,文の意義(de: Sinn, en: sense)は,その文が真ないし偽と規定される仕方である.

*5: アメリカ合衆国の哲学者.彼の思想は哲学の多くの分野,とりわけ行為論・心の哲学・言語哲学に大きな影響を与えた.

*6: http://www.is.ocha.ac.jp/~bekki/project.html

*7: ソクラテスは人間であり,任意の人間は死ぬので.全称肯定判断(A)として知られている.

*8: 『形式意味論入門』 p.3

*9: 『形式意味論入門』 p.11

*10: Heim and Kratzer §2.3

*11: と少なくとも私は読み取った.不文律として「ある項はちょうどひとつの型をもつ」というものがあると思うのだが,classificationと捉えるとこれがうまくハマる.

*12: 少なくとも Heim and Kratzerでは厳密に区別されていない.

*13: 前述の通り,型と集合は一対一に対応するため,そこまで厳密に区別する必要性も無いのかもしれないが.

*14: できると思ってほしい.

*15: Nicht: »Das komplexe Zeichen ›aRb‹ sagt, dass a in der Beziehung R zu b steht«, sondern: Dass »a« in einer gewissen Beziehung zu »b« steht, sagt, dass aRb. (Tractatus 3.1432)

*16: ロシアの論理学者・数学者であるMoses Schönfinkelに由来する.

*17: 我々が"currying"として知っている操作である.

*18: \toは右結合であると約束する.

*19: 『形式意味論入門』p. 31では,この定義のもとでstudent\textit{student}の外延を考えるには,「実際にこの世界中ですべての「学生」を知っていないと,この外延は定義できないことになる.」と述べられている.

*20: これは一見自明に見えるが,必ずしもそうではない.Heim and Kratzer §3.1において,"If α\alpha is a terminal node, α\llbracket \alpha \rrbracket is specified in the lexicon."という規則が与えられている.

*21: この取り扱いが妥当なのかはちょっとわかっていない.導入部分では捨象していい程度の問題なのだろうか.

*22: Heim and Kratzer §3.

*23: Heim and Kratzer §4.3.1