Alloyガール:ミステリーを作る1

Alloyを使ったミステリー小説の生成に関して「どうやって作ろうか」と考えている過程も割と面白いので記録・公開することにしました。ブログに書かれる「自然言語で書かれたストーリー」とGithubのコミットログの形で進んでいく「コードで書かれたストーリー」が絡み合う「小説の生成過程の小説」です。

今までのAlloy関連記事はAlloyまとめ。特にAlloyで言語女子会殺人事件Alloyで言語女子会殺人事件2Alloyで論理パズルを生成Alloyでそれなりの難易度の論理パズルを生成あたりが関連するかな。

ミステリー部を作る

僕: Alloyさんの頭脳を生かしてミステリー小説を書くことができないだろうか
JS: 面白そう!
Al: それは私に聞いてる?だったら、まず貴方の考える「ミステリー小説」ってのがどんなものか定義して。
僕: えっと、まず人が殺される。
JS: そしてみんな誰が殺したのかわからない。
僕: 「みんなわからない」は間違いじゃない?犯人はわかるわけだし。
Al: そうとは限らないわよ。たとえば「事例1: AさんがBさんを連れて廃墟ビルに入り、自分だけトイレに行くとか言って外に出る。Cさんはそれとは独立に解体工事のために廃墟ビルを爆破する。」これでAとCは結果的に共犯としてBを殺しているけどもAもCもお互いにそのことを知らない。
僕: それは殺人事件じゃなくて事故のような…
Al: あら、じゃあ事故で人が死ぬのとと殺人事件で人が死ぬのの違いを明確にして。
僕: うーむ。

「意図」とは何か?

僕: それは「殺害の意図があったかどうか」だと思うけど…
Al: 「意図」とは何?
僕: うーん、事例1の場合、AもCも、事前にBが死ぬとは思ってないわけじゃない?「事例2: Aが事前に廃墟ビルの爆破時刻を知っており、その時間にBをビルの中に入れておけばBが死ぬだろうと予想していた。」これだとAがBを殺したと言える。逆に「事例3: CはAとBがビルに入ったのを目撃したが、ちょうど憎い相手だったので爆破すれば死ぬと予想した上で予定通り爆破を実行した。」これだとCがBを殺したと言える。Aも一緒に殺すつもりだったけどそれは失敗したわけだ。
Al: つまり「ある人Xが、Yが死亡すると予想し、実際にYが死亡する」が殺人事件の定義で、犯人はX?
僕: うん
Al: つまり「事例4: ある人Yがビルの屋上から飛び降りて、それを目撃したXがYが死ぬと予想し、実際に死んだ」はXを犯人とする殺人事件である。
僕: まったまった。えっと、「ある人Xが、*自分の行為によって* Yが死亡すると予想し、実際にYが死亡する」だな。
Al: 「事例3: DはAがビルに入ったのを目撃したが、ちょうど憎い相手だったので、Cに人が入った旨を伝えなかった。結果Cは予定通りビルを爆破し、Aは死んだ」は殺人事件ではない、と。
僕: むむむ。「自分に都合のいい事態が起きるように知っていることをあえて言わない」ってのはミステリーの頻出パターンのような気がするなぁ。「知っていることを言わない」も行為に含めてはどうか。
Al: いいわよ。行為には具体的には「知っていることを言わない」の他に「爆破」と「置き去り」があるのね。
僕: まあ、他にもナイフで刺すとか銃で撃つとか、いろいろね。

「謎」とは何か?

Al: で、殺人事件が起きたらそれはミステリー?
僕: いや、条件がだいぶ足りない気がする。
Al: 「事例5: Xさんがみんなの前でYさんを刺して殺しました」は殺人事件だけどミステリーじゃない、と。
僕: そうだねぇ、全然ミステリーじゃないねぇ。
Al: 何が足りないの?
僕: うーん、謎?
Al: じゃあ謎って何か定義して。
僕: えっと…
JS: 「誰が殺したのかわからない」!
僕: そうだ。それだ。
Al: 「事例6: Xさんが殺されました。誰が殺したのかわかりませんでした。終わり。」
僕: いや、それは困る。「犯人は文章の初期に登場する」「最終的には犯人が明らかになる」も必要だ。

謎はなぜ解ける?

Al: なぜ犯人が明らかになるの?
僕: え?
Al: 「犯人がわからない」という状態から「犯人がわかる」という状態への遷移は何が引き起こすの?
僕: それは…新しい情報だな。誰かが証言したりとか、物証が見つかったりとか。
Al: 「事例7: Xさんが殺されました。誰が殺したのかわかりませんでした。Yさんが『私が殺しました』と自供しました。謎は全て解けた!」
僕: いや、自供で解決するのは困る…
Al: 「事例8: Xさんが殺されました。誰が殺したのかわかりませんでした。Yさんが監視カメラに映ってました。謎は全て解けた!」
僕: ぐむむ…単独の物証で解決されるのも困るな…
Al: 「事例8: Xさんが殺されました。誰が殺したのかわかりませんでした。犯行時刻のアリバイがないのはAさんとBさん。凶器を入手可能なのはAさんとCさん。犯人はAだ!」
僕: あー。うーん、まだ簡単すぎる気はするけど、だいぶミステリーっぽくなったかなぁ??
Al: N個目の情報で犯人が確定するけど、N-1個目まででは確定しない、ってパターンなら探せるわよ。

