CLIPS blocks world

2019-08-29 19:50发布

I am trying to create a CLIPS program that will take any initial stack and rearrange it into any goal-stack. I am asserting this, but it doesn't seem to do anything.

(assert (stack A B C) (stack D E F) (goal-stack D C B) (goal-stack A) (goal-stack F E))

This is my code so far:

(defrule move-direct
;(declare (salience 10000))
?stack1 <- (stack ?block1 $?bottom1)
?stack2 <- (stack ?block2 $?bottom2)
(goal-stack ?block1 ?block2 $?goalbottom)
=>
(retract ?stack1 ?stack2)
(assert (stack ?block1 ?block2 ?bottom2))
 (assert (stack $?bottom1))
 (printout t ?block1 " moved on top of " ?block2 crlf))

(defrule move-on-floor
; (declare (salience 10000))
 ?stack1 <- (stack ?top $?blocks ?movethisblock $?bottom1)
;(goal-stack ?movethisblock $?bottom1)
 (goal-stack $?blocks ?movethisblock $?bottom2)
 =>
 (retract ?stack1)
 (assert (stack ?top))
 (assert (stack $?blocks ?movethisblock $?bottom1))
 (printout t ?top " moved on to the floor" crlf))

标签: clips
1条回答
贼婆χ
2楼-- · 2019-08-29 20:24

Debugging code usually involves questioning your expectations. You expect the move-direct and move-on-floor rules to do something, but why? For the move-direct rule and the assertions you've made, the only possible values for ?block1 and ?block2 in the first two patterns are either A or D. So the third pattern must match a goal-stack that starts with either A A, A D, D A, or D D. Such a goal-stack does not exist, so this rule is unmatched.

For the move-on-floor rule, look at each case. If (goal-stack A) matches the goal-stack pattern where ?move-this-block is A and $?blocks is (), then there must be stack that has a block on top of A (the variable ?top). Since A is at the top of the stack, the rule won't be matched for this goal-stack.

if (goal-stack F E) matches the goal-stack pattern, the sequence ($?blocks ?move-this-block) is either (F E) or F. There is no stack with either of these sequences where there's just a single block on top, so the rule won't be matched for this sequence.

If (goal-stack D C B) matches the goal-stack pattern the sequence from the goal-stack that must match the stack is either (D C B), (D C) or (D). Again there's no stack that contains this sequence with just a single block on top of the sequence.

In the logic for the move-direct rule, you only want to directly move the block when the existing stack matches the bottom portion of a goal-stack. For the move-on-floor rule you also want to insure that you're not moving blocks off a partially completed stack.

              CLIPS (6.31 2/3/18)
    CLIPS> 
(defrule move-direct
   (declare (salience 10))
   ?stack1 <- (stack ?block1 $?bottom)
   ?stack2 <- (stack ?block2 $?goalbottom)
   (goal-stack $? ?block1 ?block2 $?goalbottom)
   =>
   (retract ?stack1 ?stack2)
   (assert (stack ?block1 ?block2 ?goalbottom))
   (assert (stack $?bottom))
   (printout t ?block1 " moved on top of " ?block2 crlf))
CLIPS> 
(defrule move-on-floor
   (goal-stack $? ?next $?goalbottom)
   (not (stack $? ?next $?goalbottom))
   ?stack <- (stack $?top ?bottom)
   (test (member$ ?next ?top))
   =>
   (retract ?stack)
   (assert (stack (nth$ 1 ?top)))
   (assert (stack (rest$ ?top) ?bottom))
   (printout t (nth$ 1 ?top) " moved on to the floor" crlf))
CLIPS> 
(assert (stack A B C)
        (stack D E F)
        (goal-stack D C B)
        (goal-stack A)
        (goal-stack F E))
<Fact-5>
CLIPS> (run)
D moved on to the floor
E moved on to the floor
F moved on top of E
A moved on to the floor
B moved on to the floor
C moved on top of B
D moved on top of C
CLIPS> (facts)
f-0     (initial-fact)
f-3     (goal-stack D C B)
f-4     (goal-stack A)
f-5     (goal-stack F E)
f-10    (stack F E)
f-11    (stack)
f-12    (stack A)
f-17    (stack D C B)
For a total of 8 facts.
CLIPS> (reset)
CLIPS> 
(assert (stack A B C)
        (goal-stack A B)
        (goal-stack C))
<Fact-3>
CLIPS> (run)
A moved on to the floor
B moved on to the floor
A moved on top of B
CLIPS> (facts)
f-0     (initial-fact)
f-2     (goal-stack A B)
f-3     (goal-stack C)
f-7     (stack C)
f-8     (stack A B)
f-9     (stack)
For a total of 6 facts.
CLIPS>
查看更多
登录 后发表回答