2012-12-16 166 views
1

我的应用程序我有许多代理商,每个代理商都有自己的知识库。
我最初的想法是有多个引擎实例,但swi prolog最多只允许一个实例。
另一种方法是在每个事实和规则中添加一个表示代理ID的附加项,但它看起来非常麻烦。SWI Prolog多知识库

例如,而不是:

position(10, 20). 
do(action(X)):-... 

我会到处写:

position(agent0, 10, 20). 
do(Agent, action(X)):-... 

因为我将在同一时间更新一剂,连保存和恢复一切每次可能好的,即使我不知道该怎么做。或者使用模块?
什么是分离不同知识库的好方法?

+1

看到[Logtalk](http://logtalk.org/) – CapelliC

+0

谢谢,我正在调查它... –

回答

3

我认为你给你的事实添加一个原子ID来标识它所对应的代理的建议是一个很好的建议,但同意这可能是麻烦的添加到你的代码回顾。

这里有一些其他的建议,大致在我的优先顺序...

  1. 使用recorded database。有了这个,你实际上可以用原子键记录事实,所以假设你可以使用recorda/3等谓词来分别用代理ID记录每个代理的事实,然后使用recorded/2,3来检索它们。几乎正是你想要的。
  2. 使用modules。大概你可以简单地为每个代理创建新的模块名称,从而为每个代理分离事实,就像名称空间的使用方式一样。例如,声称agent0:position(10,20)
  3. 使用返回子句引用的assert/2保持显式跟踪您为每个代理声明的事实。通过保留一份参考文献清单,其中列出了针对特定代理商的所有事实,您可以使用erase/1快速收回它们。请注意,使用子句引用和clause/3的组合以通过引用检索子句以及retract/1可能会收回属于其他代理的类似子句。
  4. 根据程序结构的不同,您可以简单地在列表中为每个代理程序传递一个大数据结构,如下所示:[agent0-[fact1(..), fact2(..), ...], agent1-[...], ...]并随时更新此术语。请注意,这不像使用数据库本身那样高效,因为它需要对特定事实进行大量的线性扫描;散列查找无法使用。
+0

关于模块:问题是,需要(例如)位置/ 2 *必须*使用agent0限定它:即,您需要将模块标识符传递给每个此类规则,完全符合OP的抱怨。我真的很希望看到一个可行的解决方法,因为我写了(25年前!)一个面向对象的Prolog解释器与这些功能可用.... – CapelliC

+0

谢谢你的替代品。 Logtalk看起来像是一个非常强大的工具,对于像我这样第一次使用prolog的人来说,有一些面向对象的元素让人放心。我没有注意到记录的数据库,这看起来很容易和快速的使用。 –