как заставить Клипы придерживаться правила до тех пор, пока не будут полностью обработаны данные без избыточности?

Я хочу, чтобы клипы следовали моему порядку с соблюдением правил.

Я использовал шаблон «состояние», чтобы убедиться, что правила будут выполняться по моему приказу (разрешение конфликтов), путем изменения «статуса» слота после срабатывания каждого правила. но клипы изменяют «статус» после первого выполнения правила, а не после сбора всех принятых данных с помощью правила. Итак, я использовал шаблон «изменить» и правило «callChange», чтобы изменить «статус» для меня. но все та же проблема. Я пробовал «заметность», но он всегда выполняет первое запущенное правило и не переходит к другому активированному правилу с более низкой «заметностью».

любая помощь, пожалуйста, есть мир моего кода:

    (deftemplate laptop(slot name)(slot price)(slot usagefor )(slot description))
    (deftemplate find_laptops  (slot price)(slot usagefor ))
    (deftemplate range(slot min)(slot max))
    (deftemplate state(slot status))
    (deftemplate change(slot newStatus))

    (deffacts laptops
    (laptop(name k53e)(price 200)(usagefor homeandoffice)(description 2.1i3_6gb_500gb_intel_2.2kg))
    (laptop(name x205ta)(price 200)(usagefor homeandoffice)(description 1.3atom_2gb_320ssd_intel_1.5kg))
    (laptop(name n550gk)(price 800)(usagefor gamingandprogramming)(description 2.4i7_8gb_1t_nvidia850_2.2kg))
    (state(status 1))
    (change(newStatus notFinish)))

    (defrule callChange (declare (salience 10))
    ?c<-(change(newStatus ?newStatus))
    ?s<-(state(status ?status))=>
    (modify ?c (newStatus notFinish))
    (modify ?s (status(+ ?status 1))
    ))

    (defrule get_info_laptop (declare (salience 50))
    ?s<-(state(status 1))
    ?c<-(change(newStatus ?newStatus))  =>

    (printout t "enter usagefor" crlf) (bind ?usagefor (read))
    (printout t "enter price " crlf) (bind  ?price (read))
    (assert(find_laptops(price ?price)(usagefor ?usagefor)))
    (modify ?c (newStatus Finish))
    )

    (defrule find_laptop_res (declare (salience 100))
    ?s<-(state(status 2))
    ?c<-(change(newStatus ?newStatus))
    (find_laptops(price ?price)(usagefor ?usagefor )) 
    (laptop(name ?name)(price ?price)(usagefor ?usagefor )(description ?description)) =>  
    (printout t " the name is " ?name " and the description " ?description" the best laptop is " ?name  crlf)
    (modify ?c (newStatus Finish)))

person ghiath    schedule 25.05.2015    source источник


Ответы (1)


Точное поведение, которое вы хотите, не ясно из вашего вопроса, но вот один метод для запроса пользователя, печати всех результатов, а затем определения, следует ли выполнить другой запрос.

CLIPS> (clear)
CLIPS> 
(deftemplate laptop 
   (slot name)
   (slot price)
   (slot usagefor)
   (slot description))
CLIPS> 
(deftemplate find_laptops
   (slot price)
   (slot usagefor))
CLIPS> 
(deffacts laptops
   (laptop (name k53e) (price 200) (usagefor homeandoffice) (description 2.1i3_6gb_500gb_intel_2.2kg))
   (laptop (name x205ta) (price 200) (usagefor homeandoffice) (description 1.3atom_2gb_320ssd_intel_1.5kg))
   (laptop (name n550gk) (price 800) (usagefor gamingandprogramming) (description 2.4i7_8gb_1t_nvidia850_2.2kg)))
CLIPS>    
(defrule get_info_laptop 
   (not (find_laptops))
   =>
   (printout t "Enter usagefor ") 
   (bind ?usagefor (read))
   (printout t "Enter price ") 
   (bind  ?price (read))
   (assert (find_laptops (price ?price) (usagefor ?usagefor))))
