mardi 23 octobre 2018

Clips pattern matching

I have a school project in CLIPS and I ecountered few problems with pattern matching. It is a Sokoban game in Rule Based System. Robot must push the box into warehouse, it can move up, down, right and left - those are the rules move-right etc. Then, if it ecounters a box next to itself, it is supposed to push it. If the box is next to warehouse, it should be pushed into it.

My code:

(defglobal ?*nod-gen* = 0)
(defglobal ?*sizex* = 0)
(defglobal ?*sizey* = 0)


(defrule board-fit
    ?f <- (board ?sizex1 ?sizey1)
   =>
   (bind ?*sizex* ?sizex1)
   (bind ?*sizey* ?sizey1))

(defmethod float ((?s STRING))
   (float (string-to-field ?s)))

(defrule move-right
    ?f1<-(robot ?x ?y boxes $?b1 ?bx ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level ?lvl)
    ?f2<-(wall ?wl1 ?yl1)
    (max-depth ?prof)
    (test (< ?lvl ?prof))
    (test (not (> ?x ?*sizex*)))
    (test (and (neq (+ ?x 1) ?wl1) (neq ?y ?yl1)))
    (test (and (neq (+ ?x 1) ?bx) (neq ?y ?by)))
    (test (and (neq (+ ?x 1) ?wx) (neq ?y ?wy)))
    =>
    (retract ?f1)
    (assert (robot (+ ?x 1) ?y boxes $?b1 ?bx ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level (+ ?lvl 1)))
    (bind ?*nod-gen* (+ ?*nod-gen* 1)))


(defrule move-left
    ?f1<-(robot ?x ?y boxes $?b1 ?bx ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level ?lvl)
    ?f2<-(wall ?wl1 ?yl1)
    (max-depth ?prof)
    (test (< ?lvl ?prof))
    (test (neq ?x 0))
    (test (and (neq (- ?x 1) ?wl1) (neq ?y ?yl1)))
    (test (and (neq (- ?x 1) ?bx) (neq ?y ?by)))
    (test (and (neq (- ?x 1) ?wx) (neq ?y ?wy)))
    =>
    (retract ?f1)
    (assert (robot (- ?x 1) ?y boxes $?b1 ?bx ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level (+ ?lvl 1)))
    (bind ?*nod-gen* (+ ?*nod-gen* 1)))


(defrule move-up
    ?f1<-(robot ?x ?y boxes $?b1 ?bx ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level ?lvl)
    ?f2<-(wall ?wl1 ?yl1)
    (max-depth ?prof)
    (test (< ?lvl ?prof))
    (test (> ?y ?*sizey*))
    (test (and (neq ?x ?wl1) (neq (+ ?y 1) ?yl1)))
    (test (and (neq ?x ?bx) (neq (+ ?y 1) ?by)))
    (test (and (neq ?x ?wx) (neq (+ ?y 1) ?wy)))
    =>
    (assert (robot ?x (+ ?y 1) boxes $?b1 ?bx ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level (+ ?lvl 1)))
    (bind ?*nod-gen* (+ ?*nod-gen* 1)))


(defrule move-down
    ?f1<-(robot ?x ?y boxes $?b1 ?bx ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level ?lvl)
    ?f2<-(wall ?wl1 ?yl1)
    (max-depth ?prof)
    (test (< ?lvl ?prof))
    (test (not (= ?y 0)))
    (test (and (neq ?x ?wl1) (neq (- ?y 1) ?yl1)))
    (test (and (neq ?x ?bx) (neq (- ?y 1) ?by)))
    (test (and (neq ?x ?wx) (neq (- ?y 1) ?wy)))

    =>
    (assert (robot ?x (- ?y 1) boxes $?b1 ?bx ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level (+ ?lvl 1)))
    (bind ?*nod-gen* (+ ?*nod-gen* 1)))


