Julian Solarte
Julian Solarte

Reputation: 585

Execution of a single rule for a group in Drools

I am working on an expert system based on legislation, I have many rules like these:

Rule 1: If the seizure has an amount greater than 3000, seize the amount, justification law 100

Rule 2: If the seizure is of a family type, seize the amount, justification law 200

The problem is that the action "Seize" can only be applied once, but I need to save the history of the rules that are met, I present an example below

rule "law 100"

when 
  $seizure: Seizure(amount>3000)
then
  $seizure.getRules().add("Justification: law 100 of the civil that says bla bla");
  $seizure.applyPunishment();

rule "law 200"

when 
  $seizure: Seizure(type == TYPES.Family)
then
  $seizure.getRules().add("Justification: law 200 of the family code that says bla bla");
  $seizure.applyPunishment();

As I showed above, I need the "then" part that save the description rule "$seizure.getRules().add("Justification: law of the civil code");". and I also need that if the "$seizure.applyPunishment();" was already applied in rule 1, it will not be reapplied in the rule 2.

Thanks in advice

Upvotes: 0

Views: 327

Answers (1)

mdfst13
mdfst13

Reputation: 900

You have several options here.

  1. Change applyPunishment to be idempotent.

    You don't show the code for applyPunishment, but it could look like

    private boolean alreadySeized = false;
    
    public void applyPunishment() {
        if (alreadySeized) {
            return;
        }
    
        alreadySeized = true;
    

    You could also base this on some other variable that already exists. E.g. if (seizedAmount > 0) return;. But it's hard to say how that might work without the code.

  2. You could change applyPunishment to something like markForPunishment, which could look like

    private boolean markedForPunishment;
    
    public void markForPunishment() {
        markedForPunishment = true;
    }
    

    Then add a rule like

    rule "Punish"
    
    when
      $seizure: Seizure(markedForPunishment  == true)
    then
      $seizure.applyPunishment();
    

    With an appropriate getter.

    Your other rules would call markForPunishment rather than applyPunishment.

  3. You could use a ruleflow to separate the justifications from the punishment.

  4. You could set a variable in your then clause that you use in your rules.

There are probably other options. The big decision to make is whether you want an MVEL solution or a Java solution. Several of the options will require changing both.

Upvotes: 1

Related Questions