I am solving a problem in which I need to build a tower from an unordered heap of blocks, and the size of the blocks should go from the largest to the smallest. I wrote the following code with the templates I need:
(deftemplate block
(slot size (type INTEGER))
(slot place (type SYMBOL))
(slot color (type SYMBOL))
)
(deftemplate on
(slot upper (type SYMBOL))
(slot lower (type SYMBOL))
(slot place (type SYMBOL)(default heap))
)
(deftemplate goal
(slot current-task (type SYMBOL))
)
(deffacts initial-state
(block (size 5) (place heap) (color brown))
(block (size 25) (place heap) (color white))
(block (size 14) (place heap) (color blue))
(block (size 12) (place heap) (color yellow))
)
As well as the rest of the program logic:
(defrule set-initial-task
(initial-fact)
=>
(assert (goal (current-task find)))
)
(defrule find-largest-block
(goal (current-task find))
(block (size ?size) (place heap))
(not (block (size ?larger-size&:(> ?larger-size ?size)) (place heap)))
=>
(modify (block (size ?size) (place hand)))
(modify (goal (current-task build)))
)
(defrule place-first-block
(goal (current-task build))
(block (size ?size) (place hand))
(not (block (place tower)))
=>
(modify (block (size ?size) (place tower)))
(modify (goal (current-task find)))
(printout t "Placed block " ?size " on the base of the tower." crlf)
)
(defrule place-next-block
(goal (current-task build))
(block (size ?size) (place hand) (color ?color1))
(block (size ?lower-size) (place tower) (color ?color2))
(not (on (upper ?lower-size)))
=>
(modify (block (size ?size) (place tower) (color ?color1)))
(assert (on (upper ?lower-size) (lower ?size)))
(modify (goal (current-task find)))
(printout t "Placed block " ?size " on top of " ?lower-size "." crlf)
)
(defrule end-process
(goal (current-task build))
(not (block (place heap)))
=>
(retract (goal (current-task build)))
(printout t "The tower has been built." crlf)
)
But when uploading a file to CLIPS I get errors in each modify
function:
Defining defrule: find-largest-block [ARGACCES5] Function modify expected argument #1 to be of type non-void return value
Tell me what is wrong with my code.
Once you correct these issues, your program runs correctly:
CLIPS (6.4 2/9/21)
CLIPS>
(deftemplate block
(slot size (type INTEGER))
(slot place (type SYMBOL))
(slot color (type SYMBOL))
)
CLIPS>
(deftemplate on
(slot upper (type INTEGER))
(slot lower (type INTEGER))
(slot place (type SYMBOL)(default heap))
)
CLIPS>
(deftemplate goal
(slot current-task (type SYMBOL))
)
CLIPS>
(deffacts initial-state
(block (size 5) (place heap) (color brown))
(block (size 25) (place heap) (color white))
(block (size 14) (place heap) (color blue))
(block (size 12) (place heap) (color yellow))
)
CLIPS>
(defrule set-initial-task
=>
(assert (goal (current-task find)))
)
CLIPS>
(defrule find-largest-block
?g <- (goal (current-task find))
?b <- (block (size ?size) (place heap))
(not (block (size ?larger-size&:(> ?larger-size ?size)) (place heap)))
=>
(modify ?b (place hand))
(modify ?g (current-task build))
)
CLIPS>
(defrule place-first-block
?g <- (goal (current-task build))
?b <- (block (size ?size) (place hand))
(not (block (place tower)))
=>
(modify ?b (place tower))
(modify ?g (current-task find))
(printout t "Placed block " ?size " on the base of the tower." crlf)
)
CLIPS>
(defrule place-next-block
?g <- (goal (current-task build))
?b <- (block (size ?size) (place hand) (color ?color1))
(block (size ?lower-size) (place tower) (color ?color2))
(not (on (upper ?lower-size)))
=>
(modify ?b (place tower))
(assert (on (upper ?lower-size) (lower ?size)))
(modify ?g (current-task find))
(printout t "Placed block " ?size " on top of " ?lower-size "." crlf)
)
CLIPS>
(defrule end-process
?g <- (goal (current-task find))
(not (block (place heap)))
=>
(retract ?g)
(printout t "The tower has been built." crlf)
)
CLIPS> (reset)
CLIPS> (run)
Placed block 25 on the base of the tower.
Placed block 14 on top of 25.
Placed block 12 on top of 14.
Placed block 5 on top of 12.
The tower has been built.
CLIPS>