私自身の調査と tuProlog 開発者とのさらなる議論の後、この質問に対する解決策があり、このコミュニティと共有する価値があると思います...
問題の全体的なコンテキストは、後でより興味深いアプリ (エキスパート システム、ゲーム AI、および自然言語インターフェイス) の基本アーキテクチャとして「適切に」Android で動作するように、任意の Prolog 実装を取得することです。
大きなハードルは、Prolog が STDOUT に出力する「コンソール」ベースの解釈環境であることです。Android はコンソール出力アクティビティを許容しますが、デフォルトではそのすべてを/dev/null にルーティングします。
したがって、対処すべき2つの問題があります:(1) Android環境に移植可能なPrologはありますか、( 2 )コンソール出力が/dev/nullにルーティングされたときにコンソール出力をキャプチャする問題を「適切に」処理するにはどうすればよいですか。
対処 (1) : tuProlog サイトに落ち着きました。このサイトの公式ソースは次のとおりです: Google Code Repository - tuProlog。特にAndroid向けに、プロローグを単一のJARファイルに埋め込むように設計しました。彼らはそれを行った唯一の人物であり、開発者に「対応」しています。彼らの製品はオープン ソースの Java/Androidであり、Android Prolog アプリがリリースされており、アップデートが近日中に行われます。彼らのコードを調査することは、適切な解決策を見つけるために非常に貴重でした。
アドレス指定 (2) : この調査に最も価値のあるリンクは次のとおりです。
具体的には、次のことを行う必要があります。
- ByteArrayOutputStreamオブジェクトを作成して、印刷プロセスからコンソールへのバイナリ データをキャプチャします ( System.out )。
- System.setOut (コンソール出力 [ System.out.println ]の出力先を制御する) を設定するPrintStreamオブジェクトを (ByteArrayOutputStream を使用して)作成します。
- システム出力の経路変更
- 目的のコンソール印刷出力を文字列変数にキャプチャします
- その文字列(この Android プロジェクトの場合) をリストビューの行に追加します
- リストビューのデータが変更されたことを通知する
- ByteArrayOutputStream オブジェクトをリセットします (連結を避けるため)
コードは次のとおりです。
// OutPutStream I/O Experimental Stuff
PrintStream orgStream = System.out;
// ByteArray Sub Experimental Stuff
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream psout = new PrintStream(baos, Boolean.TRUE); // Using autoFlush
// Instantiate an instance of the Prolog Engine.
//Do this only once because it's VERY expensive.
Prolog engine;
// ReRouting Print Streams
// (Inside method we need to capture console output)
System.setOut(orgStream); // Set the System Output Stream
String myResult = baos.toString(); // returns the actual text
myChatListItems.add(myResult); // Add Text to New ListView Row
chatBotAdapter.notifyDataSetChanged(); // notify the Adapter to Refresh
baos.reset(); // Reset the ByteArrayOutputStream
System.setOut(orgStream); // RESET the System Output Stream
ファイナル ノート: tuProlog は、コンソール印刷の問題を考慮して、この特定の実装を設計し、リスナーとイベントの組み合わせを使用して、Prolog の「書き込み」コマンドやその他のコマンドのキャプチャを適切に回避しました。
厳密なプロローグ クエリの解決は、ユーザー ガイドに記載されている推奨方法を熟読することでかなり簡単に実行できます。開発者はそこから必要なものをすぐに見つけることができます。
突き止めるのが難しいのは、 Write、Spy、およびError Eventsなどの Prolog Engine 関数のキャプチャです(最終的に開発者に相談しました)。そのためには、CUIConsoleの Android 実装に問い合わせる必要があります (「異なる」 CUIConsoleの Console 実装とは対照的に)。
一言で言えば、答えは次のとおりです。(a) リスナーを確立し、 (b) イベントが発生する準備をします。
コードは次のとおりです。
// Establish Prolog engine and it's appropriate listeners
// [Warning, Output, and Spy]
engine = new Prolog();
engine.addWarningListener(this);
engine.addOutputListener(this);
engine.addSpyListener(this);
//// PROLOG CONSOLE OUTPUT MECHANISMS *******************************
@Override
public void onSpy(SpyEvent e) {
Log.d(TAG, "** LG'd onSpy => SpyEvent Occured ** " );
System.out.println("** onSpy => SpyEvent Occured ** \n ");
myChatListItems.add( e.getMsg() );
chatBotAdapter.notifyDataSetChanged();
}
@Override
public void onOutput(OutputEvent e) {
Log.d(TAG, "** LG'd: onOutput => OutputEvent Occured ** " );
System.out.println("** onOutput => OutputEvent Occured ** \n ");
myChatListItems.add( e.getMsg() );
chatBotAdapter.notifyDataSetChanged();
}
@Override
public void onWarning(WarningEvent e) {
Log.d(TAG, "** LG'd: onWarning => WarningEvent Occured ** " );
System.out.println("** onWarning => WarningEvent Occured ** \n ");
myChatListItems.add( e.getMsg() );
chatBotAdapter.notifyDataSetChanged();
}
最後に:
「Prolog on Android」に興味のある方 のために、このプロセスに役立つように、私が書いたコードやリソースを喜んで提供します。お気軽にお尋ねください。