调用函数会破坏规则

时间:2014-12-19 21:36:17

标签: clips

我试图将专家系统的设计改为我的规则所执行的工作。

主题 - 在不同机器上处理不同部件。当然,每种物品在不同的机器上不同时间处理。

该系统由三个规则组成。第一条规则 - 装载机器工作。第二条规则 - 卸载机器。第三条规则 - 执行时间的移动。

我添加了函数调用的第一个规则,它寻找具有最大处理时间的项目。但是,专家系统停止了工作。只需显示" 1"。这就是全部。

(defglobal ?*time* = 0)

(deftemplate details
(field det (type SYMBOL))
(field oper (type INTEGER))
(field count (type INTEGER))
)

(deftemplate route 
(field det (type SYMBOL))
(field oper (type INTEGER))
(field machine (type INTEGER))
(field time (type INTEGER))
)

(deftemplate machine
(field num (type INTEGER))
(field count (type INTEGER)(default 0))
(field det (type SYMBOL)(default A))
(field oper (type INTEGER)(default 0))
(field time (type INTEGER)(default 0))
)

(deffacts details
(details (det A) (oper 0) (count 100))
(details (det B) (oper 0) (count 150))
(details (det C) (oper 0) (count 200))
(details (det D) (oper 0) (count 300))
(details (det E) (oper 0) (count 200))

(details (det A) (oper 1) (count 0))
(details (det B) (oper 1) (count 0))
(details (det C) (oper 1) (count 0))
(details (det D) (oper 1) (count 0))
(details (det E) (oper 1) (count 0))
....
)

(deffacts route

(route (det A) (oper 1) (machine 1) (time 10))
(route (det A) (oper 2) (machine 2) (time 5))
(route (det A) (oper 2) (machine 2) (time 2))
(route (det A) (oper 3) (machine 3) (time 4))
(route (det A) (oper 3) (machine 4) (time 3))
(route (det A) (oper 4) (machine 4) (time 8))
(route (det A) (oper 4) (machine 1) (time 8))

(route (det B) (oper 1) (machine 1) (time 8))
(route (det B) (oper 2) (machine 5) (time 4))
(route (det B) (oper 2) (machine 2) (time 6))
(route (det B) (oper 3) (machine 6) (time 3))
(route (det B) (oper 3) (machine 5) (time 2))
(route (det B) (oper 4) (machine 7) (time 2))
(route (det B) (oper 4) (machine 2) (time 3))
...
)

(deffacts machines
(machine (num 1))
(machine (num 2))
(machine (num 3))
(machine (num 4))
(machine (num 5))
(machine (num 6))
(machine (num 7))
(machine (num 8))
)


 (deffunction my-predicate (?fact1 ?fact2)
       (< (fact-slot-value ?fact1 time) (fact-slot-value ?fact2 time)))


(deffunction find-max2 (?template1 ?predicate1 ?operation ?template2 ?max)
   (bind ?max FALSE)  
      (do-for-all-facts ((?f2 ?template2)) (eq (fact-slot-value ?f2 count) 0)   

   (do-for-all-facts ((?f1 ?template1)) (eq (fact-slot-value ?f1 oper) ?operation) (eq (fact-slot-value ?f1 oper)(fact-slot-value ?f2 oper))
      (if (or (not ?max) (funcall ?predicate1 ?f1 ?max))
         then
         (bind ?max ?f1)))
         )
    )

;-------------------------------------------------------------------------------------------------- 

(defrule work_on_1
(declare (salience 10000))

(machine (num ?num1)(count ?count1) (time ?time1))
(test (eq ?count1 0))
(test (eq ?time1 0))
?node1 <- (machine (num ?num1)(count ?count1) (time ?time1))


(details (det ?detail) (oper ?operation1) (count ?count2))
(test (not (eq ?count2 0)))
?node2 <- (details (det ?detail) (oper ?operation1) (count ?count2))

; add this code
(funcall find-max2 route my-predicate ?operation1 details ?max)
(test (eq ?operation1(fact-slot-value ?max oper )))

(route (machine ?num1) (det ?detail) (oper ?operation2) (time ?time2))
(test (eq ?operation2 (+ ?operation1 1)))

=>

(if (> ?count2 30) 
then
(modify ?node1 (count 30) (time ?time2) (oper ?operation2) (det ?detail))
(modify ?node2 (count (- ?count2 30)))
(printout t ?*time*" ," ?num1 " 30 деталей типа "?detail " , " ?operation2 " , " ?time2 crlf)
else
(modify ?node1 (count ?count2) (time ?time2) (oper ?operation2) (det ?detail))
(modify ?node2 (count (- ?count2 ?count2)))
(printout t ?*time*" , " ?num1 " " ?count2 " , "?detail " , " ?operation2 " , " ?time2 crlf)
)
)

