слюни правят потоком - PullRequest
       6

слюни правят потоком

12 голосов
/ 13 октября 2011

У меня странная проблема с слюнями:

У меня есть следующие правила:

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

Я вставляю в мою сессию myData и myData.getMyDog(), где myData.getMyDog.isBaby==false

Первое правило действует, и моя собака станет ребенком. Затем запускается второй, и даже он печатает true (даже если условие должно было быть ложным)

И когда я проверяю после применения всех правил, myDog в myData устанавливается как ребенок.

Что я здесь не так делаю? Почему срабатывает второе правило? проблема в сеансе (в моем случае это состояние)?

Я думаю, что мне нужно сказать, что я где-то изменяю myData: myDog, но я не уверен, где.

Надеюсь, мой вопрос ясен, если не сказать мне.

Ответы [ 4 ]

15 голосов
/ 13 октября 2011

Когда вы изменяете факты рабочей памяти, вам нужно сообщить Drools, что данные изменились, чтобы он мог пересмотреть все соответствующие правила.

Drools оценивает факты, прежде чем применять любые подходящие правила. Если у вас есть собака с возрастом = 0 и ребенком = ложь, оба ваших правила будут активированы. Когда ваше правило is my dog a baby? запущено, это не меняет того факта, что когда Drools оценил правило baby dog, условие myDog.isBaby() == false было выполнено.

Чтобы сообщить Drools о том, что вы изменили какой-то факт, используйте update() вспомогательный метод знаний. Имейте в виду, что Drools связывает дескрипторы фактов с конкретным объектом. Если правило ссылается на MyData, и вы хотите, чтобы это правило было переоценено при изменении объекта MyData.myDog, вам нужно будет использовать update() для объекта MyData; простое выполнение update() для вашего Dog объекта не приведет к переоценке правила baby dog.

Попробуйте изменить правило is my dog a baby? на следующее:

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
9 голосов
/ 13 октября 2011

Вам нужно сделать

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

в первом правиле и переписать , когда вашего второго правила, например

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

Правило должно быть написанотаким образом, drools может автоматически определять, какие правила он должен запустить снова после изменения факта.

Каждый раз, когда вы изменяете факт в механизме правил, вам нужно сообщить рабочей памяти, что вы изменилиэто с обновлением.

Я не использовал drools с версии 4, но я предполагаю, что это все еще применяется.

2 голосов
/ 14 октября 2011

Да, вы должны обновить и собаку, и карту. Приветствия

0 голосов
/ 28 ноября 2013

Вы можете обновить собаку в рабочей памяти, используя modify или update методы вспомогательных знаний. Если вы можете использовать любую из вышеперечисленных функций, Drools снова пересмотрит правила, и вы получите бесконечный цикл. поэтому вам также необходимо использовать атрибут no-loop в вашем правиле или изменить условие на

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

так что в следующий раз он не будет снова оценивать то же правило и обновлять isBaby на true снова и снова.

...