我一直在回顾一些关于STRIPS格式中AI计划表示的材料,发现不同的人似乎对同一问题有不同的表述方式。
例如,维基百科上有一个关于实验室中的猴子问题的例子。问题描述如下:
有一个箱子可以让猴子爬上去,从而够到悬挂在天花板上的香蕉。最初,猴子在位置A,香蕉在位置B,箱子在位置C。猴子和箱子的高度是低的,但如果猴子爬上箱子,他的高度就会变成高,与香蕉的高度相同。猴子可以执行的动作包括从一个地方移动到另一个地方,从一个地方推动物体到另一个地方,爬上或爬下物体,以及抓取或松开物体。如果猴子和物体在同一地点且高度相同,抓取物体就会导致持有该物体。
以下是维基百科的计划(请注意,它与此问题描述并不完全匹配,但这是同一个问题。看起来它没有实现松开动作,这对讨论并不重要):
在这份计划中,我找不到任何关于香蕉位于高处的信息,因此唯一从计划中得知这一信息的方法是通读整个动作集,并从中推断出猴子必须在高处才能与香蕉互动,因此香蕉一定在高处。
将此信息放入初始状态是否是个好主意,并添加类似于以下内容:
Monkey(m) & Bananas(ba) & Box(bx) & Level(low) & Level(high) & Position(A) & Position(B) & Position(C) & At(m, A, low) & At(ba, B, high) & At(bx, C, low)
这样看起来相当冗长,但同时,它允许读者仅通过阅读初始状态就能理解场景。我还被告知在STRIPS中不应该使用常量,所以我认为将A、B、C声明为位置是个好主意。
是因为有些人做得不同(我觉得这会破坏使用标准化语言来表示事物的想法),还是我展示的方式之一不是正确的格式?我对STRIPS是新手,所以完全有可能(而且很可能)我错过了一些关键点。
回答:
这不是最好的维基百科。STRIPS的描述是准确的,但有点过时了。
一般来说,你不需要担心在初始状态中定义所有变量,因为变量是由领域定义的(链接文章中的四元组中的P)。为了直观理解为什么会这样,你在初始状态中有一个MONKEY
操作符,但你仍然引入了未在其他地方定义的自由变量m
。如果你尝试这样做,你会遇到先有鸡还是先有蛋的问题,所以系统中的事实只是命题变量,这些变量实际上是哨兵值,对系统的用户有意义,而不是系统本身。
你正确地指出需要在初始状态中为每个项目定义级别,但考虑到香蕉总是高,箱子总是低,只有猴子的级别会变化,这个例子中的初始状态实际上是正确的。我可能会更改这个例子,让At
命题考虑到相关对象,而不是为每个对象使用不同的命题名称,但这只是风格选择;语义是相同的。
STRIPS中的操作符通常由三个不同的组成部分表示:
- 前提条件 – 前提条件列表中的每个变量必须与当前状态中的相应变量完全匹配(真的必须是真的,假的必须是假的),但你忽略所有前提条件中未明确列出的其他变量
- 添加效果 – 当执行动作时,这些是添加到状态中的变量效果
- 删除效果 – 当执行动作时,这些是从状态中删除的效果
- 有时还有第四个成本组成部分,当考虑成本优化时
你在例子中列出的后置条件是添加效果和删除效果的联合。将它们分开的好处将在你进入删除放松抽象时体现出来。
在你提出的初始状态中,你有包含同一对象的多个属性的命题(例如At(bx, C, low)
)。这通常会被避免,取而代之的是为状态中每个对象的每个属性设置一个命题。这样做会使状态变大,但会使实现变得更加简单,因为你不需要分解状态变量来识别前提条件列表中对象的特定属性的值。