CLIPS> 
(defrule find_laptop_res 
   (find_laptops (price ?price) (usagefor ?usagefor )) 
   (laptop (name ?name) (price ?price) (usagefor ?usagefor) (description ?description)) 
   =>  
   (printout t " The name is " ?name " and the description " ?description " the best laptop is " ?name  crlf))
CLIPS> 
(defrule find_laptop_none
   (find_laptops (price ?price) (usagefor ?usagefor )) 
   (not (laptop (price ?price) (usagefor ?usagefor)))
   =>  
   (printout t " No matching laptops"  crlf))
CLIPS>    
(defrule done_laptop_res 
   (declare (salience -10))
   ?f <- (find_laptops) 
   =>  
   (printout t "Search again? ")
   (bind ?answer (read))
   (if (member$ (lowcase ?answer) (create$ y yes))
      then
      (retract ?f)))
CLIPS> (reset)
CLIPS> (run)
Enter usagefor gamingandprogramming
Enter price 800
 The name is n550gk and the description 2.4i7_8gb_1t_nvidia850_2.2kg the best laptop is n550gk
Search again? yes
Enter usagefor homeandoffice
Enter price 200
 The name is x205ta and the description 1.3atom_2gb_320ssd_intel_1.5kg the best laptop is x205ta
 The name is k53e and the description 2.1i3_6gb_500gb_intel_2.2kg the best laptop is k53e
Search again? yes
Enter usagefor homeandoffice
Enter price 300
 No matching laptops
Search again? no
CLIPS> 

В качестве альтернативы можно использовать функции запроса фактов вместо сопоставления шаблонов с правилами:

CLIPS> (clear)
CLIPS> 
(deftemplate laptop 
   (slot name)
   (slot price)
   (slot usagefor)
   (slot description))
CLIPS> 
(deffacts laptops
   (laptop (name k53e) (price 200) (usagefor homeandoffice) (description 2.1i3_6gb_500gb_intel_2.2kg))
   (laptop (name x205ta) (price 200) (usagefor homeandoffice) (description 1.3atom_2gb_320ssd_intel_1.5kg))
   (laptop (name n550gk) (price 800) (usagefor gamingandprogramming) (description 2.4i7_8gb_1t_nvidia850_2.2kg)))
CLIPS>    
(deffunction run-query ()
   (printout t "Enter usagefor ") 
   (bind ?usagefor (read))
   (printout t "Enter price ") 
   (bind  ?price (read))
   (bind ?results 
      (find-all-facts ((?f laptop)) 
         (and (eq ?f:usagefor ?usagefor)
              (eq ?f:price ?price))))
   (if (= (length$ ?results) 0)
      then
      (printout t " No matching laptops"  crlf)
      else
      (progn$ (?r ?results)
         (printout t " The name is " (fact-slot-value ?r name)
                     " and the description " (fact-slot-value ?r description)
                     " the best laptop is " (fact-slot-value ?r name)  crlf)))
   (printout t "Search again? ")
   (bind ?answer (read))
   (if (member$ (lowcase ?answer) (create$ y yes))
      then
      (return TRUE)
      else
      (return FALSE)))
CLIPS>       
(defrule get_info_laptop 
   =>
   (while (run-query) do))
CLIPS> (reset)
CLIPS> (run)
Enter usagefor gamingandprogramming
Enter price 800
 The name is n550gk and the description 2.4i7_8gb_1t_nvidia850_2.2kg the best laptop is n550gk
Search again? yes
Enter usagefor homeandoffice
Enter price 200
 The name is k53e and the description 2.1i3_6gb_500gb_intel_2.2kg the best laptop is k53e
 The name is x205ta and the description 1.3atom_2gb_320ssd_intel_1.5kg the best laptop is x205ta
Search again? y
Enter usagefor homeandoffice
Enter price 300
 No matching laptops
Search again? no
CLIPS> 
person Gary Riley    schedule 25.05.2015