defrule никогда не делает это в повестке дня | КЛИПЫ - PullRequest
0 голосов
/ 17 января 2019

Я хочу построить экспертную систему, в которой в случае чрезвычайной ситуации в здании с несколькими этажами (оно должно работать для любого количества этажей) лифт должен поднимать людей в землю.Дело в том, что отправка лифта на любом этаже никогда не включается в повестку дня, поэтому система просто ничего не делает.Правильное действие должно состоять в том, чтобы запустить правило, а затем другое правило, которое забирает людей с пола.

Код для дефрулы таков:

(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 голосов
/ 17 января 2019

Вы можете использовать команду match, чтобы увидеть, какие шаблоны в правиле сопоставляются.

         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>

Если вы выполните команду (run) в этот момент, правила будут бесконечно срабатывать в цикле, перемещающемся от пола к полу, так что вам нужно обратиться к следующему.

Если вы будете использовать факты с вычеркиванием, а не упорядоченные факты, вы получите сообщение об ошибке, если вы неправильно напишите названия слотов, поэтому лучше использовать их, если у вас есть факт с несколькими атрибутами.

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>
...