我需要一个能够只搜索满足条件的事实的最大值的函数。
(deftemplate tax
(field det (type SYMBOL))
(field oper (type INTEGER))
(field machine (type INTEGER))
(field time (type INTEGER))
)
(deffacts tax
(tax (det A) (oper 1) (machine 1) (time 10))
(tax (det A) (oper 2) (machine 2) (time 5))
(tax (det B) (oper 1) (machine 1) (time 8))
(tax (det B) (oper 2) (machine 5) (time 4))
(tax (det C) (oper 1) (machine 4) (time 10))
(tax (det C) (oper 2) (machine 2) (time 5))
(tax (det D) (oper 1) (machine 3) (time 6))
(tax (det D) (oper 2) (machine 2) (time 5))
(tax (det E) (oper 1) (machine 1) (time 7))
)
(deffunction my-predicate (?fact1 ?fact2)
(< (fact-slot-value ?fact1 time) (fact-slot-value ?fact2 time)))
(deffunction find-max (?template ?predicate)
(bind ?max FALSE)
(do-for-all-facts ((?f ?template)) TRUE
(test (eq oper 2)) ; It's my conditions. This may be something else.
(if (or (not ?max) (funcall ?predicate ?f ?max))
then
(bind ?max ?f)))
(return ?max))
(defrule find-max
=>
(bind ?tax (find-max tax my-predicate))
(if ?tax
then
(printout t "Fact " (fact-slot-value ?tax machine ) " is the maximum" crlf)))
但是我在函数find-max和rule find-max。
中遇到错误答案 0 :(得分:0)
在你的find-max deffunction中你有TRUE,你需要把你的条件放在那里。测试CE元素(test(eq?oper 2)),你放在函数中只能在规则的条件下工作。
(deffunction find-max (?template ?predicate)
(bind ?max FALSE)
(do-for-all-facts ((?f ?template)) (eq (fact-slot-value ?f oper) 2)
(if (or (not ?max) (funcall ?predicate ?f ?max))
then
(bind ?max ?f)))
(return ?max))
要查找最小值/最大值,可以使用sort函数对事实进行排序,而不是定义执行此操作的函数,然后从列表的开头或结尾处提取值。
CLIPS> (sort my-predicate (find-all-facts ((?f tax)) (eq ?f:oper 2)))
(<Fact-2> <Fact-6> <Fact-8> <Fact-4>)
CLIPS>
答案 1 :(得分:0)
我正试图解决一个与事实有关的更复杂的问题:
(deftemplate store
(field det (type SYMBOL))
(field oper (type INTEGER))
(field count (type INTEGER))
)
(deftemplate tax
(field det (type SYMBOL))
(field oper (type INTEGER))
(field machine (type INTEGER))
(field time (type INTEGER))
)
(deffacts store
(store (det A) (oper 1) (count 100))
(store (det B) (oper 1) (count 0))
(store (det A) (oper 1) (count 3))
(store (det B) (oper 1) (count 0))
(store (det A) (oper 2) (count 2))
(store (det B) (oper 2) (count 0))
(store (det A) (oper 2) (count 0))
(store (det B) (oper 2) (count 5))
(store (det A) (oper 2) (count 1))
(store (det B) (oper 1) (count 0))
)
(deffacts tax
(tax (det A) (oper 1) (machine 1) (time 10))
(tax (det A) (oper 2) (machine 2) (time 5))
(tax (det B) (oper 1) (machine 1) (time 8))
(tax (det B) (oper 2) (machine 5) (time 4))
(tax (det C) (oper 1) (machine 4) (time 10))
(tax (det C) (oper 2) (machine 2) (time 5))
(tax (det D) (oper 1) (machine 3) (time 6))
(tax (det D) (oper 2) (machine 2) (time 5))
(tax (det E) (oper 1) (machine 1) (time 7))
)
(deffunction my-predicate (?fact1 ?fact2)
(< (fact-slot-value ?fact1 time) (fact-slot-value ?fact2 time)))
(deffunction find-max (?template ?predicate)
(bind ?max FALSE)
(do-for-all-facts ((?f ?template)) (eq (fact-slot-value ?f oper) 2) ; and store:count = 0
;(do-for-all-facts ((?f ?template)) (eq (fact-slot-value ?f oper) 2) ; and ((?f2 ?template2)) (eq (fact-slot-value ?f2 count) 0) - it's not is not correct
(if (or (not ?max) (funcall ?predicate ?f ?max))
then
(bind ?max ?f)))
(return ?max))
(defrule find-max
=>
(bind ?tax (find-max tax my-predicate))
(if ?tax
then
(printout t "Fact " (fact-slot-value ?tax oper ) " is the maximum"