i want clips to follow my order with firing the rules.
i have used "state" template to make sure rules will execute at my order(conflict resolution), by modifying slot "status" after firing each rule. but, clips modifies "status" after the first execute of the rule not after fishing all accepted data with the rule.so, i have used "change" template and rule "callChange" to change the "status" for me. but, still the same problem. i tried "salience" but it do the first fired rule for ever and doesn't go to other fired rule with lower "salience".
any help please there is a peace of my code:
(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)))
The exact behavior you want is not clear from your question, but here's one technique for querying the user, printing all the results, and then determining if another query should be performed.
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>
Alternatively, using the fact query functions in place of pattern matching with rules:
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>