(defrule push-right
    ?f1<-(robot ?x ?y boxes $?b1 ?bx ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level ?lvl)
    ?f2<-(wall ?wl1 ?yl1)
    (max-depth ?prof)
    (test (< ?lvl ?prof))
    (test (< ?bx (- ?*sizex* 1)))
    (test (and (neq (+ ?x 2) ?wl1) (neq ?y ?yl1)))
    (test (not (and (neq (+ ?x 1) ?bx) (neq ?y ?by))))
    (test (and (neq (+ ?x 2) ?wx) (neq ?y ?wy)))
    (test (neq ?x 0))
    =>
    (retract ?f1)
    (assert (robot (+ ?x 1) ?y boxes $?b1 (+ ?bx 1) ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level (+ ?lvl 1)))
    (bind ?*nod-gen* (+ ?*nod-gen* 1)))

(defrule push-left
    ?f1<-(robot ?x ?y boxes $?b1 ?bx ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level ?lvl)
    ?f2<-(wall ?wl1 ?yl1)
    (max-depth ?prof)
    (test (< ?lvl ?prof))
    (test (eq (- ?x 1) ?bx))
    (test (> 0 ?bx))
    (test (eq ?x 0))
    (test (not (and (neq (- ?x 2) ?wl1) (neq ?y ?yl1))))
    (test (and (eq (- ?x 1) ?bx) (eq ?y ?by)))
    (test (not (and (eq (- ?x 2) ?wx) (eq ?y ?wy))))
    =>
    (retract ?f1)
    (assert (robot ?x (+ ?y 1) boxes $?b1 ?bx (+ ?by 1) $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level (+ ?lvl 1)))
    (bind ?*nod-gen* (+ ?*nod-gen* 1)))

(defrule push-up
    ?f1<-(robot ?x ?y boxes $?b1 ?bx ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level ?lvl)
    ?f2<-(wall ?wl1 ?yl1)
    (max-depth ?prof)
    (test (< ?lvl ?prof))
    (test (eq (+ ?y 1) ?by))
    (test (< 0 ?by))
    (test (neq ?y 0))
    (test (not (and (eq ?x ?wl1) (eq (+ ?y 2) ?yl1))))
    (test (and (eq (- ?x 1) ?bx) (eq (+ ?y 1) ?by)))
    (test (not (and (eq ?x ?wx) (eq (+ ?y 2) ?wy))))
    =>
    (retract ?f1)
    (assert (robot ?x (+ ?y 1) boxes $?b1 ?bx (+ ?by 1) $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level (+ ?lvl 1)))
    (bind ?*nod-gen* (+ ?*nod-gen* 1)))

(defrule push-down
    ?f1<-(robot ?x ?y boxes $?b1 ?bx ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level ?lvl)
    ?f2<-(wall ?wl1 ?yl1)
    (max-depth ?prof)
    (test (< ?lvl ?prof))
    (test (eq (- ?y 1) ?by))
    (test (< ?by (- ?*sizey* 1)))
    (test (neq ?y 0))
    (test (not (and (eq ?x ?wl1) (eq (- ?y 2) ?yl1))))
    (test (and (eq (- ?x 1) ?bx) (eq (- ?y 1) ?by)))
    (test (not (and (eq ?x ?wx) (eq (- ?y 2) ?wy))))
    =>
    (retract ?f1)
    (assert (robot ?x (- ?y 1) boxes $?b1 ?bx (- ?by 1) $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level (+ ?lvl 1)))
    (bind ?*nod-gen* (+ ?*nod-gen* 1)))


(defrule push-right-to-wh
    ?f1<-(robot ?x ?y boxes $?b1 ?bx ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level ?lvl)
    ?f2<-(wall ?wl1 ?yl1)
    (max-depth ?prof)
    (test (< ?lvl ?prof))
    (test (< ?bx (- ?*sizex* 1)))
    (test (and (eq (+ ?bx 1) ?wx) (eq ?wy ?by)))
    (test (and (eq (+ ?x 1) ?bx) (eq ?y ?by)))
    =>
    (retract ?f1)
    (assert (robot (+ ?x 1) ?y boxes $?b1 (+ ?bx 1) ?by $?b2 warehouses $?w1 ?wx ?wy 1 $?w2 level (+ ?lvl 1)))
    (bind ?*nod-gen* (+ ?*nod-gen* 1)))

