【问题标题】:CLIPS blocks worldCLIPS块世界
【发布时间】:2018-10-13 00:58:51
【问题描述】:

我正在尝试创建一个 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))

【问题讨论】:

    标签: clips


    【解决方案1】:

    调试代码通常涉及质疑您的期望。您希望直接移动和按楼层移动规则会有所作为,但为什么呢?对于直接移动规则和您所做的断言,前两个模式中 ?block1 和 ?block2 的唯一可能值是 A 或 D。所以第三个模式必须匹配以 A A 开头的目标堆栈, A D, D A, 或者 D D。这样的目标栈不存在,所以这个规则是不匹配的。

    对于按楼层移动规则,请查看每个案例。如果 (goal-stack A) 与 ?move-this-block 为 A 且 $?blocks 为 () 的目标堆栈模式匹配,则必须存在在 A 顶部具有块的堆栈(变量 ?top)。由于 A 位于堆栈的顶部,因此此目标堆栈的规则不会匹配。

    如果 (goal-stack F E) 与目标堆栈模式匹配,则序列 ($?blocks ?move-this-block) 是 (F E) 或 F。这些序列中的任何一个都没有堆栈顶部的单个块,因此此序列不会匹配该规则。

    如果 (goal-stack 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>
    

    【讨论】:

    • 效果很好。但是对于 (assert (stack A B C) (goal-stack A B) (goal-stack C)) 它只是将 A 放到地板上然后停止。
    猜你喜欢
    • 1970-01-01
    • 2018-06-18
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 2021-10-07
    相关资源
    最近更新 更多