4

埋め込みライブラリ [tuProlog (2p.jar)] Prolog Inference Engine を Android で実行しています。カスタム ロジック ベースを使用して、Android ListView で結果の一部を正常にクエリおよび表示できます。

表示されるのは推論エンジン自体からの結果のみであり、(デフォルトで) STDOUT に書き込む Prolog 'write' ステートメントのような補助コマンドではありません。

その「書き込み」出力の結果を Android 変数の STDOUT にキャプチャして、ユーザーに表示する必要があります。一般的なアイデア (実装する ListView とは関係ありません) は、Java ベースの Prolog Interpreter ターミナル インターフェイスを実行した場合に実行されるコマンド ライン インタラクションをシミュレートすることです。

このプロジェクトを完了するために、システム エンジニアリングに入るよりも知識工学の領域にこだわりたいので、この問題についての洞察をいただければ幸いです。

私の研究は、さらなる研究の道筋として私をここに導きましたが、システムのことはすぐに私の経験を超えてしまいます.

よろしくお願いします....

4

1 に答える 1

4

私自身の調査と 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 の「書き込み」コマンドやその他のコマンドのキャプチャを適切に回避しました。

厳密なプロローグ クエリの解決は、ユーザー ガイドに記載されている推奨方法を熟読することでかなり簡単に実行できます。開発者はそこから必要なものをすぐに見つけることができます。

突き止めるのが難しいのは、 WriteSpy、および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」に興味のある方 のために、このプロセスに役立つように、私が書いたコードやリソースを喜んで提供します。お気軽にお尋ねください。

于 2012-01-18T12:26:12.920 に答える