強い証拠が多すぎると良くない?

僕: じゃあ、「登場人物の紹介」→「殺人事件発覚」→「情報収集」→「探偵役が『謎は全て解けた』宣言」→「謎解き」ってストーリー構成でどうだろう。
Al: どうだろう、って言われても。
僕: そういうストーリーで一筆お願いします。
Al: え、書けって言ってる?ムリムリ、まだ全然情報が足りないじゃない?
僕: 足りない?
Al: まず「犯人が明らかになる」とは何か。
僕: その人以外の犯行が不可能だとわかること。
Al: 「犯行が不可能だとわかる」とは何か。
僕: えーと、その人が犯人だと仮定すると他の情報と矛盾が起きる、ってこと。
Al: で、情報には例えばカメラに写ったなどの物証があるわけね
僕: うん
Al: 「事例9: A, B, Cさんの中に犯人がいます。Aさんにはアリバイがあります。Bさんにもアリバイがあります。犯人はCだ!」これは条件を満たすわね。
僕: ぐむむ…。確かに単独の証拠では犯人が確定しない。
Al: 単独の証拠で犯人が確定することを嫌ったのは、問題が簡単になりすぎるからでしょ?
僕: うん。
Al: だったら、単独の証拠で、ある登場人物が犯人でないと確定するのも問題が簡単になりすぎるんじゃない?
僕: あー、そうか、確かにそうだなぁ。

状況設定を考える

僕: じゃあこういうのはどうだろう。いくつかの「場所」があって、その場所の間の移動には1.5単位時間かかる。
Al: ふむ。
僕: つまり、あるタイミングで場所Xにいたなら、単位時間後にX以外の場所にいることはできない。2単位時間後にはどこにいる可能性もある。
Al: 続けて。
僕: そして、各場所は十分に狭く、そこの場所にいたなら他に誰がいたかは確認できる。
Al: Xが時刻t1にP1にいた、って情報からはXが単位時間後t2にP1以外にいない、ってことだけが言えるわけね。充分弱そうね。
僕: さらに、犯人は自分の犯行を隠す目的で嘘をつく可能性がある。
Al: いいねいいね、緩くなってきたね。
僕: しかも犯人が1人であるとは限らない。
Al: おっと。そこまで行くと制約が緩すぎね。「全員共犯で嘘を付いている」っていうトリビアルな解が存在するじゃん。
僕: うーん、でも「犯人は1人です」って宣言するのも不自然だし…。
Al: 「最後の一つの情報で犯人集団が一通りに定まる」って制約を満たすなら「登場人物の証言が次々に自己矛盾していき、最後の証言も自己矛盾して全員犯人」って解があるわね。うまく書けば意外と読者に気づかれないんじゃない?
僕: えー、でももうここでネタバレしちゃったしなぁ。物証かなにかでなんとかならないかな…
Al: なんともならないわね。物証と証言が一致する場合、それは犯人が正直なことを言っただけかもしれないので何の判断材料にもならない。一方、物証と証言が矛盾する場合、証言者が犯人であることがあっさり確定する。
僕: うーむ…

逆に正直者を導入したらどうか

Al: 「嘘をつく可能性のある人は最大N人である」と制約を明記するのが嫌だったら、似たような制約を別の表現で入れたらどう?たとえば「村の祭りではM人が神に捧げる踊りを踊る。この役に選ばれた村人は祭りの期間、宗教上の理由により絶対に嘘をついていはいけない」とか。
僕: なるほど。それならありかも。
Al: 誰が踊り子なのかも他の村人から聞くことにすれば村人間の相互作用があっていいんじゃない?
僕: つまり村人は「Xは踊り子だ」「Xは時刻Tに場所Pにいた」の2通りの発言ができる、と。
Al: まずは小さい規模で、容疑者3人、1人が犯人、1人が犯人をかばって嘘をつくかもしれない人、1人が踊り子で正しいことしか言わない、という設定でどれくらいの難易度の謎が生まれるか検証するべきね。
僕: 探偵役を導入して「彼の見聞きしたものは物証同様に正しい」としてもいいかもね。
Al: まあまずはそれも入れずにシンプルなモデルでスタートすべきよ。
僕: そうだよね、夢が広がってついついいろんな物を入れたくなってしまう。探偵役の見聞きした情報から、探偵が正直だとわかっている読者は犯人がわかるのだが、村の他の人にとっては探偵はよそ者で嘘をつく可能性があると考えられていて犯人を逮捕してくれないとか。で、証拠探しが始まる、というのはどうか。
Al: 物事を複雑にするの得意ね。まずは前半がうまく動くことを確認してからにしましょう。

次回予告

Github上でmystery.alsをいじりながら色々試して、それから自然言語での続きが書かれる感じ。