2

在我的应用程序中,我有许多代理,每个代理都有自己的知识库。
我最初的想法是拥有多个引擎实例,但 swi prolog 最多允许一个实例。
另一种方法是在每个事实和规则中添加一个表示代理 id 的附加术语,但这似乎很麻烦。

例如,而不是:

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

我不得不到处写:

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

因为我会一次更新一个代理,即使每次都保存和恢复所有内容也可能没问题,即使我不知道该怎么做。还是使用模块?
分离不同知识库的好方法是什么?

4

1 回答 1

4

我认为您建议将原子 ID 添加到您的事实以识别它对应的代理是一个不错的建议,但同意回想起来添加到您的代码中可能会很麻烦。

这里有一些其他的建议,大致按照我的喜好排列......

  1. 使用记录的数据库。有了这个,您实际上可以使用原子键记录事实,因此可以推测,您可以使用recorda/3and like 谓词分别使用代理 ID 记录每个代理的事实,然后使用recorded/2,3来检索它们。几乎正是您想要的。
  2. 使用模块。大概您可以简单地为每个代理创建新的模块名称,从而分离每个代理的事实,就像使用命名空间的方式一样。例如,断言agent0:position(10,20).
  3. assert/2使用返回子句引用明确跟踪您为每个代理断言的事实。通过保留一个引用列表来标识为特定代理断言的所有事实,您可以使用erase/1. 请注意,将子句引用与clause/3通过它们的引用一起检索子句的组合使用retract/1可能会收回属于其他代理的类似子句。
  4. 根据您的程序的结构,您可以简单地传递一个包含每个代理的所有事实的大型数据结构,例如:[agent0-[fact1(..), fact2(..), ...], agent1-[...], ...]并随时更新该术语。请注意,这不如使用数据库本身高效,因为它需要对特定事实进行大量线性扫描;不能使用哈希查找。
于 2012-12-17T06:43:47.897 回答