PDDL 1.2中的域文件定义了问题的“通用(universal)”方面。本质上,这些方面是不会改变的,不管我们试图解决什么特定的情况。在PDDL 1.2中,这主要是模型中可能存在的对象类型、谓词和操作。
先引入一个简单的例子:
(define
(domain construction)
(:extends building)
(:requirements :strips :typing)
(:types
site material - object
bricks cables windows - material
)
(:constants mainsite - site)
;(:domain-variables ) ;deprecated
(:predicates
(walls-built ?s - site)
(windows-fitted ?s - site)
(foundations-set ?s - site)
(cables-installed ?s - site)
(site-built ?s - site)
(on-site ?m - material ?s - site)
(material-used ?m - material)
)
(:timeless (foundations-set mainsite))
;(:safety
;(forall
; (?s - site) (walls-built ?s)))
;deprecated
(:action BUILD-WALL
:parameters (?s - site ?b - bricks)
:precondition (and
(on-site ?b ?s)
(foundations-set ?s)
(not (walls-built ?s))
(not (material-used ?b))
)
:effect (and
(walls-built ?s)
(material-used ?b)
)
; :expansion ;deprecated
)
(:axiom
:vars (?s - site)
:context (and
(walls-built ?s)
(windows-fitted ?s)
(cables-installed ?s)
)
:implies (site-built ?s)
)
;Actions omitted for brevity
)
其中包含了这些信息:
-
Domain Name
-
Extends
-
Requirements
-
Types
-
Constants
-
Domain Variables
-
Predicates
-
Timeless Predicates
-
Safety Constraint
-
Actions
-
Axioms
1、Domain Name
(domain <name>) ==> (domain construction)
域始终以命名开头。在我们打开第一个括号并写下(define下一个参数后,我会立即执行(domain <name>)。虽然大多数规划人员从文件中获取域名,但您在命令行上传递了域名,并且不会检查域文件中的域名是否与问题文件中的域名相对应,有些人会这样做。最佳做法是包含此名称,以防万一。
请注意,我们在扩展域时也会使用此名称。
2、Extends
(:extends <domain_name>) ==> (:extends building)
该:extends参数允许域扩展另一个“父”域。使用:extends参数时,域从其父级继承以下内容
-
要求
-
类型
-
常量
-
行动
-
公理
-
永恒的命题
3、Requirements
(:requirements <requirement_name>) ==> (:requirements :strips :typing)
需求类似于编程语言中的import / include语句,但是由于PDDL是一种声明性语言,因此它是一种:requirement“必需”的规划器,以实现语言的某些方面, :requirements可以通过空格分隔列表指定多个。
4、Types
(:types
<type_name_1> ... <type_name_n> - object
<sub_name_1> ... <sub_name_n> - <type_name_1>
)
类型允许我们创建基本类型和子类型,我们可以将谓词应用于这些类型。 我们使用类型来限制哪些对象形成操作(action)的参数。 类型和子类型允许我们声明一般和特定的操作和谓词。
(:types
site material - object
bricks cables windows - material
)
这是一个类型定义。我们有一个表示建筑场地的类型 site和一个表示任何通用建筑材料的类型 material。
然后我们声明子类型 bricks, cables和 windows,这是所有类型的建筑material。
当前对象结构:
material
-
bricks
-
cables
-
windows
我们可以声明适用于任何基类型的通用谓词,例如。
(material-used ?m - material)
它适用于任何物质类型的东西。或者我们可以创建特定的谓词,比如
(windows-clean ?w - windows)
这个只适用于特定的子类型。
当前对象结构:
material
-
bricks
-
cables
-
windows
-
windows-clean
-
-
material-used
site
我们可以更进一步,比如用动作来做同样的事情。
(:action MOVE-MATERIAL
:parameters (?s1 - site ?s2 - site ?m -material)
...
)
动作MOVE-MATERIAL接收参数s1、s2类型为site,m为material。
当我们希望表达任何材料从一个地点到另一个地点的移动。我们移动的物质并不重要,因为它只是在被移动。注意,我们不能在这个操作中使用谓词 (windows-clean),因为并不是所有的 material都为它定义了这个谓词。
或者,如果我们想使用特定的材料,比如当我们在建造一堵墙时,我们可能会这样声明一个动作
(:action BUILD-WALL
:parameters (?s - site ?b - bricks)
...
)
上述操作要求特定对象是 bricks类型,因此我们可以使用使用 bricks的谓词。然而,因为所有的 bricks都是 materials,所以我们还可以使用谓词,在我们的操作中以材料为例( (material-used)
5、Constants
(:constants mainsite - site)
Constants允许我们声明存在于问题的所有实例中的对象。在上面的例子中,我们假设所有的问题都包含一个 mainsite,其中一些问题可能还包含其他的建筑site。
这在实践中并不常见,因为我们只是在每个特定的问题中重复声明对象。
6、Domain Variables
(:domain-variables (numthings 2) - integer)
域变量是表示数值的一种较老的方法,在PDDL2.1中重新定义。您可能不会看到像这样声明域,而使用PDDL2.1中更简单、更富表现力的格式。
此外,大多数规划器不支持这种语法
7、Predicates
(:predicates
(<predicate_name> <argument_1> ... <argument_n>)
)
谓词适用于特定类型的对象,或适用于所有对象。谓词在计划中的任何时刻都是真或假的,如果没有声明谓词,则假定为假(除非将开放世界假设作为一个需求包含在内)。
谓词声明的示例如下所示。在大多数情况下,谓词通常只接受一个或两个对象作为参数。但这不是一个限制,谓词(理论上)可以接受用户希望的任意多的参数。
(:predicates
(walls-built ?s - site)
(windows-fitted ?s - site)
(foundations-set ?s - site)
(cables-installed ?s - site)
(site-built ?s - site)
(on-site ?m - material ?s - site)
(material-used ?m - material)
)
在本例中,当谓词 (walls-built ?s)对给定site为真时,我们可以假设该site已经筑了墙壁。当它是假的,我们会假设site没有墙壁。
在另一种情况下,假设有多个site,其中分布着各种material,我们可以使用谓词 on-site来描述不同site上material的位置。例如 (on-site bricks1 site1) 表示材料 bricks1当前位于 site1。
要移动砖块,我们将创建一个动作,该动作表示 (on-site bricks1 site1)现在为false(假设 site2是我们移动砖块到达的位置) (on-site bricks1 site2)现在为true。
8、Timeless Predicates
(:timeless (<predicate_name> <arguments>))
一个不受时间限制的谓词是一个始终为真且不能被域中的任何操作所改变的谓词。不清楚为什么需要对始终为真且从不更改的东西建模,但它包含在规范中。下面提供了一个示例。
(:timeless (foundations-set mainsite))
9、Safety Constraint
(:safety <condition>)
安全条件是任何计划要想有效,必须在计划结束时为真。这与目标条件有何不同尚不清楚
(:safety
(forall
(?s - site) (walls-built ?s)))
它可以用来从本质上定义全局目标,这些目标必须得到满足,而不管具体的问题是什么。实际上,这些全局目标仍然会被编码到问题文件中。
10、Actions
(:action <action_name>
:parameters (<argument_1> ... <argument_n>)
:precondition (<logical_expression>)
:effect (<logical_expression>)
; :expansion
)
行动定义了世界中每个状态的转换。此转换通常是一个可以在计划执行过程中执行的操作,例如获取一个对象、构造一些东西或其他更改。
一个动作被分成三个不同的部分,在最后一个部分可以进行替换。
-
第一个部分是 :parameters部分,它定义了我们正在执行的操作,以及随后要检查和操作的谓词。
-
第二部分是 :precondition部分。它们通常是一系列谓词连接和析取,必须满足这些连接和析取,才能执行所应用的操作。注意,尽管一个行动的前提条件可能得到满足,但这并不意味着它在计划中得到应用。最终,重要的是行动的效果
-
第三部分是在 :effect和 :expansion之间进行选择,一个动作不能同时拥有这两者。大多数域使用 :effect。没有提供如何使用的细节 :expansion,因为没有很多的规划器支持它。
(:action BUILD-WALL
:parameters (?s - site ?b - bricks)
:precondition (and
(on-site ?b ?s)
(foundations-set ?s)
(not (walls-built ?s))
(not (material-used ?b))
)
:effect (and
(walls-built ?s)
(material-used ?b)
)
)
Parameters:
:parameters (argument_1 ... argument_n)
==>
:parameters (?s -site ?b - bricks)
这些参数定义了我们感兴趣的对象的类型。注意,参数可以接受任何类型或子类型。例如,如果我们有三个site实例,例如 s1、s2和s3,而我们有两个bricks b1、b2实例,我们的规划器会考虑所有可能的操作,例如:
(BUILD-WALL s1 b1) (BUILD-WALL s2 b1) (BUILD-WALL s3 b1)
(BUILD-WALL s1 b2)(BUILD-WALL s2 b2) (BUILD-WALL s3 b2)
因此,指定操作应用到的特定对象并不取决于我们用户,而是取决于action应用到的对象的类型。
在这种情况下,当我们建造一堵墙时,我们需要知道我们用什么砖来建造它,以及我们在哪里建造它。我们的行为是特定于我们选择考虑和建模的问题的,因此可能有其他用户想要或者需要建模而我不想建模的其他东西。
您的领域和问题应该只考虑和建模您试图解决的问题的各个方面。例如,这里我们还没有为实际执行工作的人建立模型,但是如果我们是一个更大的建筑工地的经理,我们可能想要这样做,因此我们需要调整这些模型。
-
Either
:parameters (?x - (either bricks windows))
这 either 术语都表示一个参数可以在这两个表达式中包含任何类型的参数。在上面的例子中,
?x可以是 bricks类型,也可以是 windows类型。
这种功能很少用于支持子类型。然而, 在直接继承的情况下,不可能把两种截然不同的类型归为一类。
Preconsitions:
:precondition (<logical_expression>)
==>
:precondition (and
(on-site ?b ?s)
(foundations-set ?s)
(not (walls-built ?s))
(not (material-used ?b))
)
前提条件是为了使一项行动成为可能而必须满足的条件。仅仅因为某个行动是可能的,并不意味着它一定会被应用,而且规划器总是会考虑某个行动是否会使状态更接近目标状态。
上面的语句是一个连词,可以认为如下所示
os(b, s) /\ fs(s) /\ ¬wb(s) /\ ¬mu(b) (/\表示“合取”,¬表示“非”)
在PDDL中,并应用于其中的所有谓词。有关逻辑关键字的详细信息,请参见下面
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接受一个参数,并表示某个逻辑表达式在整个参数中为真。在本例中, 域中的所有bricks对象都没有被使用
(forall (?b - bricks)
(not (material-used ?b))
)
When
(forall (argument)
when (inclusion_expression)
logical expression
)
当扩展一个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))
)
Exists 不能用作 effect。
Effects:
:effect (logical_expression)
==>
:effect (and
(walls-built ?s)
(material-used ?b)
)
效果由一个连接逻辑表达式组成,该表达式定义如果应用某个操作,应该将哪些值设置为true或false。注意,虽然它是一个逻辑表达式,但它不具有 precondition的表达性,因为我们只能为它分配一组真值。
这限制了我们只能使用 and和 not表达行动的效果。虽然理论上我们也可以使用 forall,但这并不受支持,也不适合建模过程,因为通常我们将计划对其产生 effect的所有对象(以及谓词)作为 parameters。
11、Axioms
(:axiom
:vars (arguments)
:context (logical_expression)
:implies (logical_expression)
)
==>
(:axiom
:vars (?s - site)
:context (and
(walls-built ?s)
(windows-fitted ?s)
(cables-installed ?s)
)
:implies (site-built ?s)
)
axiom是一个派生谓词,它的值本质上是一个逻辑表达式相对于其他谓词求值的结果
在上面的例子中,我们说的是对于任何给定的建筑工地,如果墙是建造的 (walls-built) ,窗户是安装的 (windows-fitted) ,电缆是安装的 (cables-installed),那么这意味着 site 是建造的 (site-built)。
如果在多个位置重复使用逻辑表达式,这非常有用,因为您可以将其简化为单个谓词。然而,这种语法并不常用
References
-
PDDL - The Planning Domain Definition Language, [Ghallab, M. Howe, A. Knoblock, C. McDermott, D. Ram, A. Veloso, M. Weld, D. Wilkins, D.]
原文github地址:https://github.com/nergmada/pddl-reference/blob/master/docs/reference/PDDL/domain.md