在PDDL的driverlog域中,我们定义了链接(link)和路径(path)。
(define (domain driverlog) (:requirements :typing) (:types location locatable - object driver truck obj - locatable ) (:predicates (at ?obj - locatable ?loc - location) (in ?obj1 - obj ?obj - truck) (driving ?d - driver ?v - truck) (link ?x ?y - location) (path ?x ?y - location) (empty ?v - truck) )
在问题中定义的方式如下:
(define (problem DLOG-2-2-2) (:domain driverlog) (:objects driver1 - driver driver2 - driver truck1 - truck truck2 - truck package1 - obj package2 - obj s0 - location s1 - location s2 - location p1-0 - location p1-2 - location ) (:init (at driver1 s2) (at driver2 s2) (at truck1 s0) (empty truck1) (at truck2 s0) (empty truck2) (at package1 s0) (at package2 s0) (path s1 p1-0) (path p1-0 s1) (path s0 p1-0) (path p1-0 s0) (path s1 p1-2) (path p1-2 s1) (path s2 p1-2) (path p1-2 s2) (link s0 s1) (link s1 s0) (link s0 s2) (link s2 s0) (link s2 s1) (link s1 s2) )
路径和链接有什么区别?我尝试创建一个类似的但省略了路径的问题,结果总是得到“无法解决的问题”。我该如何正确定义路径呢?
谢谢!
回答:
这些是用户定义的谓词:
(define (domain driverlog) ... (:predicates ... (link ?x ?y - location) (path ?x ?y - location) ... ) )
因此,可以通过检查相应的模型来推断它们的语义。
link
和path
都是二元谓词,它们将两个位置联系起来,显然是当可以从一个地方移动到另一个地方时。这种连接是单向的。
我从源代码中读到,定义了以下动作:
(:action DRIVE-TRUCK :parameters (?truck ?loc-from ?loc-to ?driver) :precondition (and (TRUCK ?truck) (LOCATION ?loc-from) (LOCATION ?loc-to) (DRIVER ?driver) (at ?truck ?loc-from) (driving ?driver ?truck) (link ?loc-from ?loc-to)) :effect (and (not (at ?truck ?loc-from)) (at ?truck ?loc-to)))(:action WALK :parameters (?driver ?loc-from ?loc-to) :precondition (and (DRIVER ?driver) (LOCATION ?loc-from) (LOCATION ?loc-to) (at ?driver ?loc-from) (path ?loc-from ?loc-to)) :effect (and (not (at ?driver ?loc-from)) (at ?driver ?loc-to)))
因此,如果可以从一个地方DRIVE-TRUCK
到另一个地方,那么这两个位置之间就有一个链接;如果可以从一个地方WALK
到另一个地方,那么这两个位置之间就有一个路径。
关于这一点,真的没有更多可说的了。
你不断得到UNSAT
的原因是因为你将司机和卡车放在了两个不同的位置:
(at driver1 s2)(at driver2 s2)(at truck1 s0)(at truck2 s0)
由于s0
和s2
之间的唯一连接是链接,司机无法到达卡车(反之亦然)。这是因为DRIVE-TRUCK
的一个前提条件是(driving ?driver ?truck)
,只有当司机和卡车在同一位置时,BOARD-TRUCK
才会设置这个条件。
你可以通过在s0
和s2
之间创建一个路径来解决这个问题。然而,这似乎违反了模型的命名惯例,该模型仅使用链接来连接sX
。更好的解决方案是更改初始状态,将卡车放置在每个司机所在的位置,或者至少放置在可以通过WALK
动作到达的位置。