プログラミング言語で自然言語の様に会話する方策 第0回

Copyright (C) 2024 Takym.

(最初回)今回次回→最終回

概要

当ウェブサイト「プログラミング入門講座&学習コミュニティ」はまだ準備中ですが、試験的に記事を執筆してみる事にします。題材としては、日本語や英語の様な自然言語を用いて行う日常的な会話を、プログラミング言語で実践する方法を選びました。ある程度の量の記事を用意できれば良いので、この題材を選んだ深い理由はありません。尚、ここではマークアップ言語はプログラミング言語に含めていません。

対象読者

開発環境の構築や git の仕組み等をある程度知っている方を対象とします。また、C# の文法も理解している事を前提とします。完全な初心者向けの記事は、ウェブサイトの準備が終わってから執筆し始めようと考えております。

プログラミング言語で会話する動機

通常、プログラミング言語はコンピュータに対する命令を行う為に用いられます。そのため、非常に論理的に作られており、プログラミング言語は形式言語の一種とされています。自然言語とは役割や目的が異なります。しかし、本質的にはどちらも「言語」である事には違いありません。この事実から、プログラミング言語で表現された情報と自然言語で表現された情報は相互に翻訳できると考えた訳です。実際に、プログラミング言語から自然言語への翻訳は容易にできます。例えば、下記の様な単純な Hello, World!! プログラムを日本語に訳す事を考えてみましょう。

using System;

namespace ExampleApp
{
	internal static class Program
	{
		private static void Run()
		{
			Console.WriteLine("Hello, World!!");
		}

		[STAThread()]
		private static int Main(string[] args)
		{
			try {
				Run();
				return 0;
			} catch (Exception e) {
				Console.ForegroundColor = ConsoleColor.Red;
				Console.Error.WriteLine();
				Console.Error.WriteLine(e.ToString());
				Console.ResetColor();
				return e.HResult;
			}
		}
	}
}

閑話

一般的な Hello, World!! プログラムより長いと感じるかもしれません。これは、僕がいつも使っている独自のテンプレートから書き始めたものです。エントリポイント(プログラムの開始地点)は、セキュリティを考慮して静的内部型の中に置いています。エントリポイントの中では、全ての例外を捕獲し、その内容を標準エラー出力ストリームへ流しています。また、例外の発生を OS やシェルに通知する為に HRESULT 値を返却しています。例外によっては 0 に設定されている可能性もありますが、その場合でも -1 に変える等の対応は取っていません。きちんと取っている時もあります。プログラムが正常に動作し、エラーが何も発生しなかった場合は、正常終了を表す 0 を返します。エントリポイントに STAThread 属性 を付けているのは、誤動作を回避する為です。僕は常にこの属性を付与している事を前提にコードを書いています。これが無い事に起因する不具合を全て回避する意味合いがあります。しかし、WinForms や WPF、COM 等の技術を使わないのであれば、実際には然程問題にはならないだろうとは思います。今回の例では、コマンド行引数は一切使っていませんが、宣言だけはしてあります。

閑話休題

閑話が長くなってしまいましたが、つまり、上記のコードで実質的な意味があるのは下記の部分(Run 関数の中身)だけです。

Console.WriteLine("Hello, World!!");

このコードは日本語で次の様に表現する事ができます。

コンソール画面に「Hello, World!!」と表示せよ。

若しくは、次の様な別の言い方もあります。

標準出力ストリームに「Hello, World!!」を出力しなさい。

また更に別の訳も考えられます。

出力画面へ「Hello, World!!」と書き込んでください。

(※厳密には改行も書き込んでいますが、ここでは便宜的に省いています。)

表現の種類が多いのは自然言語特有の問題ではありません。勘違いしない様に気を付けましょう。例えば、C# では下記の様に記述する事もできます。

// (1) Console クラスの Out プロパティを使う。
Console.Out.WriteLine("Hello, World!!");

// (2) 定数を用いて、ハードコーディングを避ける。
const string HelloWorldText = "Hello, World!!";
Console.WriteLine(HelloWorldText);

// (3) 不思議な体裁でコードを書く。
Console
	.WriteLine(
		"Hello, World!!".ToString()
	);

// 等々・・・

つまり、プログラミング言語で書かれた内容は、普通に自然言語でも表現する事ができる訳です。また、考え方によっては、先程の閑話もコードの説明文であり、コードの意図する所を日本語に翻訳したと言えます。僕はこの逆を考えた訳です。プログラミング言語から自然言語へ翻訳できるのと同じ様に、自然言語からプログラミング言語へ翻訳する事は可能なのだろうかと疑問に思った訳です。確かに、情緒的な文章をプログラミング言語で表現するのは、困難であり、しかも目的から外れるのかもしれません。しかし、目的外であるという事は、個人的な知的好奇心を満たす為の検証実験を妨げる理由には成り得ません。僕が調べた限りでは、会話文をプログラミング言語で表現する試みは見当たらなかったので、誰も興味が無いのかもしれませんが。以上の他に小さな動機も列記しておきます。

尚、実際に発声できるかどうかは検証しません。日本語における漢文の様な書き言葉としての役割を持つものとして考えてください。

基本構造など

基本構造や技術的詳細は次回以降に本格的に説明していこうと思います。下記の表に簡単に構想を述べておきます。

クラス 和訳 説明
Word 単語 下記の全てのクラスの基底の型。単語間の論理関係を表す為の基本的な機能を提供する。
Agent 人物 会話文を表現する利用者が用いる型。継承して使う事を前提に設計する。
Context 文脈 会話の流れや過去の記録、その他の関連するデータを保持する。
Decision 意思決定 思考の結果を記述するオブジェクト。メッセージの送受信にも使われる。
God 便利な機能をまとめた型。本当は良くないが、コードの整理が面倒な時にこれを使う事にする。

もしかすると、次回以降では上記の表の定義が変わっているかもしれませんので、参考程度として考えてください。ところで、実は以前も、神クラスを遊びで作っていました。

(最初回)今回次回→最終回