2011-10-13 28 views
12

Tôi đang gặp một vấn đề xa lạ với Drools:Drools cai trị chảy

tôi có các quy tắc sau:

rule "is my dog a baby?" 
    ruleflow-group "dog" 
    salience 10 
    when 
    dog : Dog(age <1) 
    then 
    dog.setIsBaby(true); 
end 


rule "baby dog" 
    ruleflow-group "dog" 
    salience 9 
    when 
     myData : MyData(myDog.isBaby() == false) 
    then 
     System.out.println(myData.getMyDog().getIsBaby()); 
end 

tôi chèn trong phiên tôi myData và myData.getMyDog(), nơi myData.getMyDog.isBaby==false

Đầu tiên quy tắc được kích hoạt và con chó của tôi được đặt là một đứa trẻ. Sau đó, lần thứ hai được kích hoạt, và thậm chí nó in đúng (ngay cả khi điều kiện là sai)

Và khi tôi kiểm tra sau khi kích hoạt tất cả các quy tắc, myDog trong myData được đặt thành một em bé.

Tôi đang làm gì sai ở đây? Tại sao quy tắc thứ hai được kích hoạt? là vấn đề trong phiên làm việc (trong trường hợp của tôi)?

Tôi nghĩ rằng tôi cần phải nói rằng tôi sửa đổi myData: myDog ở đâu đó, nhưng tôi không chắc chắn ở đâu.

Hy vọng câu hỏi của tôi là rõ ràng, nếu không cho tôi biết.

Trả lời

15

Khi bạn sửa đổi các sự kiện bộ nhớ hoạt động, bạn cần thông báo cho Drools rằng dữ liệu đã thay đổi để có thể đánh giá lại tất cả các quy tắc có liên quan.

Drools đánh giá sự thật trước khi kích hoạt bất kỳ quy tắc phù hợp nào. Nếu bạn có một con chó với tuổi = 0 và em bé = false, cả hai quy tắc của bạn sẽ được kích hoạt. Khi quy tắc is my dog a baby? của bạn được kích hoạt, nó không thay đổi thực tế là khi Drools đánh giá quy tắc baby dog, điều kiện myDog.isBaby() == false là đúng.

Để thông báo cho Drools rằng bạn đã sửa đổi một số thực tế, hãy sử dụng phương thức trợ giúp kiến ​​thức update(). Hãy nhớ rằng Drools liên kết các xử lý thực tế với một đối tượng cụ thể. Nếu quy tắc tham chiếu MyData và bạn muốn quy tắc đó được đánh giá lại khi đối tượng MyData.myDog đã thay đổi, bạn sẽ cần phải sử dụng update() trên đối tượng MyData; chỉ cần thực hiện update() trên đối tượng Dog của bạn, sẽ không làm cho quy tắc baby dog được đánh giá lại.

Hãy thử thay đổi quy tắc is my dog a baby? của bạn như sau:

rule "is my dog a baby?" 
    ruleflow-group "dog" 
    salience 10 
    when 
     dog : Dog(age < 1, baby == false) 
     myData : MyData(myDog == dog) 
    then 
     dog.setIsBaby(true); 
     update(dog); 
     update(myData); 
    end 
+0

Thx rất nhiều tôi sẽ cố gắng –

9

Bạn cần phải làm

then 
    dog.setIsBaby(true); 
    update(dog) 

trên quy tắc đầu tiên của bạn và viết lại khi cai trị thứ hai của bạn như

when 
    dog : Dog(isBaby == false) 
    myData : MyData(myDog == dog) 

Nguyên tắc phải được viết theo cách này, vì vậy Drools thể tự động phát hiện quy tắc nào mà nó phải chạy lại sau khi thay đổi thực tế.

Mỗi khi bạn thay đổi thực tế trong công cụ quy tắc, bạn cần phải thông báo cho bộ nhớ làm việc rằng bạn đã thay đổi nó bằng bản cập nhật.

Tôi chưa sử dụng drools kể từ phiên bản 4, nhưng tôi cho rằng điều này vẫn được áp dụng.

+0

Thx rất nhiều Tôi sẽ thử rằng –

2

Có bạn nên cập nhật cả hai con chó và bản đồ. Chúc mừng

0

Bạn có thể cập nhật con chó trong bộ nhớ hoạt động bằng cách sử dụng các phương pháp trợ giúp kiến ​​thức modify hoặc update. Nếu bạn có thể thực hiện bất kỳ chức năng nào ở trên, Drools sẽ đánh giá lại các quy tắc một lần nữa và bạn sẽ kết thúc với một vòng lặp vô hạn. vì vậy bạn cũng cần phải bạn không-loop thuộc tính trong quy tắc của bạn hoặc sửa đổi bạn tạo điều kiện để

dog : Dog(age <1, isBaby == false)

để lần sau nó sẽ không đánh giá cùng một quy tắc một lần nữa và cập nhật các isBaby true một lần nữa và một lần nữa.

Các vấn đề liên quan