我正在尝试编写一个CLIPS程序来解决任何一个Sokoban关卡,但我遇到了一个巨大的问题:
在这个例子中,我只有场地的初始状态和一个规则,该规则尝试在右侧没有箱子或障碍物的情况下将玩家向右移动(在完整的程序中,我也有一些移动箱子的规则)。问题出现在当我有一个状态与LHS ?ff <- (R ?Ir ?Xr ?Yr $?a B ?Ib ?Xb ?Yb $?b S ?Is ?Xs ?Ys ?Es $?c W ?w D ?d L ?l F ?)
匹配,而另一个由于箱子移动而创建的状态,使得规则 (not (R $? B ? =(+ ?Xr 1) ?Yr $?) )
即使在第一个状态下为真时也不为真。
(deffacts InitialState ;------static--------- (MAX_DEPTH 5) ;field ; X Y (FIELD 8 5) ;obstacle ; X Y (O 4 1) (O 1 3) (O 8 3) (O 4 3) (O 5 3) (O 4 4) (O 4 5) ;-----dynamic----- ( ;robot ; I X Y R 1 2 4 ;box ; I X Y B 1 2 2 B 2 3 4 B 3 6 2 ;storehouse ; I X Y E S 1 7 1 0 S 2 5 4 0 S 3 5 5 0 ;win W 0 ;Posibilidad de cambiar la R por W asi paramos la ejec ; depth D 0 ;last move ;0:nothing 1:up 2:right 3:down 4:left L 0 ;father id F 0 ) ) (defrule move_right_no_box (MAX_DEPTH ?MD) (FIELD ?Xf ?Yf) ?ff <- (R ?Ir ?Xr ?Yr $?a B ?Ib ?Xb ?Yb $?b S ?Is ?Xs ?Ys ?Es $?c W ?w D ?d L ?l F ?) ;comprueba que a la derecha no hay un obstacle (not (O =(+ ?Xr 1) ?Yr) ) ;comprueba que a la derecha no hay un box (not (R $? B ? =(+ ?Xr 1) ?Yr $?) ) => (assert (R ?Ir (+ ?Xr 1) ?Yr $?a B ?Ib ?Xb ?Yb $?b S ?Is ?Xs ?Ys ?Es $?c W ?w D (+ ?d 1) L 2 F ?ff)) )
例如,我有一个状态,右侧没有箱子或障碍物,但另一个状态有。我需要一种方法来在规则之间建立关系:?ff <- (R ?Ir ?Xr ?Yr $?a B ?Ib ?Xb ?Yb $?b S ?Is ?Xs ?Ys ?Es $?c W ?w D ?d L ?l F ?)
和 (not (R $? B ? =(+ ?Xr 1) ?Yr $?) )
,以确保它们指的是同一个状态(并且不同的状态不会干扰我正在评估的状态)。
换句话说,我需要一种方法来确保两个LHS评估的是同一个状态。谢谢!
附注1:我不能使用类似ID的东西,因为这会使程序的执行速度变得非常慢。
回答:
最后,我没能找到一种方法来确保两个LHS评估的是同一个状态,所以我使用’member’函数解决了这个问题: https://www.csie.ntu.edu.tw/~sylee/courses/clips/bpg/node12.2.3.html
我可以创建一个总是返回True的LHS规则,该规则由多字段变量组成,然后使用member函数检查规则的一部分是否满足我的条件。
另一个选项(尽管我不确定这是否有效,因为我没有测试过)是使用这个在单个LHS中评估所有条件: https://www.csie.ntu.edu.tw/~sylee/courses/clips/bpg/node5.4.1.4.html