2014-12-08 66 views
0

我需要一个函数来搜索仅满足条件的事实的最大值。查找剪辑中最大的事实满足条件

(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

在你的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)) 

为了找到最小值/最大值,您可以使用排序功能命令的事实,而不是定义一个函数来做到这一点,然后拉要么从一开始或值列表的末尾。

CLIPS> (sort my-predicate (find-all-facts ((?f tax)) (eq ?f:oper 2))) 
(<Fact-2> <Fact-6> <Fact-8> <Fact-4>) 
CLIPS> 
+0

非常感谢你。 – aleator 2014-12-10 13:18:36

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"