我在Android中运行一个内嵌库tuProlog (2p.jar) Prolog推理引擎,它具有自定义的逻辑库,我可以在Android ListView中成功地查询和显示(一些)结果。
显示的只是推理引擎本身的结果,而不是像Prolog 'write‘语句这样的辅助命令,它(默认情况下)写入STDOUT。
我需要在一个Android变量中捕获“写”打印到STDOUT的结果,以便显示给用户。一般的想法(我并没有与ListView结合来实现)是模拟命令行交互,如果运行一个基于Java的Prolog解释器终端接口,就会涉及到这种交互。
为了完成这个项目,我想坚持知识工程的领域,而不是进入系统工程的领域,所以我将非常感谢对这个问题的任何见解。
我的研究引导我将here作为进一步学习的途径,但系统方面的东西很快就超过了我的经验。
非常感谢你提前……
发布于 2012-01-18 20:26:13
经过我自己的研究和与tuProlog开发人员的进一步讨论,我有了这个问题的解决方案,我认为值得与这个社区分享……
这个问题的总体背景是让任何Prolog实现在Android上正确地工作,作为以后更有趣的应用程序(专家系统、游戏AI和自然语言接口)的基础架构。
最大的障碍是,Prolog是一个基于“控制台”的解释性环境,可以打印到STDOUT,虽然安卓允许控制台打印活动,但默认情况下,它会将所有这些活动路由到/dev/null。
因此,有两组问题需要解决:(1)是否有任何可移植到安卓环境的Prolog,以及(2)当控制台输出被路由到/dev/空时,如何“正确”处理捕获问题。
地址(1):我们选择了tuProlog Site,他的官方来源可以找到:Google Code Repository - tuProlog。他们已经将prolog设计为嵌入到一个单独的JAR文件中,特别是在Android上。他们是我们发现的唯一一个做到了这一点的人,而且他们对开发人员“有反应”。他们的东西是开源Java/ Android ,他们有一个Android Prolog应用程序,很快就会更新。询问他们的代码对于找到合适的解决方案是非常有价值的。
寻址(2):为这项研究增加最大价值的链接是:Reading from PrintStream、Convert Java OutputStream to InputStream,最终是最有用的StreamWriter to OutputStream。
具体地说,需要做的是:
创建一个ByteArrayOutputStream对象来捕获打印到Console (System.out).
这是代码
// 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“命令以及其他命令的捕获。
通过仔细阅读用户指南中建立的首选方法,可以相当容易地完成严格Prolog查询的求解。开发人员可以很快地从中发现他们需要的东西。
它是对Prolog引擎函数的捕获,如Write、Spy和Error事件,这些事件更难确定(我最终咨询了开发人员)。为此,你需要询问他们的 CUIConsole 的安卓实现(而不是他们的CUIConsole的控制台实现,这是“不同的”)。
简而言之,答案是这样的:(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"感兴趣的人,我非常乐意提供我写的任何代码或我拥有的任何资源,以便帮助你完成这个过程。请不要犹豫,尽管问。
https://stackoverflow.com/questions/8851410
复制相似问题