(defrule push-left-to-wh
    ?f1<-(robot ?x ?y boxes $?b1 ?bx ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level ?lvl)
    ?f2<-(wall ?wl1 ?yl1)
    (max-depth ?prof)
    (test (< ?lvl ?prof))
    (test (> ?bx 0))
    (test (and (eq (- ?x 1) ?bx) (eq ?y ?by)))
    (test (and (eq (- ?bx 1) ?wx) (eq ?wy ?by)))
    =>
    (assert (robot (- ?x 1) ?y boxes $?b1 (- ?bx 1) ?by $?b2 warehouses $?w1 ?wx ?wy 1 $?w2 level (+ ?lvl 1)))
    (bind ?*nod-gen* (+ ?*nod-gen* 1)))


(defrule push-down-to-wh
    ?f1<-(robot ?x ?y boxes $?b1 ?bx ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level ?lvl)
    ?f2<-(wall ?wl1 ?yl1)
    (max-depth ?prof)
    (test (and (< ?lvl ?prof) (< ?by (- ?*sizey* 1))))
    (test (and (eq ?x ?bx) (eq (- ?y 1) ?by)))
    (test (and (eq ?bx ?wx) (eq (- ?wy 1) ?by)))
    =>
    (retract ?f1)
    (assert (robot ?x (- ?y 1) boxes $?b1 ?bx (- ?by 1) $?b2 warehouses $?w1 ?wx ?wy 1 $?w2 level (+ ?lvl 1)))
    (bind ?*nod-gen* (+ ?*nod-gen* 1)))

(defrule push-up-to-wh
    ?f1<-(robot ?x ?y boxes $?b1 ?bx ?by $?b2 warehouses $?w1 ?wx ?wy 0 $?w2 level ?lvl)
    ?f2<-(wall ?wl1 ?yl1)
    (max-depth ?prof)
    (test (and (< ?lvl ?prof) (> (float ?by) -1.0)))
    (test (and (eq ?x ?bx) (eq (+ ?y 1) ?by)))
    (test (and (eq ?bx ?wx) (eq (+ ?wy 1) ?by)))
    =>
    (retract ?f1)
    (assert (robot ?x (+ ?y 1) boxes $?b1 ?bx (+ ?by 1) $?b2 warehouses $?w1 ?wx ?wy 1 $?w2 level (+ ?lvl 1)))
    (bind ?*nod-gen* (+ ?*nod-gen* 1)))


(defrule goal
    ?f<-(robot $? warehouses $?w1 ?wx ?wy 1 $?w2 level ?lvl)

   =>
    (printout t "SOLUTION FOUND AT LEVEL " ?lvl crlf)
    (printout t "NUMBER OF EXPANDED NODES OR TRIGGERED RULES " ?*nod-gen* crlf)
    (printout t "GOAL FACT " ?f crlf)

    (halt))

(defrule no_solution
    (robot $? level ?lvl)
    =>
    (printout t "SOLUTION NOT FOUND" crlf)
    (printout t "NUMBER OF EXPANDED NODES OR TRIGGERED RULES " ?*nod-gen* crlf)

    (halt))     

(deffunction start ()
        (reset)
    (printout t "Maximum depth:= " )
    (bind ?prof (read))
    (printout t "Search strategy " crlf "    1.- Breadth" crlf "    2.- Depth" crlf )
    (bind ?a (read))
    (if (= ?a 1)
           then    (set-strategy breadth)
           else   (set-strategy depth))
        (printout t " Execute run to start the program " crlf)


    (assert (max-depth ?prof))

)

and I got an error all the time (for every rule that has comparison of variables):

[ARGACCES2] soktest.clp, Line 186: Function '>' expected argument #1 to be of type integer or float.

How can I correct it, so it might work? I tried converting variables into float with an overwritten function, but it is stil not working properly. Robot is going only up and down.

Aucun commentaire:

Enregistrer un commentaire