I'm trying to make a clips program in order to solve any Sokoban level but I have a huge problem:
In this example, I only have the initial state of the field and a rule which tries to move the player to the right if there is not a box or an obstacle (in the full program I also have rules which move the boxes). The problem comes when I have a state which matches with the 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 ?)
and another one, created due to the movement of the boxes, which does not allow the rule (not (R $? B ? =(+ ?Xr 1) ?Yr $?) )
to be true even if the first estate makes it true.
(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))
)
For example, I have a state which do not have a box or an obstacle in the right, but I have another state which does. I need a way to establish a relation between the rules:
?ff <- (R ?Ir ?Xr ?Yr $?a B ?Ib ?Xb ?Yb $?b S ?Is ?Xs ?Ys ?Es $?c W ?w D ?d L ?l F ?)
and (not (R $? B ? =(+ ?Xr 1) ?Yr $?) )
in order to make sure that they are referring to the same state (and a different state, which is different from the one that I'm evaluating, is not interfering).
I other words, what I need is a way to make sure that both LHS are evaluating the same state. Thanks!
PD1: I can't use something like an ID because it makes the execution of the program too slow.
Okay, at the end I could not found a way to make sure that two LHS are evaluating the same state, so I solved the problem using the 'member' function: https://www.csie.ntu.edu.tw/~sylee/courses/clips/bpg/node12.2.3.html
I can create a LHS rule which always returns True and is composed of multifield variables and then using the member function check if part of the rule satisfies my condition.
Another option (even if I'm not sure this works due to I have not tested it) is to evaluate all the conditions in one LHS using this: https://www.csie.ntu.edu.tw/~sylee/courses/clips/bpg/node5.4.1.4.html