CLIPS 区块世界
CLIPS blocks world
我正在尝试创建一个 CLIPS 程序,它将采用任何初始堆栈并将其重新排列到任何目标堆栈中。我断言这个,但它似乎没有做任何事情。
(assert (stack A B C) (stack D E F) (goal-stack D C B) (goal-stack A) (goal-stack F E))
到目前为止,这是我的代码:
(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))
调试代码通常涉及质疑您的期望。您希望 move-direct 和 move-on-floor 规则有所作为,但为什么呢?对于直接移动规则和您所做的断言,前两个模式中 ?block1 和 ?block2 的唯一可能值是 A 或 D。因此第三个模式必须匹配以 A A 开头的目标堆栈, A D, D A, or D D。这样的目标栈不存在,所以这条规则不匹配。
对于楼层移动规则,请查看每个案例。如果 (goal-stack A) 匹配目标堆栈模式,其中 ?move-this-block 是 A 并且 $?blocks 是 (),那么必须有一个堆栈在 A 顶部有一个块(变量 ?top)。由于 A 位于堆栈顶部,因此此目标堆栈不匹配规则。
如果 (goal-stack F E) 与 goal-stack 模式匹配,则序列 ($?blocks ?move-this-block) 是 (F E) 或 F。这些序列中的任何一个都不存在堆栈,其中顶部只有一个块,因此不会匹配此序列的规则。
如果(目标堆栈 D C B)匹配目标堆栈模式,则必须匹配堆栈的目标堆栈中的序列是(D C B)、(D C)或(D)。同样,没有包含此序列的堆栈,序列顶部只有一个块。
在直接移动规则的逻辑中,您只想在现有堆栈与目标堆栈的底部匹配时直接移动方块。对于在地板上移动的规则,您还需要确保您没有将块从部分完成的堆栈中移出。
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>
我正在尝试创建一个 CLIPS 程序,它将采用任何初始堆栈并将其重新排列到任何目标堆栈中。我断言这个,但它似乎没有做任何事情。
(assert (stack A B C) (stack D E F) (goal-stack D C B) (goal-stack A) (goal-stack F E))
到目前为止,这是我的代码:
(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))
调试代码通常涉及质疑您的期望。您希望 move-direct 和 move-on-floor 规则有所作为,但为什么呢?对于直接移动规则和您所做的断言,前两个模式中 ?block1 和 ?block2 的唯一可能值是 A 或 D。因此第三个模式必须匹配以 A A 开头的目标堆栈, A D, D A, or D D。这样的目标栈不存在,所以这条规则不匹配。
对于楼层移动规则,请查看每个案例。如果 (goal-stack A) 匹配目标堆栈模式,其中 ?move-this-block 是 A 并且 $?blocks 是 (),那么必须有一个堆栈在 A 顶部有一个块(变量 ?top)。由于 A 位于堆栈顶部,因此此目标堆栈不匹配规则。
如果 (goal-stack F E) 与 goal-stack 模式匹配,则序列 ($?blocks ?move-this-block) 是 (F E) 或 F。这些序列中的任何一个都不存在堆栈,其中顶部只有一个块,因此不会匹配此序列的规则。
如果(目标堆栈 D C B)匹配目标堆栈模式,则必须匹配堆栈的目标堆栈中的序列是(D C B)、(D C)或(D)。同样,没有包含此序列的堆栈,序列顶部只有一个块。
在直接移动规则的逻辑中,您只想在现有堆栈与目标堆栈的底部匹配时直接移动方块。对于在地板上移动的规则,您还需要确保您没有将块从部分完成的堆栈中移出。
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>