Проверка значения флага перед вставкой флага в drools

Я создал правило, и оно вставляет вопрос в сеанс. Если вопрос верен, он вставляет ФЛАГ, а если вопрос неверен, он удаляет вопрос и не обновляет флаг. Мне нужно проверить значение флага, прежде чем вставлять вопрос в сеанс. Я пробовал несколько способов сделать это, но не получил слюни, чтобы сделать это. Вот мои правила:
Вставка правила вопроса

rule "Threat: ATTACK_OTHER_USERS; insert question"
agenda-group "evaluate attack category"
dialect "mvel"

when
    Threat(this == Threat.ATTACK_OTHER_USERS)
//    $FLAGS(this == FLAGS.PUBLIC_READABLE)   // i need the check here, the existing doesn't work
then

    insertLogical(QRiskFactor.QRF1_S4_PUBLIC_READABLE);
end

вопрос верный

rule "Threat: Public Readable  QRF_1.4 [true]"
agenda-group "evaluate attack category"
dialect "mvel"
when
     $q1: QRiskFactor(this == QRiskFactor.QRF1_S4_PUBLIC_READABLE)
     Application($rf : riskFactors[QRiskFactor.QRF1_S4_PUBLIC_READABLE.value], $rf!.factor == "true")
then
    delete($q1);
    insert(FLAGS.PUBLIC_READABLE);

end

вопрос неверен

rule "Threat: Public Readable -- QRF_1.4 [not true]"
agenda-group "evaluate attack category"
dialect "mvel"
when
     $q1: QRiskFactor(this == QRiskFactor.QRF1_S4_PUBLIC_READABLE)
     Application($rf : riskFactors[QRiskFactor.QRF1_S4_PUBLIC_READABLE.value], $rf!.factor != "true")
 then
   delete($q1);

end

person Jamshaid    schedule 27.08.2020    source источник


Ответы (1)


Вам нужно проверить наличие вашего конкретного флага в рабочей памяти. Закомментированный синтаксис в вашем правиле почти правильный, за исключением того, что у вас, кажется, присутствует посторонний $.

Поскольку вы не рассказали, что такое FLAGS, немного сложно конкретно ответить на ваш вопрос. Я собираюсь предположить, основываясь на том, как вы сформулировали свой оператор insert, что это перечисление вроде этого:

public enum FLAGS {
  PUBLIC_READABLE,
  // possibly other values
}

Поэтому, если вы хотите убедиться, что FLAGS.PUBLIC_READABLE был вставлен в рабочую память, ваше правило будет включать:

when
  exists(FLAGS( this == FLAGS.PUBLIC_READABLE ))

Я использую exists, потому что вы не указали, что вам нужно что-то делать с флагом, поэтому я просто проверяю его наличие.

Обратите внимание, что insert не выполняет повторно ранее оцененные правила. Если вам нужно переоценить всю рабочую память, вы должны вместо этого использовать update.


Основываясь на комментариях, вот как можно реализовать простое приложение-викторину. Пользователь представляет ответ на вопрос; если пользователь отвечает правильно, ему предоставляется следующий вопрос. Если пользователь отвечает неправильно, для него игра окончена, и ему дается правильный ответ на вопрос, который он дал неправильно.

Я использую несколько очень простых моделей:

class Question { 
  private int id;
  private String questionText;
  private String correctAnswer;
  // getters and setters
}
class QuizUtils {
  public static Question showNextQuestion();
  public static void doGameOver(Question questionMissed);
}

Ответ пользователя представляет собой строку, введенную непосредственно в рабочую память.

rule "User got the question right"
when
  // the user's answer
  $userAnswer: String()
  
  // the current question
  Question( correctAnswer == $userAnswer )
then
  QuizUtils.showNextQuestion();
end

rule "User got the question wrong"
when
  $userAnswer: String
  $question: Question (correctAnswer != $userAnswer )
then
  QuizUtils.doGameOver($question);
end
person Roddy of the Frozen Peas    schedule 27.08.2020
comment
Правильно. Мне нужно обновить флаг на основе ответа на заданный вопрос пользователю. а позже я должен найти вопросы, которые были заданы во время сеанса. - person Jamshaid; 30.08.2020
comment
Итак, буду ли я использовать обновление или вставку при добавлении флага в память? - person Jamshaid; 30.08.2020
comment
Также есть проблема. FLAG.PUBLIC_READABLE не находится в памяти, пока не будет дан ответ на вопрос. как мне с этим справиться? Любые идеи? - person Jamshaid; 30.08.2020
comment
Вообще не понятно, что ты делаешь. Я предположил, что многие подобные вещи вы используете в облачном режиме, который используется по умолчанию. Вы действительно работаете в потоковом режиме? - person Roddy of the Frozen Peas; 30.08.2020
comment
Либо обновление, либо вставка поместят флаг в рабочую память, вопрос о том, что использовать, сводится к тому, хотите ли вы, чтобы все правила были перезапущены (обновлены) или если вы просто хотите, чтобы последующие правила теперь могли отключить наличие флага (insert). - person Roddy of the Frozen Peas; 30.08.2020
comment
Я новичок в слюнях. Я не знаю о потоковом режиме. У меня есть система, которая задает пользователю вопрос, а в ответ на него задаются новые вопросы. Я хочу, чтобы система задавала один вопрос только один раз. Флаги, о которых я говорю, необходимы для отслеживания вопросов независимо от того, задан вопрос или нет. - person Jamshaid; 31.08.2020
comment
если вопрос еще не задан, он должен быть показан пользователю, а если он задан, он должен просто показать предыдущий ответ для этого сеанса. - person Jamshaid; 31.08.2020
comment
Да, я понимаю эту часть. Но то, как вы собираетесь использовать слюни, сбивает с толку. Ваш рабочий процесс описывает пользователя, взаимодействующего с вашим приложением в течение определенного периода времени. Drools выполняется в момент времени. Если вы не находитесь в потоковом режиме (предназначенном для потоковой передачи событий), он не будет сидеть и слушать текущие действия с одним текущим сеансом. Вы пытаетесь использовать неправильный инструмент для работы. - person Roddy of the Frozen Peas; 31.08.2020