一个 problem 是规划问题的另一半。在这个领域中,我们表达问题的全局“ worldly”方面,比如我们可以执行哪些操作,以及我们计划的世界中存在哪些类型的对象。
然后,通过准确定义对象的存在、它们的真实情况以及最终的目标是什么,这个问题巩固了这个表达式。一旦规划完成,我们希望世界处于什么样的状态。
先引入一个简单的例子:
(define
(problem buildingahouse)
(:domain construction)
;(:situation <situation_name>) ;deprecated
(:objects
s1 - site
b - bricks
w - windows
c - cables
)
(:init
(on-site b s1)
(on-site c s1)
(on-site w s1)
)
(:goal (and
(walls-built ?s1)
(cables-installed ?s1)
(windows-fitted ?s1)
)
)
)
内容:
- Problem Name
- Domain
- Situation
- Objects
- Init(Initial State)
- Goal
1、Problem Name
(problem <name>)
每个问题都有一个名称,通常这是唯一的标识符。它允许使用可以扩展问题的 situation 关键字。然而,虽然这个名称通常包含在大多数问题中,但是利用情境来扩展问题并不常见。大多数问题名称都缺乏想象力,比如 prob1 或 p1
(problem buildingahouse)
2、Domain
(:domain <domain_name>)
domain参数引用问题所在的域(有关域的详细信息,请参阅域)。虽然经常在问题文件中定义,但是这个参数通常是多余的,因为大多数计划人员从命令行获取域和问题文件,并假设其中定义的域对应于另一个中定义的问题。不过情况并不总是这样,所以无论如何都值得指定域名
(:domain construction)
3、Situation
(:situation <parent_problem_name>)
situation 参数从另一个问题文件继承 qualities 。在某些情况下,我们所有的问题都有一些共同的特性,我们可以将这些特性表示为 situation 文件的一部分。例如,我们所有的问题都有两个 site,一个贮藏库和一个建筑工地。因此,我们可以将其表示为一种情况的一部分,然后在问题文件中只表示特定问题特有的方面。
situation的使用并不常见,大多数问题文件甚至会在每个文件中定义公共元素。它在一些新型的规划器不支持,弃用。
(:situation generalbuildingproblem)
4、Objects
(:objects
object_name_1 ... object_name_n - some_object_type
...
object_name_1 ... object_name_n - some_object_type
)
对象块允许我们声明存在于我们的问题中的一组对象。每个对象名称必须是惟一的,并且应该类型化。如果没有类型化,则它们通常采用基类型 object 的属性(有关详细信息,请参阅 (Domain - Object Types)
(:objects
s1 s2 s3 - site
ba bb bc - bricks
windowAlpha windowBeta windowCharlie - windows
uierjiae faufhf uihrai - cables
)
请注意,虽然传统上我们只使用一个缩写后跟数字,但我们不需要这样做,甚至可以使用一些毫无用处的名称(如上所示)。
(:objects
s1 - site
b - bricks
w - windows
c - cables
)
5、Init
(:init
<predicate>
...
<predicate>
)
初始状态(init)特别定义了在问题开始时哪些谓词为真。这不是一个逻辑表达式,因为它只是一个为真谓词列表。除非规划器或 domain 指定了其他方法,否则所有问题都应用了“ closed world”假设,即任何未指定为真都被认为是假的。因此,我们只需要列出真实的东西
(:init
(on-site b s1)
(on-site c s1)
(on-site w s1)
)
就我们的领域和问题而言,唯一True的事件是,我们需要构建的材料是 on-site。
6、Goal
(:goal logical_expression)
目标是谓词的逻辑表达式,为了将计划视为解决方案,必须满足这些谓词。本质上,这就是我们希望世界最终的样子。注意,作为逻辑表达式,如果这个表达式排除了某个谓词,那么该谓词的值就不重要。 这意味着一个目标不仅应该有为真的谓词组成,而且还应该有为假的谓词组成。
注意,所有标准逻辑操作符(如 or 和 forall )都是目标的一部分,这意味着我们可以表示多个不同的目标状态,所有这些状态都是可接受的
(:goal (and
(walls-built ?s1)
(cables-installed ?s1)
(windows-fitted ?s1)
)
)
通常,大多数目标只是连接和否定,因为在规划的最后只有一个理想的状态。
And(合取)
(and (predicate_1) ... (predicate_n))
谓词的组合,表示所有值必须为真,才能求值为真。如。
(and (walls-built ?s) (windows-fitted ?s))
Or(析取)
(or (predicate_1) ... (predicate_n))
谓词的分离,表示至少一个值必须为真,才能求值为真。如。
(or (windows-fitted ?s) (cables-installed ?s))
Imply(蕴含)
(imply (antecedent_predicate) (consequent_predicate))
An在前提谓词和结果谓词之间蕴含。当先行词为假,或先行词和结果为真时,An就意味着计算为真。如
(imply (walls-built ?s) (foundations-set ?s))
Not(非)
(not (logical_expression/predicate_name))
Not否定谓词值或逻辑表达式。在前置条件下,它表示某个谓词值或逻辑表达式为假。在效果上,它将false赋给谓词值。
(not (material-used ?b))
Forall
(forall (argument) logical_expression)
forall接受一个参数,并表示某个逻辑表达式在参数值进入后依然为真。在本例中, domain 中的所有bricks对象都没有被使用
(forall (?b - bricks)
(not (material-used ?b))
)
When
(forall (argument)
when (inclusion_expression)
logical expression
)
when扩展一个forall条件以指定包含条件。本质上是说, forall检查when中这些条件是否满足。如。
(forall (?c - bricks)
when (on-site ?c ?s)
(material-used ?c)
)
表示 forall 的bricks满足条件 on-site ?c ?s,它们还必须满足已经使用过的条件 material-used ?c
Exists
(exists (argument) logical_expression)
exists 表达的意思与 forall相同,除了不是表示给定类型的每个对象都满足一个逻辑表达式, 它表示至少有一个符合逻辑表达式就可以。
(exists
(?c - bricks)
(not (material-used ?c))
)
References
- PDDL - The Planning Domain Definition Language, [Ghallab, M. Howe, A. Knoblock, C. McDermott, D. Ram, A. Veloso, M. Weld, D. Wilkins, D.]
- OPTIC - Optimising Preferences and Time Dependent Costs
来自 <https://github.com/nergmada/pddl-reference/blob/master/docs/reference/PDDL/problem.md>