2 个答案:

答案 0 :(得分:0)

代码存在许多问题。首先,不清楚为什么机器的冗余模式匹配和细节事实:

(machine (num ?num1)(count ?count1) (time ?time1))
(test (eq ?count1 0))
(test (eq ?time1 0))
?node1 <- (machine (num ?num1)(count ?count1) (time ?time1))

(details (det ?detail) (oper ?operation1) (count ?count2))
(test (not (eq ?count2 0)))
?node2 <- (details (det ?detail) (oper ?operation1) (count ?count2))

以下代码足以完成相同的任务:

?node1 <- (machine (num ?num1) (count ?count1&0) (time ?time1&0))
?node2 <- (details (det ?detail) (oper ?operation1) (count ?count2&~0))

其次,看起来你期望funcall模式调用一个函数调用并将该函数调用的结果放在变量中?max:

(funcall find-max2 route my-predicate ?operation1 details ?max)

没有具有此类行为的funcall条件元素。在这种情况下,您刚刚创建了一个模式条件元素,它正在寻找具有关系名称funcall的有序事实。如果你想从规则条件中调用funcall,你可以使用测试条件元素:

(test (funcall find-max2 route my-predicate ?operation1 details))

由于被调用的函数是文字find-max2,因此你可以直接调用函数,因此使用funcall毫无意义:

(test (find-max2 route my-predicate ?operation1 details))

第三,在规则条件下使用查询函数没有多大意义,因为您可以直接对事实进行模式匹配。此外,在条件中使用的查询函数的放置将导致在匹配的机器/细节事实之后执行它,但可能在有任何路径事实之前执行,因此它甚至可能不会返回正确的结果。

以下规则说明了如何在不使用查询函数的情况下查找最大值:

(defrule find-max
   (route (oper ?oper1) (time ?time1))
   (exists (details (count 0) (oper ?oper1)))
   (not (and (route (oper ?oper2) (time ?time2&:(> ?time2 ?time1)))
             (exists (details (count 0) (oper ?oper2)))))
   =>
   (printout t "Maximum time is " ?time1 crlf))

答案 1 :(得分:0)

(defrule work_on_1
(declare (salience 10000))

    ?node1 <- (machinegun (num ?num1) (count ?count1&0) (time ?time1&0)) 

    ?node2 <- (store (det ?detail) (oper ?operation1) (count ?count2&~0)) 

   (tex_route (oper ?oper1) (time ?time2))
   (exists (store (count 0) (oper ?oper1)))
   (not (and (tex_route (oper ?oper2) (time ?time3&:(> ?time3 ?time2)))
             (exists (store (count 0) (oper ?oper2)))))

    (test (eq ?time1 ?time2))




(route (machine ?num1) (det ?detail) (oper ?operation2) (time ?time2))
(test (eq ?operation2 (+ ?operation1 1)))

=>

(if (> ?count2 30) 
then
(modify ?node1 (count 30) (time ?time2) (oper ?operation2) (det ?detail))
(modify ?node2 (count (- ?count2 30)))
(printout t ?*time*" ," ?num1 " 30 деталей типа "?detail " , " ?operation2 " , " ?time2 crlf)
else
(modify ?node1 (count ?count2) (time ?time2) (oper ?operation2) (det ?detail))
(modify ?node2 (count (- ?count2 ?count2)))
(printout t ?*time*" , " ?num1 " " ?count2 " , "?detail " , " ?operation2 " , " ?time2 crlf)
)
)

这是新规则,但是当专家系统停止工作时 - 只需显示“1”。