2014-12-19 2 views
0

전문가 시스템의 디자인을 내 규칙에 따라 변경하려고합니다.함수를 호출하면 규칙이 중단됩니다.

주제 - 다른 기계에서 다른 부분을 처리합니다. 당연히 각기 다른 종류의 항목이 다른 시간에 다른 기계에서 처리됩니다.

시스템은 세 가지 규칙으로 구성됩니다. 첫 번째 규칙 - 부하 기계가 작동합니다. 두 번째 규칙 - 기계를 언로드합니다. 세 번째 규칙 - 시간 이동을 수행합니다.

최대 처리 시간을 가진 항목을 찾는 함수 호출의 첫 번째 규칙에 추가했습니다. 그러나 전문가 시스템이 작동을 멈췄습니다. 단순히 "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) 
) 
) 

답변

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"표시

다음 규칙은 쿼리 기능을 사용하지 않고 최대 값을 찾는 방법을 보여줍니다.

+0

게시 한 코드 조각과 관련된 문제는 재현 할 수 없습니다. –

+0

Gary, 내 코드 http://myfolder.ru/files/42588461 암호 1926 – aleator

+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 패턴 함수 호출을 호출하고, 그 변수에 함수 호출의 결과를 배치 최대 : t를 갖는 조건부 요소가 더 funcall가

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

없다 그의 행동 유형. 이 경우 관계 이름 funcall을 사용하여 정렬 된 사실을 찾는 패턴 조건부 요소를 만들었습니다. 당신이 테스트 조건 요소를 사용하십시오 규칙의 조건에서 funcall를 호출하고 싶었 경우 호출되는 함수가 문자 그대로 찾을-MAX2이기 때문에

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

을, 당신 때문에 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)) 
관련 문제