2014-12-08 2 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

В вашем поиске-max deffunction, где у вас есть ИСТИНА, вам нужно вместо этого разместить свое условие. Элемент test test (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

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"