Search code examples
droolsdslrules

Logic OR in a DSL


I have a question around how to do an or in a DSLR, I have this rule:

rule "Test"
    when
        There is AThing
        - with attribute1 is equal to something1
        - attribute2 is higher than or equal to somethingelse1

        There is AThing
        - with attribute1  is equal to something2
        - attribute2 is higher than or equal to somethingelse2
    then
        something is valid
end

that rewrites to a dlr like:

rule "Test"
    when
        AThing(attribute1 ==  something1, attribute2  >=  somethingelse1)
        AThing(attribute1 ==  something2, attribute2  >= somethingelse2)
    then
        something is valid
end

what's the best way to put the 2 condition into an OR in the DSLR? I would like to write something like:

rule "Test"
    when
        (There is AThing
        - with attribute1 is equal to something1
        - attribute2 is higher than or equal to somethingelse1)
        or
        (There is AThing
        - with attribute1  is equal to something2
        - attribute2 is higher than or equal to somethingelse2)
    then
        something is valid
end

but the Drools compiler is complaining, I tried many combinations of parenthesis.

In this case I could write 2 separate rules, but in reality they are part of a most complex rule I would like to avoid to repeat two big rules just for an or.

Is there a way to do that? Thanks!


Solution

  • It's best to write this as two rules - which will happen anyway.

    The syntax requires you to write an infix or on the LHS as

    when
    ( Type(...)
    or
      Type(...) )
    then
    

    and the prefix or as

    when
    (or Type(...)
        Type(...))
    then
    

    neither of which is easy to achieve using a DSL. The best you can do is to write the parentheses and the or on a line prefixed with a greater sign (>) which will simply pass the remainder through to the DRL output.

    when
    > (
      Type(...)
    > or
      Type(...)
    > )
    

    But a condition like your example can also be combined like this:

    when
        AThing(attribute1 == something1 && attribute2 >=  somethingelse1
               ||
               attribute1 == something2 && attribute2 >= somethingelse2)
    then
    

    but this will be difficult to achieve using a DSL. (Which, as I wrote in another corner of SO,...)