解决PDDL代码在plasp及VSC插件解析失败但Fast Downward可运行问题
问题
我正在开发一款LightsOut游戏的PDDL项目,代码可在Fast Downward中成功执行,但在Visual Studio Code的PDDL插件中出现解析错误,且plasp无法正确处理该代码。
引发问题的PDDL代码片段:
(define (domain lightsout) (:requirements :strips :disjunctive-preconditions :conditional-effects :typing) (:types light ) (:predicates (on ?l - light) (off ?l - light) (adjacent ?l1 ?l2 - light) ) (:action toggle :parameters (?l - light) :precondition (or (on ?l) (off ?l)) :effect (and (when (on ?l) (and (not (on ?l)) (off ?l))) (when (off ?l) (and (not (off ?l)) (on ?l))) (forall (?adj - light) (when (adjacent ?l ?adj) (and (when (on ?adj) (and (not (on ?adj)) (off ?adj))) (when (off ?adj) (and (not (off ?adj)) (on ?adj))) ) ) ) ) ) )
VSC PDDL插件在第25行报告的错误:
"Syntax error in (and ...)"
"Syntax error in action declaration."
"Unreadable structure"
此外plasp也无法解析该代码。问题与动作中嵌套的when和forall结构有关,需要修改代码以解决解析错误并保留功能,同时兼容两款工具。
解决方案
问题核心是嵌套的when结构不符合标准PDDL语法规范,部分解析工具(包括VSC插件和plasp)对多层嵌套的when支持有限。以下是兼容型修改方案:
1. 简化单个灯的切换逻辑
单个灯的on/off切换无需用两个when分支,直接通过谓词反转实现(前提已保证灯始终处于两种状态之一),减少嵌套层级。
2. 重构forall内的条件效果
将forall内部的多层when拆分为简洁的条件表达式,避免不必要的and包裹,符合标准解析工具的语法预期。
修改后的完整代码
(define (domain lightsout) (:requirements :strips :disjunctive-preconditions :conditional-effects :typing) (:types light ) (:predicates (on ?l - light) (off ?l - light) (adjacent ?l1 ?l2 - light) ) (:action toggle :parameters (?l - light) :precondition (or (on ?l) (off ?l)) :effect (and ; 切换当前灯的状态 (not (on ?l)) (not (off ?l)) (when (on ?l) (off ?l)) (when (off ?l) (on ?l)) ; 切换相邻灯的状态 (forall (?adj - light) (when (adjacent ?l ?adj) (and (not (on ?adj)) (not (off ?adj)) (when (on ?adj) (off ?adj)) (when (off ?adj) (on ?adj)) ) ) ) ) ) )
额外优化(可选)
如果灯的on和off状态严格互斥,可以只保留on谓词,用(not (on ?l))表示off状态,进一步简化代码,彻底消除解析歧义:
(define (domain lightsout) (:requirements :strips :disjunctive-preconditions :conditional-effects :typing) (:types light ) (:predicates (on ?l - light) (adjacent ?l1 ?l2 - light) ) (:action toggle :parameters (?l - light) :precondition (or (on ?l) (not (on ?l))) :effect (and ; 切换当前灯的状态 (not (on ?l)) ; 切换相邻灯的状态 (forall (?adj - light) (when (adjacent ?l ?adj) (not (on ?adj)) ) ) ) ) )
该版本逻辑简洁,所有PDDL解析工具均可完美兼容,且完全保留LightsOut的核心玩法。
内容的提问来源于stack exchange,提问作者李天然
相关产品推荐
相关产品推荐

