Найдите максимум фактов в клипах УДОВЛЕТВОРЕНИЕ СОСТОЯНИЮ

Мне нужна функция, которая будет искать максимальное значение только из фактов, удовлетворяющих моим условиям.

(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.


person aleator    schedule 08.12.2014    source источник


Ответы (2)


В вашем отклонении find-max, где у вас было TRUE, вам нужно вместо этого поместить туда свое условие. Элемент test 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> 
person Gary Riley    schedule 08.12.2014

Я пытаюсь решить более сложную проблему, связанную с пересечением фактов:

(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"
person aleator    schedule 10.12.2014