その1:16bit マイコンに論理型プログラミング言語Prologを移植
当社もマイコンの組み込みソフトウェアを開発するようになってずいぶんたちますが、前から「インタプリタが欲しいな~」と思うことがよくありました。そこで今回、スカイリーでは、"Prolog"というインタプリタ言語を、マイコン環境に実現してみました。
ベースにしたのは"S-Prolog"という処理系です。必要機能が一式揃っていながら、非常にコンパクトで使いやすい処理系です。元はMS-DOS(なつかしい・・)用ですが、これをなんとか組み込み向けに改造しました。
実装ターゲットは以下の製品です。
ルネサス RL78/G13:
Prologの詳しい説明は以下のサイトをどうぞ
Prolog - ウィキペディア(歴史的経緯など)
お気楽Prologプログラミング(言語の分かりやすい解説です)
いわゆる対話型のインタプリタ言語です。マイコン内部のファームウェアを書き換えなくても、テキストでプログラムを入力するだけで実行してくれます。対話型なのでコンソール経由で試行錯誤やデバッグができます。
ではmember/2からやってみます。マイコンはUARTでパソコンのTera Termと接続しているので、Tera Termから以下のように入力します。
member(X,[X|_]). member(X,[_|R]):-member(X,R).
これでプログラムの入力が完了です。では質問してみます。文字'a'はa, b, c, dの中に含まれますか?
?-member(a, [a, b, c, d]). yes
ちゃんとyesと答えてくれました。では、文字'a'はb, c, dの中に含まれますか?
?-member(a, [b, c, d]). no
そりゃ、noですよね~(ただしく答えてくれました)
Prologでは"?-"の後に質問を入力することでプログラムの実行を行います。
memberでは全然おもしろくないので、append/3をやってみます。Tera Termから以下のプログラムを流し込みます。
append([],List,List). append([H|T],List,[H|TList]):- append(T,List,TList).
そして質問してみます。aに、b, c, dを追加すると何になりますか?
?-append([a], [b, c, d], Y). Y = [a,b,c,d]
a, b, c, dと答えてくれました。ちょっとひねった、こんな質問はどうでしょう。「c, dに何かを追加すると、a, b, c, dになります。その何か」とは?
?-append(X, [c, d], [a, b, c, d]). X = [a,b]
なかなか賢いです。もうすこし意地悪してこういう質問「XにYを追加するとa, b, c, dになります。そのXとYの組み合わせは?」
ちゃんと全部の組み合せを答えてくれました!
では最後におなじみ、ハノイの塔をやってみましょう。パズル「ハノイの塔」についてはWikipediaをどうぞ。Tera Termから以下のプログラムをコピペで流し込みます。
hanoi(1, From, To, _) :- write([From, to, To]), nl. hanoi(N, From, To, Via) :- N1 is N - 1, hanoi(N1, From, Via, To), write([From, to, To]), nl, hanoi(N1, Via, To, From).
円盤3つで解いてみます。
どれどれ, aの円盤をbに移して、次にaの円盤をcに移して、それからbにある円盤をcに移して、、、確かに正解。うーん、私より頭いいかも?!
やはりマイコンの各種I/Oを使いたい場面が多々あります。といいますか、ペリフェラルと連動しないと組み込みにした意味がないです。そういう場合、「組み込み述語」を自分でC言語で記述して追加すれば、機能を拡張することができます。
ここでは、マイコンのA/D変換入力に接続された温度センサから温度を読み取る述語を追加してみました。
?-temp(X). X = 27 yes
これでいつでも温度が取得できます。
他、バックトラック、カットオペレータ等、標準的な機能はひと通り可能です。trace機能も載っているので(やろうと思えば)デバッグできます。
また既存のC言語プログラムとインタプリタは容易にリンクできるので、プログラム全部をPrologで記述する必要はなく、CとPrologのハイブリッドにして役割分担させられれば効果的かもしれません。
処理系単体のソフトウェアサイズは以下ように結構小型に収まりました。
これでハノイを解いた時には、正直ちょっとだけ感動しました。できればRAMサイズをもっと少なくしたいところです。
appendの例で見た通り、Prologのプログラムには双方向性という面白い特徴があります。「aにbを追加して[a, b]を得る」というプログラムを作ると、その逆方向の、「何かを足しあわせてしてa, bができる、そのXとYを探せ」と指示することができます。さらにその組み合わせをバックトラックというメカニズムで全解探索させることができます。
また、Prologにはデータやプログラム自体を実行時に登録、削除する機能があり、これをパターンマッチングで抜き出すことが可能なので、簡易データベース機能が簡単に実現できます。
そこで例えば・・
あとは今の湿度と室温から、快適かどうかをPrologが推論して結論を出します。そこでさらに双方向性を使えば、「現在の湿度X%の状況で、快適な温度は何度か?」を導き出すことも期待できます。しかもインタプリタなのでルールはハードコーディングする必要がなくいつでも差し替えられます。これを通常のプログラム言語でつくろうとすると、中々大変ですよね。
このようにPrologは、普通とかなり違う動作原理を持った言語です。使い方によっては他では真似できないデバイスが実現できそうですね~ マイコンのプログラミングがちょっと楽しくなりそうです。
近頃、"IoT (Internet of Things)”というキーワードが聞かれるようになり、センサを搭載した省電力で非力なデバイスがインターネットに接続できる環境が整ってきました。そうやってインターネットに集まった膨大なデータから意味のある役立つ情報を取り出して活用することが期待されています。
これらのデバイスは、今はまだ、ネットに接続してデータを送信するだけで一杯一杯です。でもやがては、もっと賢く、自分で「考える」力を持つようになるでしょう。
個々の"Things"たちが、まるで小さないきもののように、自律的に働き出す姿を想像をすると、数百円で購入できる安価なマイコンで人工知能言語が動くというのは、なかなか刺激的じゃありませんか?