去屑永远不会进入议程|片段

时间:2019-01-17 17:42:36

标签: clips

我想建立一个专家系统,其中在有一些楼层的建筑物发生紧急情况时(它需要工作于任意楼层),电梯应将人员带入地下。 事实是,在任何楼层发送电梯的罚单永远不会进入议程,因此系统什么也不做。正确的操作应该是开除规则,然后再开门覆耳地将人们带到地板上。

去皮的代码是这样的:

(defrule move_to_floor        "elevator moves to any floor "
      ?i <- (elevator is_at floor ?x has ?y adults and ?z minors)
      (floor ?fl&~?x has ?n adult and ?m minor people)
      (test (> (+ ?n ?m) 0))
      => 
      (retract ?i)
      (assert (elevator is_at floor ?fl has ?y adults and ?z minors))
)

这些事实是用户在上面的另一个问题中初始化的,它们是:

f-0     (initial-fact)
f-1     (elevator is_at 0 has 0 adults and 0 minors)
f-3     (capacity 4)
f-4     (floors 3)
f-5     (initCanEnter 0) ;At 0 this prevents from entering the init_defrule again
f-6     (floor 3 has 2 adult and 1 minor people)
f-7     (floor 2 has 4 adult and 5 minor people)
f-8     (floor 1 has 1 adult and 2 minor people)

我似乎找不到解决方法。另外,我使用的是假象而不是模糊的模板,因为我看到很多人在互联网上使用

1 个答案:

答案 0 :(得分:1)

您可以使用matchs命令查看规则中的哪些模式匹配。

         CLIPS (6.31 2/3/18)
CLIPS> 
(defrule move_to_floor "elevator moves to any floor "
   ?i <- (elevator is_at floor ?x has ?y adults and ?z minors)
   (floor ?fl&~?x has ?n adult and ?m minor people)
   (test (> (+ ?n ?m) 0))
   => 
   (retract ?i)
   (assert (elevator is_at floor ?fl has ?y adults and ?z minors)))
CLIPS> 
(deffacts initial
   (elevator is_at 0 has 0 adults and 0 minors)
   (capacity 4)
   (floors 3)
   (initCanEnter 0) ;At 0 this prevents from entering the init_defrule again
   (floor 3 has 2 adult and 1 minor people)
   (floor 2 has 4 adult and 5 minor people)
   (floor 1 has 1 adult and 2 minor people))
CLIPS> (reset)
CLIPS> (matches move_to_floor)
Matches for Pattern 1
 None
Matches for Pattern 2
f-5
f-6
f-7
Partial matches for CEs 1 - 2
 None
Activations
 None
(3 0 0)
CLIPS> 

在这种情况下,第一个模式不匹配。这是因为您的模式期望 is_at floor?x ,但事实包含 is_at 0 (事实中缺少符号 floor )。如果您纠正此问题,该规则将被列入议程。

CLIPS>    
(deffacts initial
   (elevator is_at floor 0 has 0 adults and 0 minors)
   (capacity 4)
   (floors 3)
   (initCanEnter 0) ;At 0 this prevents from entering the init_defrule again
   (floor 3 has 2 adult and 1 minor people)
   (floor 2 has 4 adult and 5 minor people)
   (floor 1 has 1 adult and 2 minor people))
CLIPS> (reset)
CLIPS> (agenda)
0      move_to_floor: f-1,f-7
0      move_to_floor: f-1,f-6
0      move_to_floor: f-1,f-5
For a total of 3 activations.
CLIPS>

如果您在此时发出(运行)命令,则规则将无休止地在从一个楼层到另一个楼层的循环中触发,这是您接下来需要解决的问题。

如果使用deftemplate事实而不是有序事实,则拼写插槽名称会出错,因此,如果您具有多个属性的事实,则最好使用这些。

CLIPS> (clear)
CLIPS>   
(deftemplate elevator 
  (slot at_floor (type INTEGER))
  (slot adults (type INTEGER))
  (slot minors (type INTEGER)))
CLIPS>   
(deftemplate floor
   (slot # (type INTEGER))
   (slot adults (type INTEGER))
   (slot minors (type INTEGER)))
CLIPS>    
(deffacts initial
   (elevator (at_floor 0))
   (capacity 4)
   (floors 3)
   (initCanEnter 0) 
   (floor (# 3) (adults 2) (minors 1))
   (floor (# 2) (adults 4) (minors 5))
   (floor (# 1) (adults 1) (minors 2)))
CLIPS>    
 (defrule move_to_floor 
   ?i <- (elevator (at_floor ?x))
   (floor (# ?fl&~?x) (adults ?n) (minors ?m))
   (test (> (+ ?n ?m) 0))
   => 
   (modify ?i (at_floor ?fl)))
CLIPS> (reset)
CLIPS> (facts)
f-0     (initial-fact)
f-1     (elevator (at_floor 0) (adults 0) (minors 0))
f-2     (capacity 4)
f-3     (floors 3)
f-4     (initCanEnter 0)
f-5     (floor (# 3) (adults 2) (minors 1))
f-6     (floor (# 2) (adults 4) (minors 5))
f-7     (floor (# 1) (adults 1) (minors 2))
For a total of 8 facts.
CLIPS> (agenda)
0      move_to_floor: f-1,f-7
0      move_to_floor: f-1,f-6
0      move_to_floor: f-1,f-5
For a total of 3 activations.
CLIPS>