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

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

Я использовал шаблон "состояние", чтобы убедиться, что правила будут выполняться в моем порядке (разрешение конфликтов), путем изменения слота "статус" после запуска каждого правила. но клипы изменяют "статус" после первого выполнения правила, а не после получения всех принятых данных с помощью правила. Поэтому я использовал шаблон "изменить" и правило "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)))

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> 
Другие вопросы по тегам