Search code examples
javadroolsbusiness-rules

Drools Decision Table object comparison gives inverted results


I have been struggling with a problem considering Drools and this is kind of my last resort.

Assume I have a list of 3 people: [1, 2, 3]. Think of this list as a list of ID values for these people. Now, I want to evaluate all unique pairs of these people in the following order:

  1. Person 1 against Person 2;
  2. Person 1 against Person 3;
  3. Person 2 against Person 3.

My spreadsheet's RuleTable looks like this:

RuleTable PSBR

It makes use of a trick mentioned in this comment: Drools compare two objects in decision table.

The Person class had been correctly imported, the three people have been inserted into the session and every Person object has a getId() method.

However, running fireAllRules() on the session gives me the following output:

  1. Person 1 vs Person 1
  2. Person 2 vs Person 1
  3. Person 2 vs Person 2
  4. Person 3 vs Person 1
  5. Person 3 vs Person 2
  6. Person 3 vs Person 3

You might notice that that's the complement of the set of results I would have liked.

Please note! After a wild guess, it turned out that changing the condition id > $id1 toid < $id1 solves this problem, but then the logic appears to not match in my head.

The rule I'm trying to mimic looks something as follows:

rule "same-company"
    when
        $p1 : Person($id1 : id)
        $p2 : Person($id2 : id, id > $id1)
    then
        System.out.println($p1.getId() + " " + $p2.getId());
end

This rule works fine and as expected on its own in a .drl file!

So my questions are:

  1. Is this what the spreadsheets are supposed to do?
  2. If not, what could I be doing wrong here?

I also have some more complex variables inside Person objects that I'd like to apply logic to (maps of strings for each person that I'd like to compare values of), to which the same thing happens; Drools spreadsheets seem to let a rule pass when the conditions I set have NOT been met. Targeting the opposite is possible, and works, but to me it doesn't seem like that's the way this should work.

Thanks in advance!


Edit 1: The generated DRL using Drools - Using “from” in decision table returns the following result:

package org.ps.dtable;
//generated from Decision Table
import org.ps.orm.Person;
// rule values at C12, header at C7
rule "PSBR_12"
    when
        $p1:Person ($id1: id) $p2:Person($id2:id, id > $id1 /*param*/ == "X")
    then
        System.out.println($p1 + " vs " + $p2);
end

The Excel spreadsheet looks like this: Spreadsheet

Edit 2: The $ in /*$param*/ was missing, and caused weird evaluation. Lesson learned; never forget about the money.


Solution

  • I don't see how operators < or > could ever produce 1 vs 1, but that's probably not the most important issue.

    More importantly, I can't reproduce this problem using version 5.5.

    Older versions may have handled this particular situation differently. Then it was important to realize that the spreadsheet compiler squeezes the constraint (what you have in row 4) into the parentheses of row 3 (unless the rows are formed according to a different pattern, with == added automagically). You may try to add a pair of parentheses after the second Person

    CONDITION
    $p1:Person($id1:id) $p2:Person()
    $id2:id > $id1 /*$param*/
    pairs ordered by ascending id
    

    If this doesn't work, you'll have to upgrade.

    PS: For debugging, printing the generated DRL is essential. See my answer in Drools - Using "from" in decision table

    PPS: Careful reading always helps. I overlooked that you had /* param */ without the dollar sign in your question, and so the generated rule had == "X" appended to the constraint. Strange at it seems, this compiles, and evaluates in a very weird way, which I can't figure out right away. Probably any string that is not equal to "true" is considered to be equal to "false", which would then work like a negation and produce the result you couldn't figure out. No wonder. (Very likely, the MVEL evaluation is at the bottom of this, which has produced other baffling effects.)