PDDL2.1中的域语法在1.2版的基础上进行了扩展,包括两个关键的新特性,持久性操作( durative-actions)和函数( functions),它们被称为数值流。在1.2规范的基础上指定了额外的新需求,以允许较老的规划器识别出他们不能解决这些新领域的问题
引入一个例子:
(define (domain rover-domain)
(:requirements :durative-actions :fluents :duration-inequalities)
(:types rover waypoint)
(:predicates
... ; Predicates omitted
)
(:functions
(battery-amount ?r - rover)
(sample-amount ?r - rover)
(recharge-rate ?r - rover)
(battery-capacity)
(sample-capacity)
(distance-travelled)
)
(:durative-action move
:parameters
(?r - rover
?fromwp - waypoint
?towp - waypoint)
:duration
(= ?duration 5)
:condition
(and
(at start (rover ?rover))
(at start (waypoint ?from-waypoint))
(at start (waypoint ?to-waypoint))
(over all (can-move ?from-waypoint ?to-waypoint))
(at start (at ?rover ?from-waypoint))
(at start (> (battery-amount ?rover) 8)))
:effect
(and
(decrease (fuel-level ?t) (* 2 #t))
(at end (at ?rover ?to-waypoint))
(at end (been-at ?rover ?to-waypoint))
(at start (not (at ?rover ?from-waypoint)))
(at start (decrease (battery-amount ?rover) 8))
(at end (increase (distance-travelled) 5))
)
)
... ; Additional actions omitted
)
内容:
- Requirements
- Numeric Fluents
-
Durative Actions
- :parameters
- :duration
- condition
- effect
- Continuous Effects
1、Requirements
(:requirements <requirement_name>)
Requirements 类似于编程语言中的import/include语句,但是由于PDDL是一种声明性语言,所以它是:作为给定规划器的 :requirement是“必需的”,以促进语言的某些实现。
下面是PDDL2.1向PDDL语言添加的需求列表。
- :fluents
- durative-actions
- durative-inequalities
- continuous-effects
- negative-preconditions
2、Numeric Fluents
(:functions
(<variable_name> <parameter_name> - <object_type>)
...
(<variable_name> <parameter_name> - <object_type>)
)
与谓词类似的数值流是一个变量,它应用于零个或多个对象,并在整个计划期间保持一个值。它是用一个名称后跟它所应用的对象类型来声明的。如:
(:functions
(battery-level ?r - rover)
)
例子表示域中的每个rover对象都有一个变量,该变量为 battery-level赋值。一个函数可以应用于0个或多个对象,这意味着我们也可以使用它来表示两个值之间的数值,例如距离。
(:functions
(distance ?wp1 - waypoint ?wp2 - waypoint)
)
数值影响可以通过动作和持续动作的效果来改变。数值流有许多受支持的效果。
Prefix Maths—数学前缀(前缀表达式)
Add(加)
(+ (sample-capacity) (battery-capacity))
Subtract(减)
(- (sample-capacity) (battery-capacity))
Multiply(乘)
(* (sample-capacity) (battery-capacity))
Divide(除)
(/ (sample-capacity) (battery-capacity))
前缀表示法用于表示数字流上的数学运算。我们可以看到四个主要的二进制操作,我们可以执行的数字通量。在所有这些情况下,为了转换为中缀符号,我们将运算符放在两个对象的名称之间。
Increase(递增)
(increase (battery-level ?r) 10)
递增效果将数值变量的值增加给定的值。例如,可以使用另一个数值变量作为递增值
(increase (battery-level ?r) (charge-available - ?solarpanel))
如果是function中定义的为数值函数
用法是:
(increase (total-cost) (io-cost ?s ?size)) ;;domain文件
(= (io-cost server4 number5) 5) ;;problem中init定义
Decrease(递减)
(decrease (battery-level ?r) 10)
递减效应使数值变量的值减少给定的数量。例如,可以使用另一个数值变量作为递减值。
(decrease (battery-level ?r) (power-needed-for-work - ?task))
Assign(赋值)
(assign (battery-level ?r) 10)
赋值效果将数值变量的值赋给给定的金额。例如,可以使用另一个数值变量作为赋值。
(assign (battery-level ?r) (max-charge ?r))
Scale Up(增大)
(scale-up (battery-level ?r) 2)
将数值变量的值增加给定的比例因子。比例因子可以是另一个数值变量
(scale-up (battery-level ?r) (charge-rate ?r))
Scale Down(缩小)
(scale-down (battery-level ?r) 2)
将数值变量的值降低给定的比例因子。比例因子可以是另一个数值变量
(scale-down (battery-level ?r) (consumption-rate ?r))
3、Durative Actions
(:durative-action <action_name>
:parameters (<arguments>)
:duration (= ?duration <duration_number>)
:condition (logical_expression)
:effect (logical_expression)
)
持续性动作(durative action)是一个动作,它代表一个需要大量时间来完成的动作。时间量可以表示为值或不等式(允许固定持续时间和范围持续时间操作)。与传统的 action相似,我们也有 condition和 effect,但需要注意的是,持续性行为中的关键词是 condition而不是 precondition。
这种语义变化的目的是表示持续性动作(durative action)不仅可能在动作开始时出现条件,而且可能在动作结束或持续期间出现需要为true的条件。 飞行计划就是一个很好的例子 ,为了让飞机起飞和降落, fly 动作要求跑道在动作开始和结束时是可用的。同时当飞机在飞行时,跑道不需要是可用的。
Parameters:
:parameters (argument_1 ... argument_n)
==>
:parameters (?s -site ?b - bricks)
69
这些参数定义了我们感兴趣的对象的类型。注意,参数可以接受任何类型或子类型。例如,如果我们有三个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应用到的对象的类型。
在这种情况下,当我们建造一堵墙时,我们需要知道我们用什么砖来建造它,以及我们在哪里建造它。我们的行为是特定于我们选择考虑和建模的问题的,因此可能有其他用户想要或者需要建模而我不想建模的其他东西。
领域和问题应该只考虑和建模我们试图解决的问题的各个方面。例如,这里我们还没有为实际执行工作的人建立模型,但是如果我们是一个更大的建筑工地的经理,我们可能想要这样做,因此我们需要调整这些模型。
Duration:
Fixed Value(定值)
:duration (= ?duration <duration_number>)
inequality value(不定值)
:duration (> ?duration <duration_number>)
:duration (< ?duration <duration_number>)
:duration (and
(> ?duration <duration_number>)
(< ?duration <duration_number>))
持续时间可以表示为一个固定值,也可以表示为一个不等式。也可以将持续时间表示为数值流的值,这意味着移动等操作的持续时间依赖于两点之间的距离。
:duration (= ?duration 10)
Condition:
:condition (<logical_temporal_expression>)
条件是逻辑表达式和时态表达式,必须满足这些条件才能执行持续操作。由于持续性动作是随着时间而发生的,我们可能希望表示在动作的持续期间或结束时满足了其他条件,而不仅仅是动作的开始。这就产生了三个新的关键字 at start、 at end和 over all。
:condition
(and
(at start (rover ?rover))
(at start (waypoint ?from-waypoint))
(at start (waypoint ?to-waypoint))
(over all (can-move ?from-waypoint ?to-waypoint))
(at start (at ?rover ?from-waypoint))
(at start (> (battery-amount ?rover) 8)))
At Start
带有 at start前缀的表达式或谓词意味着,要应用操作,条件必须在action开始时为true。如。
(at start (at ?rover ?from-waypoint))表示在 at start 时给定的 rover 是 at from-waypoint的。
令人困惑的是,在这个特定域中, at 是一个表示对象 at 某一点位置的谓词,同时 at start是一个关键字。
at start 通常用于每个谓词
At End
在 at end加前缀的表达式或谓词,意思是在动作结束时条件必须为真,才能应用该动作。
(at end (>= (battery-amount ?rover) 0)
本质上,我们说的是,虽然这个事实在开始或行动时不一定是真的,但在最后一定是真的。在本例中,我们表示动作结束时电池电量必须大于零。
Over All
带有一个 overall前缀的表达式或谓词,意味着该条件必须在整个操作中为真,包括在开始和结束时。如。
(over all (can-move ?from-waypoint ?to-waypoint))
在执行操作的所有点上,给定的表达式必须求值为true。在上面的例子中,我们表示必须能够从from-waypoint移动到to-waypoint,从而完成整个操作。也就是说,我们不想在操作进行到一半时发现,在某个点之后,某个路径被阻塞了导致操作不能完成。
Effect:
:effect (<logical_temporal_condition>)
与传统动作类似的效果,是在应用某个动作时使其为真的条件。请注意,这种效果总是有更多的限制,通常只允许 and和 not作为逻辑表达式。
时态表达式(如 at start和 at end)是可用的,但是一般不使用 over all。因为布尔效应为真在整个操作过程中并不常见。相反,你可以在开始时使用 at start将其设置为true,并在结束时使用 at end将其设置为false
:effect
(and
(at start (not (at ?rover ?from-waypoint)))
(at start (decrease (battery-amount ?rover) 8)))
(at end (at ?rover ?to-waypoint))
(at end (been-at ?rover ?to-waypoint))
上面的效果是说,在 at start的时候, rover 不能再被认为是在from-waypoint,而在 at end 的时候,它现在可以被认为是在to-waypoint。它还添加了第二个谓词 been-at,表示探测器在某个时刻 到达了给定的 waypoint。
4、Continuous effects
(increase (fuel ?tank) #t)
(decrease (battery ?battery) (* 5 #t))
连续效果是定义效果的另一种方法,值得专门讨论。连续效应定义了对数值变量的影响,该数值变量通过持续作用的应用是连续的。简单地说,它定义了一个变量在操作期间不断地变化。
我们可以在现实世界的燃料和电池问题中看到这种影响。随着驾驶时间的延长,我们会消耗更多的燃料,因此可以用连续效应来模拟。此外,连续效果允许规划模型考虑在持续操作终止之前操作的应用
假设我们有一个充电动作,每单位时间只给1%的电池充电,我们会在动作的效果块内用这个情况来建模
(increase (battery ?b) #t)
#t充当一个数值变量,表示动作中的当前时间点,所以我们说的函数是 (* 2 #t), 对于一个动作的每一个时间单位,变化量的值乘以2。
让我们说,我们的充电行动已经完成了一半, 到那时,电池已经充满了足够的电量,我们可以进行另一个动作, 另一个动作可能消耗一些电池,没有连续的效果, 我们最有可能在充电操作结束时进行动作,这意味着任何需要消耗电池的动作都必须等到充电完成后才能使用
Without Continuous effects (plan length: 15)
b=0
|--(recharge[10])--| |--(drive[5]--|
(b+=10) (b>5) (b-=5)
With Continuous effects (plan length: 10)
b=0
|--(recharge[10])--|
(b+=#t)
|--(drive[5])--|
(b>5) (b-=5)
在连续效应的作用下,电池在充电过程中充电到满足驱动动作的一半前提的水平。否则,我们必须等到应用了充电操作的充电效果之后,才能应用驱动操作,从而得到一个更长的(而且可以说是次优的)解决方案
References
- PDDL - The Planning Domain Definition Language, [Ghallab, M. Howe, A. Knoblock, C. McDermott, D. Ram, A. Veloso, M. Weld, D. Wilkins, D.]
- PDDL2.1: An Extension to PDDL for Expressing Temporal Planning Domains, [Fox, M. Long, D.]
- PDDL Examples
- OPTIC - Optimising Preferences and Time Dependent Costs
来自 <https://github.com/nergmada/pddl-reference/blob/master/docs/reference/PDDL2.1/domain.md>